nginx源码学习

Posted 香农随笔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx源码学习相关的知识,希望对你有一定的参考价值。

这篇文章我们继续学习main方法,我们先来看看 ngx_debug_init() 这个方法。技术分享从方法名我们也知道,debug初始化。我们先看看方法位置在哪。我们来断点在这个方法上面。 技术分享 Function “ngx_debug_init” not defined。 我们去源码里面查找,grep “ngx_debug_init” -r *。 技术分享 通过搜索结果大家应该知道,这个函数主要用于跨操作系统的东西。在Linux系统中应该是src/os/unix/ngx_linux_config.h:#define ngx_debug_init()。 仅仅是一个宏定义,内容为空。大家可以去src/os/unix/ngx_linux_config.h中看看。也就是说对于linux平台,这个函数没有意义。所以gdb中运行nginx,直接就跳到了ngx_strerror_init() 方法。 那我们就来看看ngx_strerror_init() 方法的作用。我们还是从启动nginx开始,gdb nginx,b main,r,然后输入 s 命令。 技术分享 ok,ngx_strerror_init () at src/os/unix/ngx_errno.c:58。去58行看看。技术分享 这就是ngx_strerror_init 方法体了。前面的变量我们就不看了,直接看len = NGX_SYS_NERR * sizeof(ngx_str_t); 技术分享 ngx_str_t长度为8,我的是32位系统。如果是64位系统长度就是16了。那么NGX_SYS_NERR是多少呢?技术分享 objs/ngx_auto_config.h:#define NGX_SYS_NERR  132。 也就是NGX_SYS_NERR=132。是一个宏定义,132。 那么len = NGX_SYS_NERR * sizeof(ngx_str_t);len就是132*8=1056了。 接着看!这行计算,根本没在 CPU 上计算,而是在编译的时候已经算完了。ngx_sys_errlist = malloc(len);是申请一块堆上的内存。类似于Java中的new。在gdb中输入命令 n ,next意思,我们看看下一行代码。 技术分享 我们看看len的长度是多少?输入 p len。 技术分享 没错,1056。再看看ngx_sys_errlist。static ngx_str_t  *ngx_sys_errlist;一个结构指针。输入p ngx_sys_errlist。 技术分享 (ngx_str_t *) 0x0说明什么呢?也就是在没有运行ngx_sys_errlist = malloc(len);之前,堆栈上面它的地址字节都为0。解释下0x0地址。操作系统和CPU,一起做了一个设定,地址是 0x0的那个地址,在应用程序的进程地址空间,是不可访问的。主要是为了程序员写指针初始化的时候用的。如果你要是现在用代码操作这个地址,0x0,就会引发常规的非法地址访问。操作系统就把你的进程直接杀掉了。 我们继续next。 技术分享 再打印ngx_sys_errlist看看。 技术分享 已经分配了地址。接下来 if (ngx_sys_errlist == NULL) {         goto failed; } 如分配失败,为NULL,则去到failed。大家自己看。 再接下来就是一个循环了。 for (err = 0; err < NGX_SYS_NERR; err++) {         msg = strerror(err);         len = ngx_strlen(msg);

    p = malloc(len);
    if (p == NULL) {
        goto failed;
    }

    ngx_memcpy(p, msg, len);
    ngx_sys_errlist[err].len = len;
    ngx_sys_errlist[err].data = p;

} 先看看msg = strerror(err);这个方法。一看就不是nginx自己的方法,应该是底层 C 的方法。在linux控制台输入man strerror 打印看看。 技术分享 于是我们就知道 strerror() 函数返回一个指针,指向一个“字符串”,就是一个地址,里面有一些字符,以0x0结尾。继续next。 技术分享 当err=0的时候,错误信息为Success。 继续next 技术分享 当err=1的时候,msg为Operation not permitted。大家可以自己试试,看看不同的err都是什么错误信息。 大家有没有发现,msg信息最前面为什么会有奇怪的地址呢? $15 = 0x235e94 “Success”。其实这是个动态链接库,有兴趣的同学可以查一下动态链接库的地址空间。 接下来继续 ngx_memcpy(p, msg, len);然后做一个字符串复制。 ngx_sys_errlist[err].len = len; ngx_sys_errlist[err].data = p; 这个大家一看就知道,向ngx_sys_errlist中赋值。 到这里,我们可以看出来了,ngx_sys_errlist 就是一个结构数组。一共是132个。用来存放所有的系统基本错误信息。 好,下节课我们讲 ngx_get_options()。

以上是关于nginx源码学习的主要内容,如果未能解决你的问题,请参考以下文章

nginx源码学习

C语言100个经典算法源码片段

Linux源码安装nginx并配置

nginx源码学习

Nginx——Nginx启动报错Job for nginx.service failed because the control process exited with error code(代码片段

[学习笔记]在Linux中使用源码编译的方式安装Nginx