Ubuntu 下 nginx-1.24.0 源码分析 (1)

main 函数在 

src\core\nginx.c


int ngx_cdecl
main(int argc, char *const *argv)
{
    ngx_buf_t        *b;
    ngx_log_t        *log;
    ngx_uint_t        i;
    ngx_cycle_t      *cycle, init_cycle;
    ngx_conf_dump_t  *cd;
    ngx_core_conf_t  *ccf;

    ngx_debug_init();

 进入 main 函数

最开始是局部变量的声明

然后是

ngx_debug_init();


接下来是 :

   if (ngx_strerror_init() != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_strerror_init()函数-CSDN博客


 接下来是 :

    if (ngx_get_options(argc, argv) != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_options函数-CSDN博客

当前这次执行的是:

sudo ./nginx

 除了 程序名 没有其他参数

所以 

argc=1 

于是在 ngx_get_options 函数中

static ngx_int_t
ngx_get_options(int argc, char *const *argv)
{
    u_char     *p;
    ngx_int_t   i;

    for (i = 1; i < argc; i++) {

        p = (u_char *) argv[i];

        if (*p++ != '-') {
            ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);
            return NGX_ERROR;
        }

        while (*p) {

            switch (*p++) {

            case '?':
            case 'h':
                ngx_show_version = 1;
                ngx_show_help = 1;
                break;

            case 'v':
                ngx_show_version = 1;
                break;

            case 'V':
                ngx_show_version = 1;
                ngx_show_configure = 1;
                break;

            case 't':
                ngx_test_config = 1;
                break;

            case 'T':
                ngx_test_config = 1;
                ngx_dump_config = 1;
                break;

            case 'q':
                ngx_quiet_mode = 1;
                break;

            case 'p':
                if (*p) {
                    ngx_prefix = p;
                    goto next;
                }

                if (argv[++i]) {
                    ngx_prefix = (u_char *) argv[i];
                    goto next;
                }

                ngx_log_stderr(0, "option \"-p\" requires directory name");
                return NGX_ERROR;

            case 'e':
                if (*p) {
                    ngx_error_log = p;

                } else if (argv[++i]) {
                    ngx_error_log = (u_char *) argv[i];

                } else {
                    ngx_log_stderr(0, "option \"-e\" requires file name");
                    return NGX_ERROR;
                }

                if (ngx_strcmp(ngx_error_log, "stderr") == 0) {
                    ngx_error_log = (u_char *) "";
                }

                goto next;

            case 'c':
                if (*p) {
                    ngx_conf_file = p;
                    goto next;
                }

                if (argv[++i]) {
                    ngx_conf_file = (u_char *) argv[i];
                    goto next;
                }

                ngx_log_stderr(0, "option \"-c\" requires file name");
                return NGX_ERROR;

            case 'g':
                if (*p) {
                    ngx_conf_params = p;
                    goto next;
                }

                if (argv[++i]) {
                    ngx_conf_params = (u_char *) argv[i];
                    goto next;
                }

                ngx_log_stderr(0, "option \"-g\" requires parameter");
                return NGX_ERROR;

            case 's':
                if (*p) {
                    ngx_signal = (char *) p;

                } else if (argv[++i]) {
                    ngx_signal = argv[i];

                } else {
                    ngx_log_stderr(0, "option \"-s\" requires parameter");
                    return NGX_ERROR;
                }

                if (ngx_strcmp(ngx_signal, "stop") == 0
                    || ngx_strcmp(ngx_signal, "quit") == 0
                    || ngx_strcmp(ngx_signal, "reopen") == 0
                    || ngx_strcmp(ngx_signal, "reload") == 0)
                {
                    ngx_process = NGX_PROCESS_SIGNALLER;
                    goto next;
                }

                ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);
                return NGX_ERROR;

            default:
                ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));
                return NGX_ERROR;
            }
        }

    next:

        continue;
    }

    return NGX_OK;
}

进入不了 for 循环

直接走到

return NGX_OK;

返回到 main 函数中


接下来是 :

if (ngx_show_version) {
        ngx_show_version_info();

        if (!ngx_test_config) {
            return 0;
        }
    }

ngx_show_version 未设置,此时是 0

于是跳过这段代码


接下来是 :

/* TODO */ ngx_max_sockets = -1;

初始化全局变量 ngx_max_sockets

ngx_max_sockets 是一个全局变量,用于存储 Nginx 能够处理的最大文件描述符(socket)数量。

文件描述符是操作系统用于管理打开的文件、socket 等资源的标识符。Nginx 作为一个高性能的 Web 服务器,需要处理大量的并发连接,因此文件描述符的数量对性能有重要影响

初始值为 -1 的意义

  • 将 ngx_max_sockets 初始化为 -1 表示在程序启动时,还没有确定实际的最大文件描述符数量。

  • -1 通常用作一个初始值或无效值,表示该变量尚未被正确初始化或配置

  • 在后续的代码中,Nginx 会根据操作系统的限制和配置文件中的设置来更新 ngx_max_sockets 的值。


接下来是 :

ngx_time_init();

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_time_init 函数-CSDN博客


接下来是 :

#if (NGX_PCRE)
    ngx_regex_init();
#endif

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_regex_init 函数-CSDN博客


接下来是 :

    ngx_pid = ngx_getpid();
    ngx_parent = ngx_getppid();

获取当前进程的进程ID(ngx_pid)和父进程的进程ID(ngx_parent)。

这在后续的进程管理中很有用。

src/os/unix/ngx_process.h 中:

#define ngx_getpid   getpid
#define ngx_getppid  getppid

getpid 和 getppid 是 C 语言中用于获取进程 ID 的函数,定义在 <unistd.h> 头文件中

getpid():获取当前进程的进程ID
getppid():获取当前进程的父进程ID

父进程是创建当前进程的进程(如通过fork())。
若父进程终止,子进程的PPID会被重置为init进程(PID=1)


接下来是: 

    log = ngx_log_init(ngx_prefix, ngx_error_log);
    if (log == NULL) {
        return 1;
    }

 Ubuntu 下 nginx-1.24.0 源码分析 - ngx_log_init 函数-CSDN博客

此次调用 ngx_log_init 

prefix 和 error_log 都还没有设置此时还是 null

进入 ngx_log_init 

首先是

