Kentaro Kuribayashi's blog

Software Engineering, Management, Books, and Daily Journal.

Reading nginx's Code with GNU gdb in Mac OSX Lion

We started reading nginx's code being lead by id:suzak...

Premises

  • Mac OSX Lion
  • GNU gdb 6.3.50-20050815 (Apple version gdb-1708)
  • nginx-1.1.16
  • We're going to find out what ngx_single_process_cycle() in os/unix/ngx_process_cycle.c:295, called from core/nginx.c:200 main(), does.
$ gdb -v
GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Thu Nov  3 21:59:02 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin".

GNU GLOBAL

Install GNU GLOBAL by homebrew, and generate tags and annotated source code as HTML files using it.

$ cd nginx-1.1.16
$ brew install global
$ gtags -v
$ htags -saF
  • Generates tags by gtags
  • Generates annotated source code as HTML files (not required, but can be convenient)

Setup Git Repository

Initializing nginx source code directory as Git repository can be useful when we add some modification into the code directly; we can track the changes by git command.

$ git init
$ cat .gitignore
GPATH
GRTAGS
GTAGS
Makefile
html/
objs/
build/
$ git add .
$ git ci

Build the Code for reading

$ ./configure --without-http_rewrite_module --with-debug --prefix=build
$ make
$ make install
  • Since I got build error caused by PCRE, I omitted http_rewrite_module with the option --without-http_rewrite_module. Anyway, we won't look into modules' details.
  • Enables debugging --with-debug.
  • Install nginx into ./build directory.

Configuration for Reading

Edit build/conf/nginx.conf a bit.

Since we're going to read what ngx_single_process_cycle does, disable master process at first. Add the line into the conf file.

master_process off;

Additionally, in order to avoid a problem (described later) which fork(2) raises in Mac OSX environment, add one more line below.

daemon off;

Change the port to which nginx listens for convenience.

server {
    listen       8080;
    server_name  localhost;

    ...
}

Run nginx via gdb

$ gdb build/sbin/nginx

Mac + gdb with a Program which Executes fork(2)

The gdb manual says:

On most systems, gdb has no special support for debugging programs which create additional processes using the fork function. When a program forks, gdb will continue to debug the parent process and the child process will run unimpeded.

To follow child process forked by its parent, you need to do as below:

(gdb) set follow-fork-mode child

But, it is likely supported only in HP-UX or Linux according to the manual:

On some systems, gdb provides support for debugging programs that create additional processes using the fork or vfork functions. Currently, the only platforms with this feature are HP-UX (11.x and later only?) and gnu/Linux (kernel version 2.5.60 and later).

We can just disable nginx's daemonization, because we want the simplest process of actual running code. Just do it:

daemon off;

Then, you can get enabled to follow the code without forking.