Upgrade to Pro — share decks privately, control downloads, hide ads and more …

nginxの初期化について

karky7
November 28, 2015

 nginxの初期化について

karky7

November 28, 2015
Tweet

Other Decks in Technology

Transcript

  1. nginxの初期化 @karky7 2015/11/28

  2. 自己紹介 氏名:デニーロ・田畑 三島にある、Handsという会社で、後輩のパシリをやってます

  3. 自己紹介 twitter: @karky7 contribute gentoo-haskellコミッタ 日本OpenSolarisユーザーグループ会 パッケージメンテナ gentoo好き 静岡ベシャベシャ協会 伊東支部(会計)

    ハッシュタグ #ベシャベシャ
  4. 初期化フェーズについて調べてみた

  5. 初めに注意事項

  6. ちなみにそんなに知ってるわけじゃないので

  7. 間違ってたら、許してね

  8. 細かい、ツッコミなしでお願いします

  9. 細かい、ツッコミしたら...

  10. None
  11. 原液

  12. イッキさせます、キリッ!

  13. nginxの特徴 apacheとの違いとかは、世の素晴らしい先生の方々のドキュメントを 参照お願いします、はしょります

  14. 私はコードを追っかけてみました

  15. main関数その1 1. ngx_strerror_init() 2. ngx_get_options() 3. ngx_time_init() 4. ngx_regex_init() 5.

    ngx_log_init()
  16. main関数その2 6. ngx_ssl_init() 7. ngx_save_argv() 8. ngx_process_options() 9. ngx_os_init() 10.

    ngx_crc32_table_init() 11. ngx_add_inherited_sockets()
  17. main関数その3 12. モジュール数のカウント 13. ngx_init_cycle() ・・・これでかい 14. ngx_os_status() 15. ngx_init_signals()

    16. ngx_daemon() ・・・ デーモン化 ※ページを稼いでいる分けではありませ
  18. main関数その4 17. ngx_master_process_cycle() 18. ngx_start_worker_processes() 19. ngx_spawn_process() ・・・ worker_processes分さらにfork() 19.

    ngx_worker_process_cycle() ・・・ event loopへ突入
  19. みるの、やだ、なえるwww

  20. ngx_strerror_init() 135個あるエラーコードをエラー文字列へ変換しngx_sys_errlist配列 へする 変換はstrerror()を利用してerrnoを文字列化

  21. ngx_get_options() コマンドラインのオプション解析

  22. ngx_time_init() 時間関連の初期化、ログの出力フォーマットを作成

  23. ngx_regex_init() PCRE系の初期化、pcre用のメモリ確保関数、メモリ解放関数へのポイ ンタを初期化 PCRE Perl Compatible Regular Expressions perl互換正規表現互換ライブラリ

  24. ngx_log_init() error_logをログレベルNGX_LOG_NOTICEでオープン --error-log-path=で指定した場合、NGX_ERROR_LOG_PATHがdefine される それ以外はprefixからの相対パスでnginx.confで指定可能

  25. ngx_ssl_init() SSLライブラリ関連の初期化処理

  26. ngx_save_argv() コマンドライン引数の情報を一時cycle変数へコピー、環境変数のポイ ンタ(environ)を取得 environ ・・・ ローダのldに設定されているプロセスの環境変数 ... 00007ffff7ffd000 4K rw---

    ld-2.20.so ...
  27. ngx_process_options() init_cycleのprefix情報、ログ関連の情報を初期化

  28. ngx_os_init() CPU、pagesizeに関する情報収集 利用可能なCPU数の取得(cpuinfo) pagesizeの取得 CPUのキャッシュラインのサイズを取得 open可能なファイルディスクリプタの数を取得

  29. 利用可能なCPU数の取得 ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN);

  30. pagesizeの取得 ngx_pagesize = getpagesize(); / * s y s c

    o n f ( _ S C _ P A G E S I Z E ) * /
  31. CPU Cache Line とりあえず暫定的に決め打ちしておいて、後でcpuinfoでしっかり設定 ngx_cacheline_size = NGX_CPU_CACHE_LINE; ... void ngx_cpuinfo(void)

    { ... ... case 6: ngx_cacheline_size = 32; model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0); if (model >= 0xd0) { / * I n t e l C o r e , C o r e 2 , A t o m * / ngx_cacheline_size = 64; } break; ...
  32. CPU Cache Line Pentium /Pro/II/III ... 32 Intel Core, Core

    2, Atom ... 64 AMD ... 64 その他 ... 128 となっております
  33. open可能fd数 プロセスがオープンできる最大のfd数 getrlimit(RLIMIT_NOFILE, &rlmt) ngx_max_sockets = (ngx_int_t) rlmt.rlim_cur; karky7 ~

    # ulimit -a ... open files (-n) 1024 ここで設定されるのは初期値で、のちにnginx.confファイルの worker_rlimit_nofileで指定可能
  34. ngx_crc32_table_init() 巡回冗長検査のテーブル設定 16の要素がキャッシュラインに収まるかどうかの検査(だと思うのですが) if (((uintptr_t) ngx_crc32_table_short & ~((uintptr_t) ngx_cacheline_size -

    1)) == (uintptr_t) ngx_crc32_table_short) { return NGX_OK; } p = ngx_alloc(16 * sizeof(uint32_t) + ngx_cacheline_size, ngx_cycle->log);
  35. ngx_add_inherited_sockets() NGINX_VARに設定された環境変数のソケット番号について追加オプシ ョンを設定 ※ 例えばSO_SNDBUFな

  36. moduleへのindexを設定 moduleの管理構造体へ(*ngx_modules[])indexを設定

  37. ngx_module_t *ngx_modules[]とは モジュールを管理するオブジェクトをまとめた構造体、モジュールを追 っかけるにはこの構造体からみるといいね! objs/ngx_modiles.c ngx_module_t *ngx_modules[] = { &ngx_core_module,

    &ngx_errlog_module, ... ... &ngx_http_copy_filter_module, &ngx_http_range_body_filter_module, &ngx_http_not_modified_filter_module, NULL }; objsディレクトリはconfigure時に生成されます
  38. ngx_init_cycle() 主要なデータオブジェクトcycleの初期化、ページ単位で色々なデータ 構造を詰めながら初期化を実行していく 4KB単位で領域をアロケートしていく 4KBのなかに色々な型の情報を詰めて確保していく Listenソケットの作成 モジュールのcontext設定関数の呼び出し

  39. ngx_create_pool() 4KBを確保し、その領域の先頭に領域のメタ情報を格納したインスタン スを返してくる

  40. allocate関数 posix_memalign() Linux版 memalign() Solaris版 ⁽˙³˙⁾◟( ˘•ω•˘ )◞⁽˙³˙⁾ Mac, Win

    ???
  41. メモリ管理 sysconf(_SC_PAGESIZE)でアライメントされた領域のアドレスを返し てくる nginxが確保したメモリ領域は、OSのページング機構に最適化されて いる 領域中に確保される変数オブジェクトはページを跨いで確保される事 はない(と思うよ)

  42. 初期状態でこうなってます

  43. ngx_pcalloc() cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t)); 4KBの領域にsizeof(ngx_cycle_t)分の領域を確保しそのポインタを返し てくる

  44. 領域内に確保されるインスタンスの開始アドレスは16の倍数にアライメントされています

  45. module context呼び出し 設定領域の確保、基本的にはこんな感じで利用されているが、設定領域 へのポインタ配列として利用しているケースもあるよ

  46. module context ngx_module_t経由でngx_core_module_create_confが呼ばれます static ngx_core_module_t ngx_core_module_ctx = { ngx_string("core"), ngx_core_module_create_conf,

    / * v o i d * ( * c r e a t e _ c o n f ) ( n g x _ c y c l e _ t * c y c l e ) ; * / ngx_core_module_init_conf / * c h a r * ( * i n i t _ c o n f ) ( n g x _ c y c l e _ t * c y c l e , v o i d * c o n f ) ; * / }; ngx_module_t ngx_core_module = { NGX_MODULE_V1, &ngx_core_module_ctx, / * m o d u l e c o n t e x t * / ngx_core_commands, / * m o d u l e d i r e c t i v e s * / NGX_CORE_MODULE, / * m o d u l e t y p e * / NULL, / * i n i t m a s t e r * / NULL, / * i n i t m o d u l e * / NULL, / * i n i t p r o c e s s * / NULL, / * i n i t t h r e a d * / NULL, / * e x i t t h r e a d * / NULL, / * e x i t p r o c e s s * / NULL, / * e x i t m a s t e r * / NGX_MODULE_V1_PADDING };
  47. nginx.confの読込と初期化

  48. ngx_conf_parse() 実際のnginx.confのparseを実行 #define NGX_CONF_BUFFER 4096 .. for ( ;; )

    { rc = ngx_conf_read_token(cf); ... defaultでnginx.confファイルのサイズは4096バイトに制限される でかいファイルを読みたい場合は、NGX_CONF_BUFFERをでかくし てコンパイル confファイルにluaコードとか書きすぎると叱られる
  49. ngx_read_file() threadが利用可能な処理系の場合pread()で読込 pread()とはファイルオフセットを変化させないread() 複数スレッドで同じfd(nginx.conf)へアクセスできる したがってファイルオフセットはスレッド固有に管理

  50. parseされた値 ngx_str_t型の10個の領域を使って値を変換していく、10も使わないけど

  51. 引数を内部数値へ変換 static ngx_command_t ngx_core_commands[] = { { ngx_string("daemon"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, ngx_conf_set_flag_slot,

    / * パラメータ化する関数 * / 0, offsetof(ngx_core_conf_t, daemon), NULL }, ... { ngx_string("worker_processes"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, ngx_set_worker_processes, / * パラメータ化する関数 * / 0, 0, NULL }, ... ...
  52. 関連はこんな感じ

  53. 要約すると ngx_conf_read_token() ファイルからトークンを抽出 ngx_conf_handler() トークンを引当しcmdの設定ハンドラを呼び出す

  54. ログファイルなどのopen accecc_log、error_logのopen if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) { ngx_log_error(NGX_LOG_EMERG,

    log, ngx_errno, "fcntl(FD_CLOEXEC) \"%s\" failed", file[i].name.data); goto failed; } FD_CLOEXECでexecve()された場合でも適切にfdをcloseするように 設定
  55. Listen socketを作成 IP情報はcycle->listeningの配列で管理 複数指定可能 server { listen 192.168.11.3:8000; server_name localhost;

    location / { ... } } server { listen 192.168.11.3:8989; ... }
  56. Listen socketをnonblocking化 int nb = 1; retrun ioctl(s, FIONBIO, &nb);

    ソケットをnonblockingへ設定 fcntl ・・・ F_SETFL,O_NONBLOCK ioctl ・・・ FIONBIO Posix.1g ・・・ fcntlで設定を推奨ということらしい
  57. Socketオプション TCP_DEFFER_ACCEPT データがソケットに到着したときに起きてくるオプション、 nonblocking socketと絡めた場合動作がちょっと不明... SO_ACCEPTFILTER FreeBSD、NetBSB 5.0以降で利用できるソケットオプションらし い、acceptする前に何やらfilterできるそうです

  58. NGX_CORE_MODULEの初期化 static ngx_core_module_t ngx_core_module_ctx = { ngx_string("core"), ngx_core_module_create_conf, / *

    v o i d * ( * c r e a t e _ c o n f ) ( n g x _ c y c l e _ t * c y c l e ) ; * / ngx_core_module_init_conf / * こちらです * / }; 最終初期化処理の実行
  59. ngx_configure_listening_sockets() ソケットの追加オプションの設定 soket option SO_RCVBUF, SO_SNDBUF, SO_KEEPALIVE, SO_SETFIB, SO_ACCEPTFILTER TCP

    option TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_FASTOPEN, TCP_DEFER_ACCEPT バックログの設定
  60. module_init系の呼出 全てのモジュールのinit_module系を呼び出す(定義されていればです が) for (i = 0; ngx_modules[i]; i++) {

    if (ngx_modules[i]->init_module) { if (ngx_modules[i]->init_module(cycle) != NGX_OK) { / * f a t a l * / exit(1); } } } ngx_event_module_init ngx_regex_module_init ngx_http_spdy_module_init
  61. ngx_init_signals() ... 1 シグナル情報をまとめたテーブルを利用してシグナルハンドラを登録 ngx_signal_t signals[] = { { ngx_signal_value(NGX_RECONFIGURE_SIGNAL),/

    * S I G H U P * / "SIG" ngx_value(NGX_RECONFIGURE_SIGNAL), / * " S I G H U P " * / "reload", ngx_signal_handler }, / * h a n d l e r * /
  62. ngx_init_signals() ... 2 シグナルハンドラをngx_signal_handler()へセット SIGHUP ... NGX_RECONFIGURE_SIGNAL SIGTERM ... NGX_TERMINATE_SIGNAL

    SIGQUIT ... NGX_SHUTDOWN_SIGNAL SIGWINCH ... NGX_NOACCEPT_SIGNAL SIGUSR1 ... NGX_REOPEN_SIGNAL SIGUSR2 ... NGX_CHANGEBIN_SIGNAL SIGALRM SIGINT SIGIO SIGCHLD SIGSYS SIGPIPE
  63. ngx_signal_handler() ... 1 ngx_processの値が以下の場合 NGX_PROCESS_MASTER NGX_PROCESS_SINGLE NGX_SHUTDOWN_SIGNAL ... ngx_quit =

    1(shutdown) NGX_TERMINATE_SIGNAL ... ngx_terminate = 1 (exiting) SIGINT ... ngx_terminate = 1 (exiting) NGX_NOACCEPT_SIGNAL ... ngx_noaccept = 1 (stop accepting connections) NGX_RECONFIGURE_SIGNAL ... ngx_reconfigure = 1 (reconfiguring) NGX_REOPEN_SIGNAL ... ngx_reopen = 1 (reopeninig log) NGX_CHANGEBIN_SIGNAL ... ignore = 1 (ignore) SIGALRM ... ngx_sigalrm = 1 SIGIO ... ngx_sigio = 1 SIGCHLD ... ngx_reap = 1
  64. ngx_signal_handler() ... 2 ngx_processの値が以下の場合 NGX_PROCESS_WORKER NGX_PROCESS_HELPER NGX_NOACCEPT_SIGNAL ... ngx_debug_quit =

    1(ngx_daemonized == 0) NGX_SHUTDOWN_SIGNAL ... ngx_quit = 1 (shutting down) NGX_TERMINATE_SIGNAL ... ngx_terminate = 1 (exiting) NGX_REOPEN_SIGNAL ... ngx_reopen = 1 (reopening logs) NGX_RECONFIGURE_SIGNAL ... (ignoring) NGX_CHANGEBIN_SIGNAL ... (ignoring) SIGIO ... (ignoring)
  65. ngx_process_get_status() ... 1 SIGCHLDは子プロセスの終了ステータスを取得してクリーンアップ for ( ;; ) { pid

    = waitpid(-1, &status, WNOHANG); ... / * p i d から終了プロセスをe x i t e d へ設定 * / for (i = 0; i < ngx_last_process; i++) { if (ngx_processes[i].pid == pid) { ngx_processes[i].status = status; ngx_processes[i].exited = 1; process = ngx_processes[i].name; break; } } ...
  66. ngx_process_get_status() ... 2 子プロセスの終了ステータスによってログを書込 WIFEXITED(status) 子プロセスが通常終了(exit())した場合にTrueを返す WEXITSTATUS(status) 子プロセスの終了ステータスを返す、WIFEXITEDがTrueの場合だ け呼ぶこと WTERMSIG(status)

    子プロセスの終了の原因となったシグナル番号を返す、 WIFSIGNALEDがTrueの場合だけ呼ぶこと if (WEXITSTATUS(status) == 2 && ngx_processes[i].respawn) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "%s %P exited with fatal code %d " "and cannot be respawned", process, pid, WEXITSTATUS(status)); ngx_processes[i].respawn = 0; } ngx_unlock_mutexes(pid); ...
  67. ngx_daemon() 「daemon = on」でdaemon化する、このプロセスが NGX_MASTER_PROCESSと設定される 親プロセス 速攻exit() 子プロセス ngx_pidへプロセスIDを格納 dup2()でSTDIN,STDOU,STDERRを/dev/nullへ複製

    ngx_daemonized = 1 ngx_create_pidfile() NGX_MASTER_PROCESSのpid(ngx_pid)をnginx.pidファイルへ 書き出し
  68. ngx_master_process_cycle() ... 1 「master_process on」でmaster_processを作成

  69. ngx_master_process_cycle() ... 2 その後呼ぶforループ中でシグナルを受信したくないため、無視するシ グナルを設定する。 forループ中では子プロセスを調整するための処理 を実行中のためシグナルを受信してしまうと、まずい事になる。 sigemptyset(&set); sigaddset(&set, SIGCHLD);

    sigaddset(&set, SIGALRM); sigaddset(&set, SIGIO); sigaddset(&set, SIGINT); sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL)); if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, "sigprocmask() failed"); } ...
  70. ngx_master_process_cycle() ... 3 ngx_start_worker_processes()呼出 子プロセスとしてworker_processが生成 for ( ;; ) {

    ... sigsuspend(&set); ... worker_processを生成した親はループに突入しsigsuspend()でsleep
  71. sigsuspend() 無視したシグナルを一時的に退避して寝る 無視しているシグナルが受信可能状態になる シグナルハンドラを実行して起きてくる 起きた後は前回仕込んだシグナルマスクが有効になっている シグナルハンドラを実行した後は、グローバル変数などが更新されてい るので、そのフラグに応じて生成した子プロセスを処理する ... if (ngx_quit)

    { ngx_signal_worker_processes(cycle, /* killの発行 */ ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); ...
  72. ngx_start_worker_processes() 「worker_processes」数のworker_processをさらにfork()する type = NGX_PROCESS_RESPAWNでngx_spawn_process()の呼出 / * n = w

    o r k e r _ p r o c e s s e s * / for (i = 0; i < n; i++) { ngx_spawn_process(cycle, ngx_worker_process_cycle, (void *) (intptr_t) i, "worker process", type); / * f o r k ( ) した子プロセスの情報を保存 * / ch.pid = ngx_processes[ngx_process_slot].pid; ch.slot = ngx_process_slot; ch.fd = ngx_processes[ngx_process_slot].channel[0]; ngx_pass_open_channel(cycle, &ch); }
  73. ngx_spawn_process() 子プロセス通信するためのStream UNIX Domain Socketを作成 if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel)

    == -1) { ... ngx_processes[s].channel[0,1]をnonblockingへ設定 ngx_processes[s].channel[0]をシグナル駆動IOへ設定 ngx_processes[s].channel[0]をF_SETOWN SIGIOを受け取るソケットのプロセスを ngx_pid(NGX_MASTER_PROCESS)に設定 ngx_processes[s].channel[0,1]をFD_CLOEXEC execされても自動closeするようsocketを設定
  74. ngx_worker_process_cycle() ngx_worker_process_init() 初期化処理 「worker process」へプロセス名を設定 ngx_process_events() 実際のevent loopへ突入

  75. ngx_worker_process_init() ngx_process = NGX_PROCESS_WORKERに設定 worker_rlimit_nofileの設定 プロセスの優先度を設定 moduleのinit_module呼出

  76. ngx_process_events() event loopのepoolでクライアントのアクセスがまるまでsleep events = epoll_wait(ep, event_list, (int) nevents, timer);

    backtraceスはこんな感じ #0 ngx_epoll_process_events (cycle=0x7457f0, timer=18446744073709551615, flags=1) at src/event/ #1 0x00000000004326b3 in ngx_process_events_and_timers (cycle=0x7457f0) at src/event/ngx_event. #2 0x000000000044007d in ngx_worker_process_cycle (cycle=0x7457f0, data=0x0) at src/os/unix/ngx #3 0x000000000043c6db in ngx_spawn_process (cycle=0x7457f0, proc=0x43fe5c <ngx_worker_process_c #4 0x000000000043ed3f in ngx_start_worker_processes (cycle=0x7457f0, n=1, type=-3) at src/os/un #5 0x000000000043e34d in ngx_master_process_cycle (cycle=0x7457f0) at src/os/unix/ngx_process_c #6 0x0000000000407e5d in main (argc=1, argv=0x7fffffffd868) at src/core/nginx.c:431
  77. こうなる

  78. epollってなに I/O multiplexing(I/Oの多重化)のうちの1つ select() ... fdセットからの検索が必要 poll() ... 高速なselectのようなもの、移植性にかける模様 Linuxのみ(Solarisは/dev/pollデバイスで行なう)

    fdの管理をkernel内で管理 fdの数は無制限 fdの検索がO(1)になっているためユーザーランドの処理はselectより 高速
  79. epollのサーバーサイドのそれ 1 1. epollオブジェクトの作成 epfd = epoll_create(MAX_EVENTS) 2. Listenソケットをイベントへ登録 struct

    epoll_event ev; / * L i s t e n s o k e t 設定用* / struct epoll_event events[MAX_EVENTS]; / * e v e n t 発生取得用 * / sock = socket(PF_INET, SOCK_STREAM, 0) bind(sock, (struct sockaddr *) &sin, sizeof sin); listen(sock, BACKLOG); ev.events = EPOLLIN; ev.data.fd = sock; epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev); 3. wait int nfd = epoll_wait(epfd, events, MAX_EVENTS, -1);
  80. epollのサーバーサイドのそれ 2 4. イベントループ開始 for (i = 0; i <

    nfd; i++) { / * L i s t e n S o c k e t が起きた * / if (events[i].data.fd == sock) { / * s o c k はL i s t e n s o c k e t * / / * クライアントのs o k e t ファイルディスクリプタの取得 * / int client = accept(socket, (struct sockaddr *) &client_addr, &client_addr_len); / * クライアントのs o k e t をn o n b l o c k i n g へ * / int flag = fcntl(client, F_GETFL, 0); fcntl(client, F_SETFL, flag | O_NONBLOCK); / * k e r n e l へ読込可能、エッジトリガ形式で登録依頼 * / ev.events = EPOLLIN | EPOLLET; ev.data.fd = client; / * 登録 * / epoll_ctl(epfd, EPOLL_CTL_ADD, client, &ev); } else { / * 読込が可能なf d が既に入ってる * / int client = events[i].data.fd; int n = read(client, buffer, sizeof(buffer)); write(client, buffer, n); } } というような感じで動きます...コードはイメージです アハ
  81. 最後におまけ 「もうクドいよ」って吐き捨てないで..

  82. nginxをデバックモードでトレースしてみる configure # ! / b i n / b

    a s h uname -r | grep gentoo GENTOO=$? if [ $GENTOO -eq 0 ] ; then echo '' echo 'Check system is `Gentoo`' echo '' ADDOPT="--with-cc-opt=-I/usr/include --with-ld-opt=-L/usr/lib64" else ADDOPT=" " fi CFLAGS="-g -O0" ./configure --prefix=$HOME/devbin/nginx \ --conf-path=$HOME/devbin/nginx/conf/nginx.conf \ --error-log-path=$HOME/devbin/nginx/var/log/error_log \ --pid-path=$HOME/devbin/nginx/var/run/nginx.pid \ --lock-path=$HOME/devbin/nginx/var/run/lock/nginx.lock \ --http-log-path=$HOME/devbin/nginx/var/log/nginx/access_log \ --http-client-body-temp-path=$HOME/devbin/nginx/var/lib/nginx/tmp/client \ --http-proxy-temp-path=$HOME/devbin/nginx/var/lib/nginx/tmp/proxy \ --http-fastcgi-temp-path=$HOME/devbin/nginx/var/lib/nginx/tmp/fastcgi \
  83. ビルド build # ! / b i n / b

    a s h TMP=$HOME/devbin/nginx/var/lib/nginx/tmp/ LOG=$HOME/devbin/nginx/logs/ make -j6 make install if [ -d $TMP ]; then echo "[ $TMP ] found" else echo "Create directory [ $TMP ]" mkdir -p $TMP fi if [ -d $LOG ]; then echo "[ $LOG ] found" else echo "Create directory [ $LOG ]" mkdir -p $LOG fi
  84. fork()に備えたgdbの設定 ~/.gdbinit set history save on set history size 10000

    set history filename ~/.gdb_history set print pretty on set print static-members off set charset UTF-8 set follow-fork-mode child set detach-on-fork off dir /home/cuomo/Code/nginx/ngx-1.8.0/src dir /home/cuomo/Code/nginx/ngx-1.8.0/src/event dir /home/cuomo/Code/nginx/ngx-1.8.0/src/event/modules ... set follow-fork-mode child fork()したら子プロセスに自動attach set detach-on-fork off fork()後親、子プロセスともに捕まえる
  85. ちょっとやってみる emacsから「M-x gdb」 emacs> gdb -i=mi ~/devbin/nginx/sbin/nginx Type "apropos word"

    to search for commands related to "word"... Reading symbols from /home/cuomo/devbin/nginx/sbin/nginx...done. (gdb) b main Breakpoint 1 at 0x40791f: file src/core/nginx.c, line 203. (gdb) r Starting program: /home/cuomo/devbin/nginx/sbin/nginx [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Breakpoint 1, main (argc=1, argv=0x7fffffffd818) at src/core/nginx.c:203 203 { (gdb) できたか?!
  86. 今後は... 今後は、キャバクラに連れて逝ってもラッテから、イベント、モジュー ルの動きとか追っかけたいと思います

  87. ご清聴有難うございました