ngx_log_t *
ngx_log_init(u_char *prefix, u_char *error_log)
{
    u_char  *p, *name;
    size_t   nlen, plen;

    ngx_log.file = &ngx_log_file;
    ngx_log.log_level = NGX_LOG_NOTICE;
  • 将全局日志对象 ngx_log 的文件指针指向 ngx_log_file

  • 设置默认日志级别为 NGX_LOG_NOTICE(通知级别)

    if (error_log == NULL) {
        error_log = (u_char *) NGX_ERROR_LOG_PATH;
    }

    name = error_log;
    nlen = ngx_strlen(name);

此时 error_log 还是null

于是进入这个 if 条件中

把默认值 NGX_ERROR_LOG_PATH 赋值给 error_log 

这个默认值是在 执行configure命令时定义的一个宏,它的值由 configure 命令的配置项 --error-log-path 指定

    if (nlen == 0) {
        ngx_log_file.fd = ngx_stderr;
        return &ngx_log;
    }

    p = NULL;

nlen 不是0

跳过这个 if 条件

if (name[0] != '/') {

检查路径是否以 / 开头

是以 开头

所以当前 name 已经是绝对路径了,不需要拼接前缀

ngx_log_file.fd = ngx_open_file(name, NGX_FILE_APPEND,
                                    NGX_FILE_CREATE_OR_OPEN,
                                    NGX_FILE_DEFAULT_ACCESS);

以追加的方式打开 name 指向的 日志文件 

此时返回的 fd 是 4

    if (ngx_log_file.fd == NGX_INVALID_FILE) {
        ngx_log_stderr(ngx_errno,
                       "[alert] could not open error log file: "
                       ngx_open_file_n " \"%s\" failed", name);

 NGX_INVALID_FILE 的值是 -1 无效的文件描述符,表示上一步的打开文件失败

现在这个条件不成立,跳过这段代码

   if (p) {
        ngx_free(p);
    }

    return &ngx_log;

由于之前条件不成立,所以 没有用到 p

最后返回 ngx_log 的地址


回到 main 函数中

接下来是: 

ngx_ssl_init(log);

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_ssl_init 函数-CSDN博客


接下来是: 

  ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));

把 init_cycle 的每个字节都初始化为 0

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cycle_t 类型-CSDN博客

    init_cycle.log = log;

将之前 初始化的 日志对象的地址 记录在 log 字段

    ngx_cycle = &init_cycle;

现在 ngx_cycle 是指向 init_cycle 的指针了


   init_cycle.pool = ngx_create_pool(1024, log);

创建一个内存池要求的内存大小是 1024 字节,然后将地址记录到 init_cycle pool 字段进行管理

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_create_pool函数-CSDN博客

进入 ngx_create_pool

ngx_pool_t *
ngx_create_pool(size_t size, ngx_log_t *log)
{
    ngx_pool_t  *p;

    p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
    if (p == NULL) {
        return NULL;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_memalign函数-CSDN博客

 使用 ngx_memalign 来分配内存

NGX_POOL_ALIGNMENT 是要求的对齐边界,值为 16

进入 ngx_memalign

void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
    void  *p;
    int    err;

    err = posix_memalign(&p, alignment, size);

调用 posix_memalign 来分配一块对齐的内存

posix_memalign 函数-CSDN博客

 此次返回值为 0

也就是分配内存成功了

p=0x5aa55f9765a0

这个地址是按 16 对齐的

if (err) {
        ngx_log_error(NGX_LOG_EMERG, log, err,
                      "posix_memalign(%uz, %uz) failed", alignment, size);
        p = NULL;
    }

条件不成立,跳过这段代码

return p;

把分配的地址返回到

ngx_create_pool 函数中


 回到 ngx_create_pool

接下来是:

   if (p == NULL) {
        return NULL;
    }

条件不成立,跳过这段代码

    p->d.last = (u_char *) p + sizeof(ngx_pool_t);
    p->d.end = (u_char *) p + size;
    p->d.next = NULL;
    p->d.failed = 0;

    size = size - sizeof(ngx_pool_t);
    p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;

    p->current = p;
    p->chain = NULL;
    p->large = NULL;
    p->cleanup = NULL;
    p->log = log;

    return p;

赋值然后返回 内存池 地址

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_create_pool函数-CSDN博客

当前 size = 944 , NGX_MAX_ALLOC_FROM_POOL = -1
所以 p->max=944


回到 main 函数中

接下来是:

   if (init_cycle.pool == NULL) {
        return 1;
    }

条件不成立,跳过这段代码

   if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_save_argv函数-CSDN博客


    if (ngx_process_options(&init_cycle) != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_process_options-CSDN博客

 进入 ngx_process_options

static ngx_int_t
ngx_process_options(ngx_cycle_t *cycle)
{
    u_char  *p;
    size_t   len;

    if (ngx_prefix) {

ngx_prefix 还是 null

所以跳过这个 if 代码段进入 else

接下来是:

ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);

将 默认的配置文件路径前缀设置给 cycle->conf_prefix

ngx_str_set(&cycle->prefix, NGX_PREFIX);

将 默认的路径前缀设置给 cycle->prefix

    if (ngx_conf_file) {
        cycle->conf_file.len = ngx_strlen(ngx_conf_file);
        cycle->conf_file.data = ngx_conf_file;

    } else {
        ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);
    }

此次启动没有指定 配置文件路径

所以 ngx_conf_file 在这里还是 null

进入 else 中,将 默认的配置文件路径设置给 cycle->conf_file 进行管理

接下来是:

    if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
        return NGX_ERROR;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_full_name 函数-CSDN博客

cycle->conf_file 保存的配置文件路径可能是 相对路径,需要 调用 ngx_conf_full_name  来拼接路径前缀 然后形成完成的路径

进入 ngx_conf_full_name 中

ngx_int_t
ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name, ngx_uint_t conf_prefix)
{
    ngx_str_t  *prefix;

    prefix = conf_prefix ? &cycle->conf_prefix : &cycle->prefix;

    return ngx_get_full_name(cycle->pool, prefix, name);
}

这里传进来的 conf_prefix 的值是 0

所以 prefix =  &cycle->prefix; 选择 cycle->prefix (/usr/local/nginx/) 作为配置文件路径前缀

然后调用 ngx_get_full_name 来拼接路径

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_get_full_name 函数-CSDN博客

进入 ngx_get_full_name

ngx_int_t
ngx_get_full_name(ngx_pool_t *pool, ngx_str_t *prefix, ngx_str_t *name)
{
    size_t      len;
    u_char     *p, *n;
    ngx_int_t   rc;

    rc = ngx_test_full_name(name);

    if (rc == NGX_OK) {
        return rc;
    }

调用 ngx_test_full_name 来判断 name (/home/wsd/桌面/nginx/conf/nginx.conf) 是否是完整的路径

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_test_full_name-CSDN博客

进入 ngx_test_full_name

static ngx_int_t
ngx_test_full_name(ngx_str_t *name)
{
#if (NGX_WIN32)
    u_char  c0, c1;

    c0 = name->data[0];

    if (name->len < 2) {
        if (c0 == '/') {
            return 2;
        }

        return NGX_DECLINED;
    }

    c1 = name->data[1];

    if (c1 == ':') {
        c0 |= 0x20;

        if ((c0 >= 'a' && c0 <= 'z')) {
            return NGX_OK;
        }

        return NGX_DECLINED;
    }

    if (c1 == '/') {
        return NGX_OK;
    }

    if (c0 == '/') {
        return 2;
    }

    return NGX_DECLINED;

#else

    if (name->data[0] == '/') {
        return NGX_OK;
    }

    return NGX_DECLINED;

#endif
}

 当前环境是 Ubuntu  #if (NGX_WIN32) 不成立

所以接下来执行的是:

    if (name->data[0] == '/') {
        return NGX_OK;
    }

    return NGX_DECLINED;

条件成立 name  的第一个字符是

被认为是 绝对路径

返回 NGX_OK


回到 ngx_get_full_name

   rc = ngx_test_full_name(name);

    if (rc == NGX_OK) {
        return rc;
    }

rc 得到的返回值是 NGX_OK

条件成立,把这个 NGX_OK 返回到 ngx_conf_full_name 

return ngx_get_full_name(cycle->pool, prefix, name);

这个结果继续向上返回到 ngx_process_options


回到 ngx_process_options

接下来是:

if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
        return NGX_ERROR;
    }

于是 这里 调用 ngx_conf_full_name 得到 返回值 NGX_OK

条件不成立

接下来是:

   for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
         p > cycle->conf_file.data;
         p--)
    {
        if (ngx_path_separator(*p)) {
            cycle->conf_prefix.len = p - cycle->conf_file.data + 1;
            cycle->conf_prefix.data = cycle->conf_file.data;
            break;
        }
    }

cycle->conf_file.data 是配置文件路径,

cycle->conf_file.data + cycle->conf_file.len - 1 指向这个路径字符串的最后一个字节

从最后一个字符向第一个字符遍历

if (ngx_path_separator(*p)) { 判断当前这个字符是否是分隔符 /

这个 分隔符后面是 配置文件的文件名,前面是配置文件的目录

将 cycle->conf_file.data 的地址赋给cycle->conf_prefix.data

从这个地址开始 len 个字符是 配置文件所在的目录

于是 

cycle->conf_file.data(0x5bfbfeaf3e50) = cycle->conf_prefix.data(0x5bfbfeaf3e50)

这2个地址一样

cycle->conf_file.len=38
cycle->conf_file.data=/home/wsd/桌面/nginx/conf/nginx.conf

cycle->conf_prefix.len=28
cycle->conf_prefix.data=/home/wsd/桌面/nginx/conf/

就是 cycle->conf_file.data 的前 28 个字节

接下来是:

if (ngx_error_log) {
        cycle->error_log.len = ngx_strlen(ngx_error_log);
        cycle->error_log.data = ngx_error_log;

    } else {
        ngx_str_set(&cycle->error_log, NGX_ERROR_LOG_PATH);
    }

当前 ngx_error_log=null  还没有设置它

所以进入 else

把 默认值 NGX_ERROR_LOG_PATH(/home/wsd/桌面/nginx/LOG/error.log)

设置给 cycle->error_log             

       

接下来是:

    if (ngx_conf_params) {
        cycle->conf_param.len = ngx_strlen(ngx_conf_params);
        cycle->conf_param.data = ngx_conf_params;
    }

 ngx_conf_params 没有设置是 null

所以跳过这段代码

if (ngx_test_config) {
        cycle->log->log_level = NGX_LOG_INFO;
    }

ngx_test_config 0

所以跳过这段代码

  return NGX_OK;

返回结果


回到 main 函数中

接下来是:

   if (ngx_os_init(log) != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_init 函数-CSDN博客

 进入 ngx_os_init

ngx_int_t
ngx_os_init(ngx_log_t *log)
{
    ngx_time_t  *tp;
    ngx_uint_t   n;
#if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)
    long         size;
#endif

#if (NGX_HAVE_OS_SPECIFIC_INIT)
    if (ngx_os_specific_init(log) != NGX_OK) {
        return NGX_ERROR;
    }
#endif

调用 ngx_os_specific_init 函数

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_os_specific_init函数-CSDN博客

 进入 ngx_os_specific_init

ngx_int_t
ngx_os_specific_init(ngx_log_t *log)
{
    struct utsname  u;

    if (uname(&u) == -1) {
        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, "uname() failed");
        return NGX_ERROR;
    }

调用 uname 获取系统信息 

这次获得的系统信息如下:

// 操作系统名称

u.sysname=Linux 

//主机名          
u.nodename=wsd-vm

//操作系统发行版本
u.release=6.8.0-52-generic

// 操作系统版本信息
u.version=#53~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Wed Jan 15 19:18:46 UTC 2

// 硬件架构
u.machine=x86_64

接下来是:

    (void) ngx_cpystrn(ngx_linux_kern_ostype, (u_char *) u.sysname,
                       sizeof(ngx_linux_kern_ostype));

    (void) ngx_cpystrn(ngx_linux_kern_osrelease, (u_char *) u.release,
                       sizeof(ngx_linux_kern_osrelease));

复制 u.sysname u.release 存储到全局变量 ngx_linux_kern_ostype 和 ngx_linux_kern_osrelease

   ngx_os_io = ngx_linux_io;

    return NGX_OK;

设置 ngx_os_io 

然后返回结果


回到 ngx_os_init

接下来是:

   if (ngx_init_setproctitle(log) != NGX_OK) {
        return NGX_ERROR;
    }

调用 ngx_init_setproctitle

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_setproctitle函数-CSDN博客

 进入 ngx_init_setproctitle

ngx_int_t
ngx_init_setproctitle(ngx_log_t *log)
{
    u_char      *p;
    size_t       size;
    ngx_uint_t   i;

    size = 0;

    for (i = 0; environ[i]; i++) {
        size += ngx_strlen(environ[i]) + 1;
    }

遍历 环境变量

ngx_strlen(environ[i]) + 1;

是当前这个环境变量占用的内存字节数量(字符串长度 + 字符串结束标志 '\0')

累加到 size 中,最终 size 的值是整个环境变量占据的字节数量

这次的执行情况:

i=0
environ[0]="COLORTERM=truecolor"
ngx_strlen(environ[0]) + 1  =20
size=20

i=1
environ[1]="LANGUAGE=zh_CN:en"
ngx_strlen(environ[1]) + 1  =18
size=38

i=2
environ[2]="LC_ADDRESS=zh_CN.UTF-8"
ngx_strlen(environ[2]) + 1  =23
size=61

i=3
environ[3]="LC_NAME=zh_CN.UTF-8"
ngx_strlen(environ[3]) + 1  =20
size=81

i=4
environ[4]="LC_MONETARY=zh_CN.UTF-8"
ngx_strlen(environ[4]) + 1  =24
size=105

i=5
environ[5]="XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.SUZ122"
ngx_strlen(environ[5]) + 1  =54
size=159

i=6
environ[6]="LC_PAPER=zh_CN.UTF-8"
ngx_strlen(environ[6]) + 1  =21
size=180

i=7
environ[7]="LANG=zh_CN.UTF-8"
ngx_strlen(environ[7]) + 1  =17
size=197

i=8
environ[8]="LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:"
ngx_strlen(environ[8]) + 1  =1519
size=1716

i=9
environ[9]="XDG_CURRENT_DESKTOP=ubuntu:GNOME"
ngx_strlen(environ[9]) + 1  =33
size=1749

i=10
environ[10]="TERM=xterm-256color"
ngx_strlen(environ[10]) + 1  =20
size=1769

i=11
environ[11]="LC_IDENTIFICATION=zh_CN.UTF-8"
ngx_strlen(environ[11]) + 1  =30
size=1799

i=12
environ[12]="DISPLAY=:0"
ngx_strlen(environ[12]) + 1  =11
size=1810

i=13
environ[13]="LC_TELEPHONE=zh_CN.UTF-8"
ngx_strlen(environ[13]) + 1  =25
size=1835

i=14
environ[14]="LC_MEASUREMENT=zh_CN.UTF-8"
ngx_strlen(environ[14]) + 1  =27
size=1862

i=15
environ[15]="LC_TIME=zh_CN.UTF-8"
ngx_strlen(environ[15]) + 1  =20
size=1882

i=16
environ[16]="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
ngx_strlen(environ[16]) + 1  =76
size=1958

i=17
environ[17]="LC_NUMERIC=zh_CN.UTF-8"
ngx_strlen(environ[17]) + 1  =23
size=1981

i=18
environ[18]="MAIL=/var/mail/root"
ngx_strlen(environ[18]) + 1  =20
size=2001

i=19
environ[19]="LOGNAME=root"
ngx_strlen(environ[19]) + 1  =13
size=2014

i=20
environ[20]="USER=root"
ngx_strlen(environ[20]) + 1  =10
size=2024

i=21
environ[21]="HOME=/root"
ngx_strlen(environ[21]) + 1  =11
size=2035

i=22
environ[22]="SHELL=/bin/bash"
ngx_strlen(environ[22]) + 1  =16
size=2051

i=23
environ[23]="SUDO_COMMAND=./nginx"
ngx_strlen(environ[23]) + 1  =21
size=2072

i=24
environ[24]="SUDO_USER=wsd"
ngx_strlen(environ[24]) + 1  =14
size=2086

i=25
environ[25]="SUDO_UID=1000"
ngx_strlen(environ[25]) + 1  =14
size=2100

i=26
environ[26]="SUDO_GID=1000"
ngx_strlen(environ[26]) + 1  =14
size=2114

 接下来是:

   p = ngx_alloc(size, log);
    if (p == NULL) {
        return NGX_ERROR;
    }

为环境变量分配内存,环境变量将要迁移到新分配的内存中

此次运行的情况:

p = ngx_alloc(size=2114, log);

p=0x654273b10f20

  接下来是:

    ngx_os_argv_last = ngx_os_argv[0];

ngx_os_argv_last 将用于标记命令行参数可用的边界

ngx_os_argv[0] 是存储参数的那片内存的首地址

 接下来是:

for (i = 0; ngx_os_argv[i]; i++) {
        if (ngx_os_argv_last == ngx_os_argv[i]) {
            ngx_os_argv_last = ngx_os_argv[i] + ngx_strlen(ngx_os_argv[i]) + 1;
        }
    }

循环,每次循环获取下一个参数的首地址,直到这个地址为 null,

null 是标记,意味着到此为止,后面没有更多的参数了

ngx_os_argv[i] 是参数首地址,ngx_strlen(ngx_os_argv[i])  是参数的长度,最后再 + 1,就越过了这个参数的最后一个字节成了下一个参数的最后一个字节

所以下一次循环时 ngx_os_argv[i] 是下一个参数的首地址 等于 上一次循环被重新赋值的 ngx_os_argv_last 

这样 ngx_os_argv_last 的值在不断的向后移动,直到它等于存贮参数的内存的最后一个字节的下一个字节(也是环境变量的第一个字节)

此次的执行情况是:

i=0
ngx_os_argv_last(0x7ffecc4747a6) == ngx_os_argv[0](0x7ffecc4747a6)  
ngx_os_argv_last(0x7ffecc4747ae) = ngx_os_argv[0] + ngx_strlen(ngx_os_argv[0])(7) + 1;

因为此次运行时没有给命令行参数,所以 只有一个参数,也就是运行的程序名

 接下来是:

for (i = 0; environ[i]; i++) {
        if (ngx_os_argv_last == environ[i]) {

            size = ngx_strlen(environ[i]) + 1;
            ngx_os_argv_last = environ[i] + size;

            ngx_cpystrn(p, (u_char *) environ[i], size);
            environ[i] = (char *) p;
            p += size;
        }
    }

现在 ngx_os_argv_last 等于环境变量的首地址

循环逻辑与上一个循环相同

ngx_os_argv_last 逐渐向后移

每次遍历还会将 环境变量依次迁移到新分配的内存

此次的运行情况:

i=0
ngx_os_argv_last(=0x7ffde3e967ae) == environ[0](=0x7ffde3e967ae)
size(=20) = ngx_strlen(environ[0])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e967c2) = environ[0](=0x7ffde3e967ae) + size(=20);
ngx_cpystrn(0x62a807451f20, 0x7ffde3e967ae, 20);
environ[0](=0x62a807451f20) = (char *) p(=0x62a807451f20);
 p(=0x62a807451f34) += size(=20); 

i=1
ngx_os_argv_last(=0x7ffde3e967c2) == environ[1](=0x7ffde3e967c2)
size(=18) = ngx_strlen(environ[1])(=17) + 1;
ngx_os_argv_last(=0x7ffde3e967d4) = environ[1](=0x7ffde3e967c2) + size(=18);
ngx_cpystrn(0x62a807451f34, 0x7ffde3e967c2, 18);
environ[1](=0x62a807451f34) = (char *) p(=0x62a807451f34);
 p(=0x62a807451f46) += size(=18); 

i=2
ngx_os_argv_last(=0x7ffde3e967d4) == environ[2](=0x7ffde3e967d4)
size(=23) = ngx_strlen(environ[2])(=22) + 1;
ngx_os_argv_last(=0x7ffde3e967eb) = environ[2](=0x7ffde3e967d4) + size(=23);
ngx_cpystrn(0x62a807451f46, 0x7ffde3e967d4, 23);
environ[2](=0x62a807451f46) = (char *) p(=0x62a807451f46);
 p(=0x62a807451f5d) += size(=23); 

i=3
ngx_os_argv_last(=0x7ffde3e967eb) == environ[3](=0x7ffde3e967eb)
size(=20) = ngx_strlen(environ[3])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e967ff) = environ[3](=0x7ffde3e967eb) + size(=20);
ngx_cpystrn(0x62a807451f5d, 0x7ffde3e967eb, 20);
environ[3](=0x62a807451f5d) = (char *) p(=0x62a807451f5d);
 p(=0x62a807451f71) += size(=20); 

i=4
ngx_os_argv_last(=0x7ffde3e967ff) == environ[4](=0x7ffde3e967ff)
size(=24) = ngx_strlen(environ[4])(=23) + 1;
ngx_os_argv_last(=0x7ffde3e96817) = environ[4](=0x7ffde3e967ff) + size(=24);
ngx_cpystrn(0x62a807451f71, 0x7ffde3e967ff, 24);
environ[4](=0x62a807451f71) = (char *) p(=0x62a807451f71);
 p(=0x62a807451f89) += size(=24); 

i=5
ngx_os_argv_last(=0x7ffde3e96817) == environ[5](=0x7ffde3e96817)
size(=54) = ngx_strlen(environ[5])(=53) + 1;
ngx_os_argv_last(=0x7ffde3e9684d) = environ[5](=0x7ffde3e96817) + size(=54);
ngx_cpystrn(0x62a807451f89, 0x7ffde3e96817, 54);
environ[5](=0x62a807451f89) = (char *) p(=0x62a807451f89);
 p(=0x62a807451fbf) += size(=54); 

i=6
ngx_os_argv_last(=0x7ffde3e9684d) == environ[6](=0x7ffde3e9684d)
size(=21) = ngx_strlen(environ[6])(=20) + 1;
ngx_os_argv_last(=0x7ffde3e96862) = environ[6](=0x7ffde3e9684d) + size(=21);
ngx_cpystrn(0x62a807451fbf, 0x7ffde3e9684d, 21);
environ[6](=0x62a807451fbf) = (char *) p(=0x62a807451fbf);
 p(=0x62a807451fd4) += size(=21); 

i=7
ngx_os_argv_last(=0x7ffde3e96862) == environ[7](=0x7ffde3e96862)
size(=17) = ngx_strlen(environ[7])(=16) + 1;
ngx_os_argv_last(=0x7ffde3e96873) = environ[7](=0x7ffde3e96862) + size(=17);
ngx_cpystrn(0x62a807451fd4, 0x7ffde3e96862, 17);
environ[7](=0x62a807451fd4) = (char *) p(=0x62a807451fd4);
 p(=0x62a807451fe5) += size(=17); 

i=8
ngx_os_argv_last(=0x7ffde3e96873) == environ[8](=0x7ffde3e96873)
size(=1519) = ngx_strlen(environ[8])(=1518) + 1;
ngx_os_argv_last(=0x7ffde3e96e62) = environ[8](=0x7ffde3e96873) + size(=1519);
ngx_cpystrn(0x62a807451fe5, 0x7ffde3e96873, 1519);
environ[8](=0x62a807451fe5) = (char *) p(=0x62a807451fe5);
 p(=0x62a8074525d4) += size(=1519); 

i=9
ngx_os_argv_last(=0x7ffde3e96e62) == environ[9](=0x7ffde3e96e62)
size(=33) = ngx_strlen(environ[9])(=32) + 1;
ngx_os_argv_last(=0x7ffde3e96e83) = environ[9](=0x7ffde3e96e62) + size(=33);
ngx_cpystrn(0x62a8074525d4, 0x7ffde3e96e62, 33);
environ[9](=0x62a8074525d4) = (char *) p(=0x62a8074525d4);
 p(=0x62a8074525f5) += size(=33); 

i=10
ngx_os_argv_last(=0x7ffde3e96e83) == environ[10](=0x7ffde3e96e83)
size(=20) = ngx_strlen(environ[10])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e96e97) = environ[10](=0x7ffde3e96e83) + size(=20);
ngx_cpystrn(0x62a8074525f5, 0x7ffde3e96e83, 20);
environ[10](=0x62a8074525f5) = (char *) p(=0x62a8074525f5);
 p(=0x62a807452609) += size(=20); 

i=11
ngx_os_argv_last(=0x7ffde3e96e97) == environ[11](=0x7ffde3e96e97)
size(=30) = ngx_strlen(environ[11])(=29) + 1;
ngx_os_argv_last(=0x7ffde3e96eb5) = environ[11](=0x7ffde3e96e97) + size(=30);
ngx_cpystrn(0x62a807452609, 0x7ffde3e96e97, 30);
environ[11](=0x62a807452609) = (char *) p(=0x62a807452609);
 p(=0x62a807452627) += size(=30); 

i=12
ngx_os_argv_last(=0x7ffde3e96eb5) == environ[12](=0x7ffde3e96eb5)
size(=11) = ngx_strlen(environ[12])(=10) + 1;
ngx_os_argv_last(=0x7ffde3e96ec0) = environ[12](=0x7ffde3e96eb5) + size(=11);
ngx_cpystrn(0x62a807452627, 0x7ffde3e96eb5, 11);
environ[12](=0x62a807452627) = (char *) p(=0x62a807452627);
 p(=0x62a807452632) += size(=11); 

i=13
ngx_os_argv_last(=0x7ffde3e96ec0) == environ[13](=0x7ffde3e96ec0)
size(=25) = ngx_strlen(environ[13])(=24) + 1;
ngx_os_argv_last(=0x7ffde3e96ed9) = environ[13](=0x7ffde3e96ec0) + size(=25);
ngx_cpystrn(0x62a807452632, 0x7ffde3e96ec0, 25);
environ[13](=0x62a807452632) = (char *) p(=0x62a807452632);
 p(=0x62a80745264b) += size(=25); 

i=14
ngx_os_argv_last(=0x7ffde3e96ed9) == environ[14](=0x7ffde3e96ed9)
size(=27) = ngx_strlen(environ[14])(=26) + 1;
ngx_os_argv_last(=0x7ffde3e96ef4) = environ[14](=0x7ffde3e96ed9) + size(=27);
ngx_cpystrn(0x62a80745264b, 0x7ffde3e96ed9, 27);
environ[14](=0x62a80745264b) = (char *) p(=0x62a80745264b);
 p(=0x62a807452666) += size(=27); 

i=15
ngx_os_argv_last(=0x7ffde3e96ef4) == environ[15](=0x7ffde3e96ef4)
size(=20) = ngx_strlen(environ[15])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e96f08) = environ[15](=0x7ffde3e96ef4) + size(=20);
ngx_cpystrn(0x62a807452666, 0x7ffde3e96ef4, 20);
environ[15](=0x62a807452666) = (char *) p(=0x62a807452666);
 p(=0x62a80745267a) += size(=20); 

i=16
ngx_os_argv_last(=0x7ffde3e96f08) == environ[16](=0x7ffde3e96f08)
size(=76) = ngx_strlen(environ[16])(=75) + 1;
ngx_os_argv_last(=0x7ffde3e96f54) = environ[16](=0x7ffde3e96f08) + size(=76);
ngx_cpystrn(0x62a80745267a, 0x7ffde3e96f08, 76);
environ[16](=0x62a80745267a) = (char *) p(=0x62a80745267a);
 p(=0x62a8074526c6) += size(=76); 

i=17
ngx_os_argv_last(=0x7ffde3e96f54) == environ[17](=0x7ffde3e96f54)
size(=23) = ngx_strlen(environ[17])(=22) + 1;
ngx_os_argv_last(=0x7ffde3e96f6b) = environ[17](=0x7ffde3e96f54) + size(=23);
ngx_cpystrn(0x62a8074526c6, 0x7ffde3e96f54, 23);
environ[17](=0x62a8074526c6) = (char *) p(=0x62a8074526c6);
 p(=0x62a8074526dd) += size(=23); 

i=18
ngx_os_argv_last(=0x7ffde3e96f6b) == environ[18](=0x7ffde3e96f6b)
size(=20) = ngx_strlen(environ[18])(=19) + 1;
ngx_os_argv_last(=0x7ffde3e96f7f) = environ[18](=0x7ffde3e96f6b) + size(=20);
ngx_cpystrn(0x62a8074526dd, 0x7ffde3e96f6b, 20);
environ[18](=0x62a8074526dd) = (char *) p(=0x62a8074526dd);
 p(=0x62a8074526f1) += size(=20); 

i=19
ngx_os_argv_last(=0x7ffde3e96f7f) == environ[19](=0x7ffde3e96f7f)
size(=13) = ngx_strlen(environ[19])(=12) + 1;
ngx_os_argv_last(=0x7ffde3e96f8c) = environ[19](=0x7ffde3e96f7f) + size(=13);
ngx_cpystrn(0x62a8074526f1, 0x7ffde3e96f7f, 13);
environ[19](=0x62a8074526f1) = (char *) p(=0x62a8074526f1);
 p(=0x62a8074526fe) += size(=13); 

i=20
ngx_os_argv_last(=0x7ffde3e96f8c) == environ[20](=0x7ffde3e96f8c)
size(=10) = ngx_strlen(environ[20])(=9) + 1;
ngx_os_argv_last(=0x7ffde3e96f96) = environ[20](=0x7ffde3e96f8c) + size(=10);
ngx_cpystrn(0x62a8074526fe, 0x7ffde3e96f8c, 10);
environ[20](=0x62a8074526fe) = (char *) p(=0x62a8074526fe);
 p(=0x62a807452708) += size(=10); 

i=21
ngx_os_argv_last(=0x7ffde3e96f96) == environ[21](=0x7ffde3e96f96)
size(=11) = ngx_strlen(environ[21])(=10) + 1;
ngx_os_argv_last(=0x7ffde3e96fa1) = environ[21](=0x7ffde3e96f96) + size(=11);
ngx_cpystrn(0x62a807452708, 0x7ffde3e96f96, 11);
environ[21](=0x62a807452708) = (char *) p(=0x62a807452708);
 p(=0x62a807452713) += size(=11); 

i=22
ngx_os_argv_last(=0x7ffde3e96fa1) == environ[22](=0x7ffde3e96fa1)
size(=16) = ngx_strlen(environ[22])(=15) + 1;
ngx_os_argv_last(=0x7ffde3e96fb1) = environ[22](=0x7ffde3e96fa1) + size(=16);
ngx_cpystrn(0x62a807452713, 0x7ffde3e96fa1, 16);
environ[22](=0x62a807452713) = (char *) p(=0x62a807452713);
 p(=0x62a807452723) += size(=16); 

i=23
ngx_os_argv_last(=0x7ffde3e96fb1) == environ[23](=0x7ffde3e96fb1)
size(=21) = ngx_strlen(environ[23])(=20) + 1;
ngx_os_argv_last(=0x7ffde3e96fc6) = environ[23](=0x7ffde3e96fb1) + size(=21);
ngx_cpystrn(0x62a807452723, 0x7ffde3e96fb1, 21);
environ[23](=0x62a807452723) = (char *) p(=0x62a807452723);
 p(=0x62a807452738) += size(=21); 

i=24
ngx_os_argv_last(=0x7ffde3e96fc6) == environ[24](=0x7ffde3e96fc6)
size(=14) = ngx_strlen(environ[24])(=13) + 1;
ngx_os_argv_last(=0x7ffde3e96fd4) = environ[24](=0x7ffde3e96fc6) + size(=14);
ngx_cpystrn(0x62a807452738, 0x7ffde3e96fc6, 14);
environ[24](=0x62a807452738) = (char *) p(=0x62a807452738);
 p(=0x62a807452746) += size(=14); 

i=25
ngx_os_argv_last(=0x7ffde3e96fd4) == environ[25](=0x7ffde3e96fd4)
size(=14) = ngx_strlen(environ[25])(=13) + 1;
ngx_os_argv_last(=0x7ffde3e96fe2) = environ[25](=0x7ffde3e96fd4) + size(=14);
ngx_cpystrn(0x62a807452746, 0x7ffde3e96fd4, 14);
environ[25](=0x62a807452746) = (char *) p(=0x62a807452746);
 p(=0x62a807452754) += size(=14); 

i=26
ngx_os_argv_last(=0x7ffde3e96fe2) == environ[26](=0x7ffde3e96fe2)
size(=14) = ngx_strlen(environ[26])(=13) + 1;
ngx_os_argv_last(=0x7ffde3e96ff0) = environ[26](=0x7ffde3e96fe2) + size(=14);
ngx_cpystrn(0x62a807452754, 0x7ffde3e96fe2, 14);
environ[26](=0x62a807452754) = (char *) p(=0x62a807452754);
 p(=0x62a807452762) += size(=14); 

  接下来是:

ngx_os_argv_last--;

    return NGX_OK;

 ngx_os_argv_last 的值 -1,指向原来存放环境变量的那片内存的最后一个字节

然后返回


 回到 ngx_os_init

  接下来是:

ngx_pagesize = getpagesize();

 获取 当前系统一页的大小是多少字节

此次的情况

ngx_pagesize=4096

   ngx_cacheline_size = NGX_CPU_CACHE_LINE;

 存储 CPU 缓存行大小,默认值为 NGX_CPU_CACHE_LINE

目前的情况:

 ngx_cacheline_size=64

for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }

计算页面大小的对数(ngx_pagesize_shift),即页面大小是 2 的多少次幂。

例如,4KB 的页面大小对应 ngx_pagesize_shift = 12

此次的情况:

ngx_pagesize_shift=12

  if (ngx_ncpu == 0) {
        ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);
    }

 获取当前系统在线的 CPU 核心数

此次的情况是:

ngx_ncpu=2

    if (ngx_ncpu < 1) {
        ngx_ncpu = 1;
    }

条件不成立,跳过这段代码

    size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
    if (size > 0) {
        ngx_cacheline_size = size;
    }

sysconf(_SC_LEVEL1_DCACHE_LINESIZE) :获取一级缓存行大小

成功就更新 ngx_cacheline_size ,之前的值是默认值

此次的情况:

获取成功,但获得的值和默认值一样

 ngx_cacheline_size=64

  接下来是:

    ngx_cpuinfo();

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_cpuinfo 函数-CSDN博客

接下来是:

    if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) {
        ngx_log_error(NGX_LOG_ALERT, log, errno,
                      "getrlimit(RLIMIT_NOFILE) failed");
        return NGX_ERROR;
    }

    ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur;

 获取文件描述符数量的限制

此次的情况是:

ngx_max_sockets=1024

#if (NGX_HAVE_INHERITED_NONBLOCK || NGX_HAVE_ACCEPT4)
    ngx_inherited_nonblocking = 1;
#else
    ngx_inherited_nonblocking = 0;
#endif

ngx_inherited_nonblocking :全局变量,指示当前环境是否支持继承非阻塞套接字 

当前情况:

ngx_inherited_nonblocking=1

   tp = ngx_timeofday();
    srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);

    return NGX_OK;

获取当前的时间缓存 用来 设置随机数种子 

返回 NGX_OK


回到 main 函数中

接下来是:

    if (ngx_crc32_table_init() != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_crc32_table_init 函数-CSDN博客

   ngx_slab_sizes_init();

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_slab_sizes_init 函数-CSDN博客

进入 ngx_slab_sizes_init

void
ngx_slab_sizes_init(void)
{
    ngx_uint_t  n;

    ngx_slab_max_size = ngx_pagesize / 2;
    ngx_slab_exact_size = ngx_pagesize / (8 * sizeof(uintptr_t));
    for (n = ngx_slab_exact_size; n >>= 1; ngx_slab_exact_shift++) {
        /* void */
    }
}

此次的情况是: 

ngx_slab_max_size=2048
ngx_slab_exact_size=64
ngx_slab_exact_shift=6


回到 main 函数中

接下来是:

   if (ngx_add_inherited_sockets(&init_cycle) != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_add_inherited_sockets函数-CSDN博客

进入 ngx_add_inherited_sockets

static ngx_int_t
ngx_add_inherited_sockets(ngx_cycle_t *cycle)
{
    u_char           *p, *v, *inherited;
    ngx_int_t         s;
    ngx_listening_t  *ls;

    inherited = (u_char *) getenv(NGINX_VAR);

此次 

inherited 是 null,没有需要继承的 套接字描述符

    if (inherited == NULL) {
        return NGX_OK;
    }

返回 NGX_OK


回到 main 函数中

接下来是:

    if (ngx_preinit_modules() != NGX_OK) {
        return 1;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_preinit_modules 函数-CSDN博客

进入 ngx_preinit_modules

ngx_int_t
ngx_preinit_modules(void)
{
    ngx_uint_t  i;

    for (i = 0; ngx_modules[i]; i++) {
        ngx_modules[i]->index = i;
        ngx_modules[i]->name = ngx_module_names[i];
    }

    ngx_modules_n = i;
    ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES;

    return NGX_OK;
}

进入循环,遍历 ngx_modules 数组

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_modules-CSDN博客

为每个模块的 index name 字段赋值

此次的情况是:

ngx_modules[0]->index = 0
ngx_modules[0]->name = ngx_core_module
ngx_modules[1]->index = 1
ngx_modules[1]->name = ngx_errlog_module
ngx_modules[2]->index = 2
ngx_modules[2]->name = ngx_conf_module
ngx_modules[3]->index = 3
ngx_modules[3]->name = ngx_openssl_module
ngx_modules[4]->index = 4
ngx_modules[4]->name = ngx_regex_module
ngx_modules[5]->index = 5
ngx_modules[5]->name = ngx_events_module
ngx_modules[6]->index = 6
ngx_modules[6]->name = ngx_event_core_module
ngx_modules[7]->index = 7
ngx_modules[7]->name = ngx_epoll_module
ngx_modules[8]->index = 8
ngx_modules[8]->name = ngx_http_module
ngx_modules[9]->index = 9
ngx_modules[9]->name = ngx_http_core_module
ngx_modules[10]->index = 10
ngx_modules[10]->name = ngx_http_log_module
ngx_modules[11]->index = 11
ngx_modules[11]->name = ngx_http_upstream_module
ngx_modules[12]->index = 12
ngx_modules[12]->name = ngx_http_v2_module
ngx_modules[13]->index = 13
ngx_modules[13]->name = ngx_http_static_module
ngx_modules[14]->index = 14
ngx_modules[14]->name = ngx_http_gzip_static_module
ngx_modules[15]->index = 15
ngx_modules[15]->name = ngx_http_autoindex_module
ngx_modules[16]->index = 16
ngx_modules[16]->name = ngx_http_index_module
ngx_modules[17]->index = 17
ngx_modules[17]->name = ngx_http_mirror_module
ngx_modules[18]->index = 18
ngx_modules[18]->name = ngx_http_try_files_module
ngx_modules[19]->index = 19
ngx_modules[19]->name = ngx_http_auth_basic_module
ngx_modules[20]->index = 20
ngx_modules[20]->name = ngx_http_access_module
ngx_modules[21]->index = 21
ngx_modules[21]->name = ngx_http_limit_conn_module
ngx_modules[22]->index = 22
ngx_modules[22]->name = ngx_http_limit_req_module
ngx_modules[23]->index = 23
ngx_modules[23]->name = ngx_http_geo_module
ngx_modules[24]->index = 24
ngx_modules[24]->name = ngx_http_map_module
ngx_modules[25]->index = 25
ngx_modules[25]->name = ngx_http_split_clients_module
ngx_modules[26]->index = 26
ngx_modules[26]->name = ngx_http_referer_module
ngx_modules[27]->index = 27
ngx_modules[27]->name = ngx_http_rewrite_module
ngx_modules[28]->index = 28
ngx_modules[28]->name = ngx_http_ssl_module
ngx_modules[29]->index = 29
ngx_modules[29]->name = ngx_http_proxy_module
ngx_modules[30]->index = 30
ngx_modules[30]->name = ngx_http_fastcgi_module
ngx_modules[31]->index = 31
ngx_modules[31]->name = ngx_http_uwsgi_module
ngx_modules[32]->index = 32
ngx_modules[32]->name = ngx_http_scgi_module
ngx_modules[33]->index = 33
ngx_modules[33]->name = ngx_http_grpc_module
ngx_modules[34]->index = 34
ngx_modules[34]->name = ngx_http_memcached_module
ngx_modules[35]->index = 35
ngx_modules[35]->name = ngx_http_empty_gif_module
ngx_modules[36]->index = 36
ngx_modules[36]->name = ngx_http_browser_module
ngx_modules[37]->index = 37
ngx_modules[37]->name = ngx_http_upstream_hash_module
ngx_modules[38]->index = 38
ngx_modules[38]->name = ngx_http_upstream_ip_hash_module
ngx_modules[39]->index = 39
ngx_modules[39]->name = ngx_http_upstream_least_conn_module
ngx_modules[40]->index = 40
ngx_modules[40]->name = ngx_http_upstream_random_module
ngx_modules[41]->index = 41
ngx_modules[41]->name = ngx_http_upstream_keepalive_module
ngx_modules[42]->index = 42
ngx_modules[42]->name = ngx_http_upstream_zone_module
ngx_modules[43]->index = 43
ngx_modules[43]->name = ngx_http_write_filter_module
ngx_modules[44]->index = 44
ngx_modules[44]->name = ngx_http_header_filter_module
ngx_modules[45]->index = 45
ngx_modules[45]->name = ngx_http_chunked_filter_module
ngx_modules[46]->index = 46
ngx_modules[46]->name = ngx_http_v2_filter_module
ngx_modules[47]->index = 47
ngx_modules[47]->name = ngx_http_range_header_filter_module
ngx_modules[48]->index = 48
ngx_modules[48]->name = ngx_http_gzip_filter_module
ngx_modules[49]->index = 49
ngx_modules[49]->name = ngx_http_postpone_filter_module
ngx_modules[50]->index = 50
ngx_modules[50]->name = ngx_http_ssi_filter_module
ngx_modules[51]->index = 51
ngx_modules[51]->name = ngx_http_charset_filter_module
ngx_modules[52]->index = 52
ngx_modules[52]->name = ngx_http_userid_filter_module
ngx_modules[53]->index = 53
ngx_modules[53]->name = ngx_http_headers_filter_module
ngx_modules[54]->index = 54
ngx_modules[54]->name = ngx_http_copy_filter_module
ngx_modules[55]->index = 55
ngx_modules[55]->name = ngx_http_range_body_filter_module
ngx_modules[56]->index = 56
ngx_modules[56]->name = ngx_http_not_modified_filter_module
ngx_modules[57]->index = 57
ngx_modules[57]->name = ngx_stream_module
ngx_modules[58]->index = 58
ngx_modules[58]->name = ngx_stream_core_module
ngx_modules[59]->index = 59
ngx_modules[59]->name = ngx_stream_log_module
ngx_modules[60]->index = 60
ngx_modules[60]->name = ngx_stream_proxy_module
ngx_modules[61]->index = 61
ngx_modules[61]->name = ngx_stream_upstream_module
ngx_modules[62]->index = 62
ngx_modules[62]->name = ngx_stream_write_filter_module
ngx_modules[63]->index = 63
ngx_modules[63]->name = ngx_stream_ssl_module
ngx_modules[64]->index = 64
ngx_modules[64]->name = ngx_stream_limit_conn_module
ngx_modules[65]->index = 65
ngx_modules[65]->name = ngx_stream_access_module
ngx_modules[66]->index = 66
ngx_modules[66]->name = ngx_stream_geo_module
ngx_modules[67]->index = 67
ngx_modules[67]->name = ngx_stream_map_module
ngx_modules[68]->index = 68
ngx_modules[68]->name = ngx_stream_split_clients_module
ngx_modules[69]->index = 69
ngx_modules[69]->name = ngx_stream_return_module
ngx_modules[70]->index = 70
ngx_modules[70]->name = ngx_stream_set_module
ngx_modules[71]->index = 71
ngx_modules[71]->name = ngx_stream_upstream_hash_module
ngx_modules[72]->index = 72
ngx_modules[72]->name = ngx_stream_upstream_least_conn_module
ngx_modules[73]->index = 73
ngx_modules[73]->name = ngx_stream_upstream_random_module
ngx_modules[74]->index = 74
ngx_modules[74]->name = ngx_stream_upstream_zone_module

ngx_modules_n 静态模块的总数

ngx_max_module 表示Nginx支持的最大模块数量

NGX_MAX_DYNAMIC_MODULES  动态加载模块的最大数量

ngx_modules_n=75
ngx_max_module(=203) = ngx_modules_n(75) + NGX_MAX_DYNAMIC_MODULES(128)  


回到 main 函数中

接下来是:

cycle = ngx_init_cycle(&init_cycle);
    if (cycle == NULL) {
        if (ngx_test_config) {
            ngx_log_stderr(0, "configuration file %s test failed",
                           init_cycle.conf_file.data);
        }

        return 1;
    }

调用 ngx_init_cycle

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_init_cycle 函数-CSDN博客

进入 ngx_init_cycle

ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
    void                *rv;
    char               **senv;
    ngx_uint_t           i, n;
    ngx_log_t           *log;
    ngx_time_t          *tp;
    ngx_conf_t           conf;
    ngx_pool_t          *pool;
    ngx_cycle_t         *cycle, **old;
    ngx_shm_zone_t      *shm_zone, *oshm_zone;
    ngx_list_part_t     *part, *opart;
    ngx_open_file_t     *file;
    ngx_listening_t     *ls, *nls;
    ngx_core_conf_t     *ccf, *old_ccf;
    ngx_core_module_t   *module;
    char                 hostname[NGX_MAXHOSTNAMELEN];

    ngx_timezone_update();

    /* force localtime update with a new timezone */

    tp = ngx_timeofday();
    tp->sec = 0;

    ngx_time_update();

更新时间

   log = old_cycle->log;

获取之前的 log 对象,暂时还是用它来记录 log

   pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
    if (pool == NULL) {
        return NULL;
    }
    pool->log = log;

创建一个新的内存池,然后设置它使用的 log

此次的情况是:

pool = ngx_create_pool(16384, log)
pool= 0x5f33e4db67b0 (地址)

接下来是: 

   cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
    if (cycle == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

此次的情况是:

cycle = ngx_pcalloc(pool, 648);
cycle= 0x5c67408e7800 

    cycle->pool = pool;
    cycle->log = log;
    cycle->old_cycle = old_cycle;
   cycle->conf_prefix.len = old_cycle->conf_prefix.len;
    cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
    if (cycle->conf_prefix.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

给字段赋值

此次的情况是:

cycle->conf_prefix.len =28
cycle->conf_prefix.data=/home/wsd/桌面/nginx/conf/ 

    cycle->prefix.len = old_cycle->prefix.len;
    cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
    if (cycle->prefix.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

此次的情况是:

cycle->prefix.len = 17)
cycle->prefix.data= /usr/local/nginx/

    cycle->error_log.len = old_cycle->error_log.len;
    cycle->error_log.data = ngx_pnalloc(pool, old_cycle->error_log.len + 1);
    if (cycle->error_log.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }
    ngx_cpystrn(cycle->error_log.data, old_cycle->error_log.data,
                old_cycle->error_log.len + 1);

此次的情况是:

cycle->error_log.len=36 

cycle->error_log.data=/home/wsd/桌面/nginx/LOG/error.log 

   cycle->conf_file.len = old_cycle->conf_file.len;
    cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
    if (cycle->conf_file.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }
    ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
                old_cycle->conf_file.len + 1);

此次的情况是:

cycle->conf_file.len=38
cycle->conf_file.data=/home/wsd/桌面/nginx/conf/nginx.conf

    cycle->conf_param.len = old_cycle->conf_param.len;
    cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
    if (cycle->conf_param.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

此次的情况是:

cycle->conf_param.len=0
cycle->conf_param.data 是 null

运行时没有给命令行参数

    n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;

 此次的情况是:

n = 0 ? 0 : 10;
n=10

    if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *))
        != NGX_OK)
    {
        ngx_destroy_pool(pool);
        return NULL;
    }

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_array_init 函数-CSDN博客

    ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *));

 将 paths 数组的前 n 个元素清零

    if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))
        != NGX_OK)
    {
        ngx_destroy_pool(pool);
        return NULL;
    }

 初始化数组 config_dump

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_conf_dump_t-CSDN博客

    ngx_rbtree_init(&cycle->config_dump_rbtree, &cycle->config_dump_sentinel,
                    ngx_str_rbtree_insert_value);

 Ubuntu 下 nginx-1.24.0 源码分析 - ngx_rbtree_init-CSDN博客

   if (old_cycle->open_files.part.nelts) {
        n = old_cycle->open_files.part.nelts;
        for (part = old_cycle->open_files.part.next; part; part = part->next) {
            n += part->nelts;
        }

    } else {
        n = 20;
    }

此次运行的情况是:

old_cycle->open_files.part.nelts=0

所以进入 else 
n=20

if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
        != NGX_OK)
    {
        ngx_destroy_pool(pool);
        return NULL;
    }

初始化新周期的 open_files 列表。

此次运行的情况是:

ngx_list_init(&cycle->open_files, pool, n=20, sizeof(ngx_open_file_t)=40)

    if (old_cycle->shared_memory.part.nelts) {
        n = old_cycle->shared_memory.part.nelts;
        for (part = old_cycle->shared_memory.part.next; part; part = part->next)
        {
            n += part->nelts;
        }

    } else {
        n = 1;
    }

 设置新周期的 shared_memory 的元素数量

此次运行的情况是:

old_cycle->shared_memory.part.nelts=0 

所以 进入else
n=1

  if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
        != NGX_OK)
    {
        ngx_destroy_pool(pool);
        return NULL;
    }

 初始化 shared_memory

此次运行的情况是:


ngx_list_init(&cycle->shared_memory, pool, n=1, sizeof(ngx_shm_zone_t)=88 )

   n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;

 此次运行的情况是:

n(=10) = old_cycle->listening.nelts(=0) ? old_cycle->listening.nelts(=0) : 10 

  if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t))
        != NGX_OK)
    {
        ngx_destroy_pool(pool);
        return NULL;
    }

初始化 cycle->listening 数组

此次运行的情况是:

ngx_array_init(&cycle->listening, pool, n(=10), sizeof(ngx_listening_t)(=296))  

    ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t));

cycle->listening 内存区域清 0

   ngx_queue_init(&cycle->reusable_connections_queue);
    cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
    if (cycle->conf_ctx == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

从内存池 pool 中分配一个指针数组 conf_ctx,每个元素对应一个模块的配置结构指针。 


    if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
        ngx_destroy_pool(pool);
        return NULL;
    }

调用 gethostname() 系统调用获取本地主机名,存储到 hostname 缓冲区。

    hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
    cycle->hostname.len = ngx_strlen(hostname);

确保 hostname 以 \0 结尾

计算主机名的实际长度(不含终止符),存储到 cycle->hostname.len 

    cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
    if (cycle->hostname.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

从内存池 pool 分配内存,存储主机名的副本

    ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);

将主机名转换为全小写,存储到 cycle->hostname.data

此次运行的情况是:

hostname=wsd-vm 
cycle->hostname.len=6
cycle->hostname.data = ngx_pnalloc(pool, 6) 
cycle->hostname.data=0x6165d5b590d0 地址
cycle->hostname.data = wsd-vm

    if (ngx_cycle_modules(cycle) != NGX_OK) {
        ngx_destroy_pool(pool);
        return NULL;
    }

调用 ngx_cycle_modules 初始化 cycle->modules 数组,该数组包含所有核心模块的指针


    for (i = 0; cycle->modules[i]; i++) {
        if (cycle->modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

遍历所有核心模块

module = cycle->modules[i]->ctx;

获取核心模块的配置

if (module->create_conf) {
            rv = module->create_conf(cycle);
            if (rv == NULL) {
                ngx_destroy_pool(pool);
                return NULL;
            }
            cycle->conf_ctx[cycle->modules[i]->index] = rv;
        }
    }

调用模块的 create_conf 方法创建默认配置结构,并将其存储到 conf_ctx 数组的对应位置。

此次运行的情况是:

i=0
cycle->modules[0]->name = ngx_core_module
cycle->modules[0]->type == NGX_CORE_MODULE
module->create_conf = 0x5c9ee022c9b8 
cycle->conf_ctx[0] = 0x5c9f13b4c738

i=1
cycle->modules[1]->name = ngx_errlog_module
cycle->modules[1]->type == NGX_CORE_MODULE
module->create_conf = (nil) 

i=2
cycle->modules[2]->name = ngx_conf_module
cycle->modules[2]->type != NGX_CORE_MODULE 
continue 

i=3
cycle->modules[3]->name = ngx_openssl_module
cycle->modules[3]->type == NGX_CORE_MODULE
module->create_conf = 0x5c9ee02587ea 
cycle->conf_ctx[3] = 0x5c9f13b4c830

i=4
cycle->modules[4]->name = ngx_regex_module
cycle->modules[4]->type == NGX_CORE_MODULE
module->create_conf = 0x5c9ee0263174 
cycle->conf_ctx[4] = 0x5c9f13b4c838

i=5
cycle->modules[5]->name = ngx_events_module
cycle->modules[5]->type == NGX_CORE_MODULE
module->create_conf = (nil) 

i=6
cycle->modules[6]->name = ngx_event_core_module
cycle->modules[6]->type != NGX_CORE_MODULE 
continue 

i=7
cycle->modules[7]->name = ngx_epoll_module
cycle->modules[7]->type != NGX_CORE_MODULE 
continue 

i=8
cycle->modules[8]->name = ngx_http_module
cycle->modules[8]->type == NGX_CORE_MODULE
module->create_conf = (nil) 

i=9
cycle->modules[9]->name = ngx_http_core_module
cycle->modules[9]->type != NGX_CORE_MODULE 
continue 

i=10
cycle->modules[10]->name = ngx_http_log_module
cycle->modules[10]->type != NGX_CORE_MODULE 
continue 

i=11
cycle->modules[11]->name = ngx_http_upstream_module
cycle->modules[11]->type != NGX_CORE_MODULE 
continue 

i=12
cycle->modules[12]->name = ngx_http_v2_module
cycle->modules[12]->type != NGX_CORE_MODULE 
continue 

i=13
cycle->modules[13]->name = ngx_http_static_module
cycle->modules[13]->type != NGX_CORE_MODULE 
continue 

i=14
cycle->modules[14]->name = ngx_http_gzip_static_module
cycle->modules[14]->type != NGX_CORE_MODULE 
continue 

i=15
cycle->modules[15]->name = ngx_http_autoindex_module
cycle->modules[15]->type != NGX_CORE_MODULE 
continue 

i=16
cycle->modules[16]->name = ngx_http_index_module
cycle->modules[16]->type != NGX_CORE_MODULE 
continue 

i=17
cycle->modules[17]->name = ngx_http_mirror_module
cycle->modules[17]->type != NGX_CORE_MODULE 
continue 

i=18
cycle->modules[18]->name = ngx_http_try_files_module
cycle->modules[18]->type != NGX_CORE_MODULE 
continue 

i=19
cycle->modules[19]->name = ngx_http_auth_basic_module
cycle->modules[19]->type != NGX_CORE_MODULE 
continue 

i=20
cycle->modules[20]->name = ngx_http_access_module
cycle->modules[20]->type != NGX_CORE_MODULE 
continue 

i=21
cycle->modules[21]->name = ngx_http_limit_conn_module
cycle->modules[21]->type != NGX_CORE_MODULE 
continue 

i=22
cycle->modules[22]->name = ngx_http_limit_req_module
cycle->modules[22]->type != NGX_CORE_MODULE 
continue 

i=23
cycle->modules[23]->name = ngx_http_geo_module
cycle->modules[23]->type != NGX_CORE_MODULE 
continue 

i=24
cycle->modules[24]->name = ngx_http_map_module
cycle->modules[24]->type != NGX_CORE_MODULE 
continue 

i=25
cycle->modules[25]->name = ngx_http_split_clients_module
cycle->modules[25]->type != NGX_CORE_MODULE 
continue 

i=26
cycle->modules[26]->name = ngx_http_referer_module
cycle->modules[26]->type != NGX_CORE_MODULE 
continue 

i=27
cycle->modules[27]->name = ngx_http_rewrite_module
cycle->modules[27]->type != NGX_CORE_MODULE 
continue 

i=28
cycle->modules[28]->name = ngx_http_ssl_module
cycle->modules[28]->type != NGX_CORE_MODULE 
continue 

i=29
cycle->modules[29]->name = ngx_http_proxy_module
cycle->modules[29]->type != NGX_CORE_MODULE 
continue 

i=30
cycle->modules[30]->name = ngx_http_fastcgi_module
cycle->modules[30]->type != NGX_CORE_MODULE 
continue 

i=31
cycle->modules[31]->name = ngx_http_uwsgi_module
cycle->modules[31]->type != NGX_CORE_MODULE 
continue 

i=32
cycle->modules[32]->name = ngx_http_scgi_module
cycle->modules[32]->type != NGX_CORE_MODULE 
continue 

i=33
cycle->modules[33]->name = ngx_http_grpc_module
cycle->modules[33]->type != NGX_CORE_MODULE 
continue 

i=34
cycle->modules[34]->name = ngx_http_memcached_module
cycle->modules[34]->type != NGX_CORE_MODULE 
continue 

i=35
cycle->modules[35]->name = ngx_http_empty_gif_module
cycle->modules[35]->type != NGX_CORE_MODULE 
continue 

i=36
cycle->modules[36]->name = ngx_http_browser_module
cycle->modules[36]->type != NGX_CORE_MODULE 
continue 

i=37
cycle->modules[37]->name = ngx_http_upstream_hash_module
cycle->modules[37]->type != NGX_CORE_MODULE 
continue 

i=38
cycle->modules[38]->name = ngx_http_upstream_ip_hash_module
cycle->modules[38]->type != NGX_CORE_MODULE 
continue 

i=39
cycle->modules[39]->name = ngx_http_upstream_least_conn_module
cycle->modules[39]->type != NGX_CORE_MODULE 
continue 

i=40
cycle->modules[40]->name = ngx_http_upstream_random_module
cycle->modules[40]->type != NGX_CORE_MODULE 
continue 

i=41
cycle->modules[41]->name = ngx_http_upstream_keepalive_module
cycle->modules[41]->type != NGX_CORE_MODULE 
continue 

i=42
cycle->modules[42]->name = ngx_http_upstream_zone_module
cycle->modules[42]->type != NGX_CORE_MODULE 
continue 

i=43
cycle->modules[43]->name = ngx_http_write_filter_module
cycle->modules[43]->type != NGX_CORE_MODULE 
continue 

i=44
cycle->modules[44]->name = ngx_http_header_filter_module
cycle->modules[44]->type != NGX_CORE_MODULE 
continue 

i=45
cycle->modules[45]->name = ngx_http_chunked_filter_module
cycle->modules[45]->type != NGX_CORE_MODULE 
continue 

i=46
cycle->modules[46]->name = ngx_http_v2_filter_module
cycle->modules[46]->type != NGX_CORE_MODULE 
continue 

i=47
cycle->modules[47]->name = ngx_http_range_header_filter_module
cycle->modules[47]->type != NGX_CORE_MODULE 
continue 

i=48
cycle->modules[48]->name = ngx_http_gzip_filter_module
cycle->modules[48]->type != NGX_CORE_MODULE 
continue 

i=49
cycle->modules[49]->name = ngx_http_postpone_filter_module
cycle->modules[49]->type != NGX_CORE_MODULE 
continue 

i=50
cycle->modules[50]->name = ngx_http_ssi_filter_module
cycle->modules[50]->type != NGX_CORE_MODULE 
continue 

i=51
cycle->modules[51]->name = ngx_http_charset_filter_module
cycle->modules[51]->type != NGX_CORE_MODULE 
continue 

i=52
cycle->modules[52]->name = ngx_http_userid_filter_module
cycle->modules[52]->type != NGX_CORE_MODULE 
continue 

i=53
cycle->modules[53]->name = ngx_http_headers_filter_module
cycle->modules[53]->type != NGX_CORE_MODULE 
continue 

i=54
cycle->modules[54]->name = ngx_http_copy_filter_module
cycle->modules[54]->type != NGX_CORE_MODULE 
continue 

i=55
cycle->modules[55]->name = ngx_http_range_body_filter_module
cycle->modules[55]->type != NGX_CORE_MODULE 
continue 

i=56
cycle->modules[56]->name = ngx_http_not_modified_filter_module
cycle->modules[56]->type != NGX_CORE_MODULE 
continue 

i=57
cycle->modules[57]->name = ngx_stream_module
cycle->modules[57]->type == NGX_CORE_MODULE
module->create_conf = (nil) 

i=58
cycle->modules[58]->name = ngx_stream_core_module
cycle->modules[58]->type != NGX_CORE_MODULE 
continue 

i=59
cycle->modules[59]->name = ngx_stream_log_module
cycle->modules[59]->type != NGX_CORE_MODULE 
continue 

i=60
cycle->modules[60]->name = ngx_stream_proxy_module
cycle->modules[60]->type != NGX_CORE_MODULE 
continue 

i=61
cycle->modules[61]->name = ngx_stream_upstream_module
cycle->modules[61]->type != NGX_CORE_MODULE 
continue 

i=62
cycle->modules[62]->name = ngx_stream_write_filter_module
cycle->modules[62]->type != NGX_CORE_MODULE 
continue 

i=63
cycle->modules[63]->name = ngx_stream_ssl_module
cycle->modules[63]->type != NGX_CORE_MODULE 
continue 

i=64
cycle->modules[64]->name = ngx_stream_limit_conn_module
cycle->modules[64]->type != NGX_CORE_MODULE 
continue 

i=65
cycle->modules[65]->name = ngx_stream_access_module
cycle->modules[65]->type != NGX_CORE_MODULE 
continue 

i=66
cycle->modules[66]->name = ngx_stream_geo_module
cycle->modules[66]->type != NGX_CORE_MODULE 
continue 

i=67
cycle->modules[67]->name = ngx_stream_map_module
cycle->modules[67]->type != NGX_CORE_MODULE 
continue 

i=68
cycle->modules[68]->name = ngx_stream_split_clients_module
cycle->modules[68]->type != NGX_CORE_MODULE 
continue 

i=69
cycle->modules[69]->name = ngx_stream_return_module
cycle->modules[69]->type != NGX_CORE_MODULE 
continue 

i=70
cycle->modules[70]->name = ngx_stream_set_module
cycle->modules[70]->type != NGX_CORE_MODULE 
continue 

i=71
cycle->modules[71]->name = ngx_stream_upstream_hash_module
cycle->modules[71]->type != NGX_CORE_MODULE 
continue 

i=72
cycle->modules[72]->name = ngx_stream_upstream_least_conn_module
cycle->modules[72]->type != NGX_CORE_MODULE 
continue 

i=73
cycle->modules[73]->name = ngx_stream_upstream_random_module
cycle->modules[73]->type != NGX_CORE_MODULE 
continue 

i=74
cycle->modules[74]->name = ngx_stream_upstream_zone_module
cycle->modules[74]->type != NGX_CORE_MODULE 
continue 

第一个模块是 ngx_core_module  

它的 create_conf 存在

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_core_module-CSDN博客


进入 它的 create_conf

ngx_core_module_create_conf-CSDN博客


第二个 NGX_CORE_MODULE 模块是 ngx_errlog_module

ngx_errlog_module-CSDN博客

它的 create_conf 是NULL
 


 下一个有 create_conf NGX_CORE_MODULE 模块

ngx_openssl_module

ngx_openssl_module-CSDN博客

ngx_openssl_create_conf-CSDN博客


 下一个有 create_conf NGX_CORE_MODULE 模块

ngx_regex_module

ngx_regex_module-CSDN博客


i=4
cycle->modules[4]->name = ngx_regex_module
cycle->modules[4]->type == NGX_CORE_MODULE
module->create_conf = 0x5c9ee0263174 
cycle->conf_ctx[4] = 0x5c9f13b4c838

i=5
cycle->modules[5]->name = ngx_events_module
cycle->modules[5]->type == NGX_CORE_MODULE
module->create_conf = (nil) 

i=6
cycle->modules[6]->name = ngx_event_core_module
cycle->modules[6]->type != NGX_CORE_MODULE 
continue 

i=7
cycle->modules[7]->name = ngx_epoll_module
cycle->modules[7]->type != NGX_CORE_MODULE 
continue 

i=8
cycle->modules[8]->name = ngx_http_module
cycle->modules[8]->type == NGX_CORE_MODULE
module->create_conf = (nil) 

i=9
cycle->modules[9]->name = ngx_http_core_module
cycle->modules[9]->type != NGX_CORE_MODULE 
continue 

i=10
cycle->modules[10]->name = ngx_http_log_module
cycle->modules[10]->type != NGX_CORE_MODULE 
continue 

i=11
cycle->modules[11]->name = ngx_http_upstream_module
cycle->modules[11]->type != NGX_CORE_MODULE 
continue 

i=12
cycle->modules[12]->name = ngx_http_v2_module
cycle->modules[12]->type != NGX_CORE_MODULE 
continue 

i=13
cycle->modules[13]->name = ngx_http_static_module
cycle->modules[13]->type != NGX_CORE_MODULE 
continue 

i=14
cycle->modules[14]->name = ngx_http_gzip_static_module
cycle->modules[14]->type != NGX_CORE_MODULE 
continue 

i=15
cycle->modules[15]->name = ngx_http_autoindex_module
cycle->modules[15]->type != NGX_CORE_MODULE 
continue 

i=16
cycle->modules[16]->name = ngx_http_index_module
cycle->modules[16]->type != NGX_CORE_MODULE 
continue 

i=17
cycle->modules[17]->name = ngx_http_mirror_module
cycle->modules[17]->type != NGX_CORE_MODULE 
continue 

i=18
cycle->modules[18]->name = ngx_http_try_files_module
cycle->modules[18]->type != NGX_CORE_MODULE 
continue 

i=19
cycle->modules[19]->name = ngx_http_auth_basic_module
cycle->modules[19]->type != NGX_CORE_MODULE 
continue 

i=20
cycle->modules[20]->name = ngx_http_access_module
cycle->modules[20]->type != NGX_CORE_MODULE 
continue 

i=21
cycle->modules[21]->name = ngx_http_limit_conn_module
cycle->modules[21]->type != NGX_CORE_MODULE 
continue 

i=22
cycle->modules[22]->name = ngx_http_limit_req_module
cycle->modules[22]->type != NGX_CORE_MODULE 
continue 

i=23
cycle->modules[23]->name = ngx_http_geo_module
cycle->modules[23]->type != NGX_CORE_MODULE 
continue 

i=24
cycle->modules[24]->name = ngx_http_map_module
cycle->modules[24]->type != NGX_CORE_MODULE 
continue 

i=25
cycle->modules[25]->name = ngx_http_split_clients_module
cycle->modules[25]->type != NGX_CORE_MODULE 
continue 

i=26
cycle->modules[26]->name = ngx_http_referer_module
cycle->modules[26]->type != NGX_CORE_MODULE 
continue 

i=27
cycle->modules[27]->name = ngx_http_rewrite_module
cycle->modules[27]->type != NGX_CORE_MODULE 
continue 

i=28
cycle->modules[28]->name = ngx_http_ssl_module
cycle->modules[28]->type != NGX_CORE_MODULE 
continue 

i=29
cycle->modules[29]->name = ngx_http_proxy_module
cycle->modules[29]->type != NGX_CORE_MODULE 
continue 

i=30
cycle->modules[30]->name = ngx_http_fastcgi_module
cycle->modules[30]->type != NGX_CORE_MODULE 
continue 

i=31
cycle->modules[31]->name = ngx_http_uwsgi_module
cycle->modules[31]->type != NGX_CORE_MODULE 
continue 

i=32
cycle->modules[32]->name = ngx_http_scgi_module
cycle->modules[32]->type != NGX_CORE_MODULE 
continue 

i=33
cycle->modules[33]->name = ngx_http_grpc_module
cycle->modules[33]->type != NGX_CORE_MODULE 
continue 

i=34
cycle->modules[34]->name = ngx_http_memcached_module
cycle->modules[34]->type != NGX_CORE_MODULE 
continue 

i=35
cycle->modules[35]->name = ngx_http_empty_gif_module
cycle->modules[35]->type != NGX_CORE_MODULE 
continue 

i=36
cycle->modules[36]->name = ngx_http_browser_module
cycle->modules[36]->type != NGX_CORE_MODULE 
continue 

i=37
cycle->modules[37]->name = ngx_http_upstream_hash_module
cycle->modules[37]->type != NGX_CORE_MODULE 
continue 

i=38
cycle->modules[38]->name = ngx_http_upstream_ip_hash_module
cycle->modules[38]->type != NGX_CORE_MODULE 
continue 

i=39
cycle->modules[39]->name = ngx_http_upstream_least_conn_module
cycle->modules[39]->type != NGX_CORE_MODULE 
continue 

i=40
cycle->modules[40]->name = ngx_http_upstream_random_module
cycle->modules[40]->type != NGX_CORE_MODULE 
continue 

i=41
cycle->modules[41]->name = ngx_http_upstream_keepalive_module
cycle->modules[41]->type != NGX_CORE_MODULE 
continue 

i=42
cycle->modules[42]->name = ngx_http_upstream_zone_module
cycle->modules[42]->type != NGX_CORE_MODULE 
continue 

i=43
cycle->modules[43]->name = ngx_http_write_filter_module
cycle->modules[43]->type != NGX_CORE_MODULE 
continue 

i=44
cycle->modules[44]->name = ngx_http_header_filter_module
cycle->modules[44]->type != NGX_CORE_MODULE 
continue 

i=45
cycle->modules[45]->name = ngx_http_chunked_filter_module
cycle->modules[45]->type != NGX_CORE_MODULE 
continue 

i=46
cycle->modules[46]->name = ngx_http_v2_filter_module
cycle->modules[46]->type != NGX_CORE_MODULE 
continue 

i=47
cycle->modules[47]->name = ngx_http_range_header_filter_module
cycle->modules[47]->type != NGX_CORE_MODULE 
continue 

i=48
cycle->modules[48]->name = ngx_http_gzip_filter_module
cycle->modules[48]->type != NGX_CORE_MODULE 
continue 

i=49
cycle->modules[49]->name = ngx_http_postpone_filter_module
cycle->modules[49]->type != NGX_CORE_MODULE 
continue 

i=50
cycle->modules[50]->name = ngx_http_ssi_filter_module
cycle->modules[50]->type != NGX_CORE_MODULE 
continue 

i=51
cycle->modules[51]->name = ngx_http_charset_filter_module
cycle->modules[51]->type != NGX_CORE_MODULE 
continue 

i=52
cycle->modules[52]->name = ngx_http_userid_filter_module
cycle->modules[52]->type != NGX_CORE_MODULE 
continue 

i=53
cycle->modules[53]->name = ngx_http_headers_filter_module
cycle->modules[53]->type != NGX_CORE_MODULE 
continue 

i=54
cycle->modules[54]->name = ngx_http_copy_filter_module
cycle->modules[54]->type != NGX_CORE_MODULE 
continue 

i=55
cycle->modules[55]->name = ngx_http_range_body_filter_module
cycle->modules[55]->type != NGX_CORE_MODULE 
continue 

i=56
cycle->modules[56]->name = ngx_http_not_modified_filter_module
cycle->modules[56]->type != NGX_CORE_MODULE 
continue 

i=57
cycle->modules[57]->name = ngx_stream_module
cycle->modules[57]->type == NGX_CORE_MODULE
module->create_conf = (nil) 

i=58
cycle->modules[58]->name = ngx_stream_core_module
cycle->modules[58]->type != NGX_CORE_MODULE 
continue 

i=59
cycle->modules[59]->name = ngx_stream_log_module
cycle->modules[59]->type != NGX_CORE_MODULE 
continue 

i=60
cycle->modules[60]->name = ngx_stream_proxy_module
cycle->modules[60]->type != NGX_CORE_MODULE 
continue 

i=61
cycle->modules[61]->name = ngx_stream_upstream_module
cycle->modules[61]->type != NGX_CORE_MODULE 
continue 

i=62
cycle->modules[62]->name = ngx_stream_write_filter_module
cycle->modules[62]->type != NGX_CORE_MODULE 
continue 

i=63
cycle->modules[63]->name = ngx_stream_ssl_module
cycle->modules[63]->type != NGX_CORE_MODULE 
continue 

i=64
cycle->modules[64]->name = ngx_stream_limit_conn_module
cycle->modules[64]->type != NGX_CORE_MODULE 
continue 

i=65
cycle->modules[65]->name = ngx_stream_access_module
cycle->modules[65]->type != NGX_CORE_MODULE 
continue 

i=66
cycle->modules[66]->name = ngx_stream_geo_module
cycle->modules[66]->type != NGX_CORE_MODULE 
continue 

i=67
cycle->modules[67]->name = ngx_stream_map_module
cycle->modules[67]->type != NGX_CORE_MODULE 
continue 

i=68
cycle->modules[68]->name = ngx_stream_split_clients_module
cycle->modules[68]->type != NGX_CORE_MODULE 
continue 

i=69
cycle->modules[69]->name = ngx_stream_return_module
cycle->modules[69]->type != NGX_CORE_MODULE 
continue 

i=70
cycle->modules[70]->name = ngx_stream_set_module
cycle->modules[70]->type != NGX_CORE_MODULE 
continue 

i=71
cycle->modules[71]->name = ngx_stream_upstream_hash_module
cycle->modules[71]->type != NGX_CORE_MODULE 
continue 

i=72
cycle->modules[72]->name = ngx_stream_upstream_least_conn_module
cycle->modules[72]->type != NGX_CORE_MODULE 
continue 

i=73
cycle->modules[73]->name = ngx_stream_upstream_random_module
cycle->modules[73]->type != NGX_CORE_MODULE 
continue 

i=74
cycle->modules[74]->name = ngx_stream_upstream_zone_module
cycle->modules[74]->type != NGX_CORE_MODULE 
continue 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/984863.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Dagger 2 系列(五)——进阶之@Scope 和 @Singleton

前言&#xff1a; 在上一篇Dagger 2 系列&#xff08;四&#xff09;——Named 和 Qualifier注解介绍&#xff0c;了Named 和 Qualifier注解&#xff0c;这篇文章&#xff0c;我们将会了解另外俩个注解&#xff1a;Scope 和 Singleton。 在这篇文章中你会了解到&#xff1a; …

STM32初始安装

前言 很多人刚买来STM32就迫不及待地想要用它来写程序&#xff0c;看见STM32开发版和ST-Link上有几个插口就直接连接&#xff0c;结果就像我一样一不小心就导致ST -Link烧坏了&#x1f602; 所以本篇博客将做最基础的但是对于小白来说最重要的教学&#xff0c;STM32的线路连接…

爱普生温补晶振 TG5032CFN高精度稳定时钟的典范

在科技日新月异的当下&#xff0c;众多领域对时钟信号的稳定性与精准度提出了极为严苛的要求。爱普生温补晶振TG5032CFN是一款高稳定性温度补偿晶体振荡器&#xff08;TCXO&#xff09;。该器件通过内置温度补偿电路&#xff0c;有效抑制环境温度变化对频率稳定性的影响&#x…

深入理解C语言链表:数据结构的基石

在C语言的编程宇宙中&#xff0c;链表就像是一座稳固的基石&#xff0c;支撑着众多复杂程序的构建。它以独特的魅力和强大的功能&#xff0c;在解决各类编程难题时发挥着至关重要的作用。今天&#xff0c;就让我们一同深入探索链表的奥秘。 目录 一、链表初相识 二、链表的结…

从头开始开发基于虹软SDK的人脸识别考勤系统(python+RTSP开源)(二)

今天咱们继续昨天的话题&#xff0c;今天的重点是看思路和代码了。废话不多说&#xff0c;直接上干货。 先说一句&#xff0c;为了省事&#xff0c;直接一个文件完成所有功能&#xff0c;可能在代码可读性上差一些&#xff0c;比较眼花缭乱哈哈。整个文件含空行代码共1931行&a…

报表控件stimulsoft操作:使用 Angular 应用程序的报告查看器组件

Stimulsoft Ultimate &#xff08;原Stimulsoft Reports.Ultimate&#xff09;是用于创建报表和仪表板的通用工具集。该产品包括用于WinForms、ASP.NET、.NET Core、JavaScript、WPF、PHP、Java和其他环境的完整工具集。无需比较产品功能&#xff0c;Stimulsoft Ultimate包含了…

【网络编程】WSAAsyncSelect 模型

十、基于I/O模型的网络开发 接着上次的博客继续分享&#xff1a;select模型 10.8 异步选择模型WSAAsyncSelect 10.8.1 基本概念 WSAAsyncSelect模型是Windows socket的一个异步I/O 模型&#xff0c;利用这个模型&#xff0c;应用程序 可在一个套接字上接收以Windows 消息为基…

从0开始的操作系统手搓教程43——实现一个简单的shell

目录 添加 read 系统调用&#xff0c;获取键盘输入 :sys_read putchar和clear 上班&#xff1a;实现一个简单的shell 测试上电 我们下面来实现一个简单的shell 添加 read 系统调用&#xff0c;获取键盘输入 :sys_read /* Read count bytes from the file pointed to by fi…

鸿蒙应用开发—数据持久化之SQLite

文章目录 SQLite简介创建数据库添加数据查询数据更新数据删除数据升级数据库使用事务参考 SQLite简介 SQLite是一个轻量级关系数据库&#xff0c;占用资源很少&#xff0c;只有几百KB的大小&#xff0c;无需服务器支撑&#xff0c;是一个零配置、事务性的SQL数据库引擎。 相对…

应急响应--流量分析

&#xff08;一&#xff09;Cobalt Strike流量特征分析 1.HTTP特征 源码特征&#xff1a; 在流量中&#xff0c;通过http协议的url路径&#xff0c;在checksum8解密算法计算后&#xff0c;32位的后门得到的结果是92&#xff0c;64位的后门得到的结果是93&#xff0c;该特征符…

初始化E9环境,安装Sqlserver数据库

title: 初始化E9环境,安装Sqlserver数据库 date: 2025-03-10 19:27:19 tags: E9SqlServer初始化E9环境,安装Sqlserver数据库 安装E9本地环境安装Sql server 数据库1、检查SQL Server服务是否开启2、检查SQL Server网络网络配置是否开启创建一个ecology数据库点击初始化数据库…

自然语言处理:无监督朴素贝叶斯模型

介绍 大家好&#xff0c;博主又来和大家分享自然语言处理领域的知识了&#xff0c;今天给大家介绍的是无监督朴素贝叶斯模型。 在自然语言处理这个充满挑战又极具魅力的领域&#xff0c;如何从海量的文本数据中挖掘有价值的信息&#xff0c;一直是研究者们不断探索的课题。无…

API调试工具的无解困境:白名单、动态IP与平台设计问题

引言 你是否曾经在开发中遇到过这样的尴尬情形&#xff1a;你打开了平台的API调试工具&#xff0c;准备一番操作&#xff0c;结果却发现根本无法连接到平台&#xff1f;别急&#xff0c;问题出在调试工具本身。今天我们要吐槽的就是那些神奇的开放平台API调试工具&#xff0c;…

VSCode 2025最新前端开发必备插件推荐汇总(提效指南)

&#x1f31f;前言: 如果你是一名前端开发工程师&#xff0c;合适的开发工具能大大提高工作效率。Visual Studio Code (VSCode) 凭借其轻量级、高扩展性的特点&#xff0c;已成为众多前端开发者在win系电脑的首选IDE。 名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。—…

小程序事件系统 —— 33 事件传参 - data-*自定义数据

事件传参&#xff1a;在触发事件时&#xff0c;将一些数据作为参数传递给事件处理函数的过程&#xff0c;就是事件传参&#xff1b; 在微信小程序中&#xff0c;我们经常会在组件上添加一些自定义数据&#xff0c;然后在事件处理函数中获取这些自定义数据&#xff0c;从而完成…

初阶数据结构(C语言实现)——4.2队列

目录 2.队列2.1队列的概念及结构2.2队列的实现2.2.1 初始化队列2.2.2 销毁队列2.2.3 队尾入队列2.2.4 队头出队列2.2.5获取队列头部元素2.2.6 获取队列队尾元素2.2.7获取队列中有效元素个数2.2.8 检测队列是否为空&#xff0c;如果为空返回非零结果&#xff0c;如果非空返回0 3…

linux 命令 cat

cat 是 Linux 中用于查看、创建和合并文件的常用命令&#xff0c;全称 concatenate&#xff08;连接&#xff09;。其核心功能是将文件内容输出到终端或重定向到其他文件/命令中。以下是详细用法及场景示例&#xff1a; 基本语法 cat [选项] [文件1] [文件2] ... 选项…

TON基金会确认冠名赞助2025香港Web3嘉年华,并将于4月8日重磅呈现“TON生态日”

近日&#xff0c;由万向区块链实验室与HashKey Group联合推出的Web3年度盛典——2025香港Web3嘉年华正式宣布&#xff0c;TON基金会确认成为本届嘉年华的冠名赞助商&#xff0c;并将于4月8日在主会场特别举办“TON生态日”专题Side Event&#xff0c;集中展现TON生态的最新技术…

【Java代码审计 | 第七篇】文件上传漏洞成因及防范

未经许可&#xff0c;不得转载。 文章目录 文件上传漏洞漏洞成因未验证文件类型和扩展名未限制文件上传路径 防范验证文件类型和扩展名验证文件内容限制文件上传路径使用安全的文件上传库 标准代码 文件上传漏洞 文件上传漏洞是指攻击者通过上传恶意文件&#xff08;如可执行脚…

【无人机路径规划】基于麻雀搜索算法(SSA)的无人机路径规划(Matlab)

效果一览 代码获取私信博主基于麻雀搜索算法&#xff08;SSA&#xff09;的无人机路径规划&#xff08;Matlab&#xff09; 一、算法背景与核心思想 麻雀搜索算法&#xff08;Sparrow Search Algorithm, SSA&#xff09;是一种受麻雀群体觅食行为启发的元启发式算法&#xff0…