Last active
November 4, 2016 04:09
-
-
Save dylanninin/bfc9cfce80a4d8737952440b25d61298 to your computer and use it in GitHub Desktop.
ngx-phase-handlers.stp with comments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Dumped by ngx-phase-handlers of openresty-systemtap-tools | |
- Ubuntu 16.04 | |
- 2016-11-03 | |
*/ | |
/* probe begin event */ | |
probe begin { | |
/* target() return pid specifed as "stap -x pid ngx-phase-handlers.stp" */ | |
printf("Tracing %d (/usr/local/openresty/nginx/sbin/nginx)...\n", target()) | |
} | |
/* print phase */ | |
function print_phase(cmcf, phase_num) { | |
n = @cast(cmcf, "ngx_http_core_main_conf_t", "/usr/local/openresty/nginx/sbin/nginx")->phases[phase_num]->handlers->nelts | |
handler_addr = @cast(cmcf, "ngx_http_core_main_conf_t", "/usr/local/openresty/nginx/sbin/nginx")->phases[phase_num]->handlers->elts | |
handler = @cast(handler_addr, "ngx_http_handler_pt", "/usr/local/openresty/nginx/sbin/nginx") | |
for ( i = 0; i < n; i++ ) { | |
/* string:usymname(address) returns the symbol name of the specified address */ | |
printf(" %s\n", usymname(handler)) | |
/* next handler address by offset */ | |
handler_addr += &@cast(0, "ngx_int_t", "/usr/local/openresty/nginx/sbin/nginx")[1] | |
handler = @cast(handler_addr, "ngx_http_handler_pt", "/usr/local/openresty/nginx/sbin/nginx") | |
} | |
} | |
/* | |
User space event probes prefixed with process | |
- process("PATH").function("function") | |
- nm show symbols in a executable binary file | |
- readelf ELF(Executable and Linkable File format) | |
Nginx request phases | |
- 0 post-read | |
- 1 server-rewrite | |
- 2 find_config | |
- 3 rewrite | |
- 4 post-rewrite | |
- 5 pre-access | |
- 6 access | |
- 7 post-access | |
- 8 try-files | |
- 9 content | |
- 10 log | |
Reference | |
- https://sourceware.org/systemtap/SystemTap_Beginners_Guide/userspace-probing.html | |
- https://github.com/openresty/openresty-systemtap-toolkit/blob/master/ngx-phase-handlers | |
- http://tengine.taobao.org/book/chapter_12.html#id8 | |
*/ | |
probe process("/usr/local/openresty/nginx/sbin/nginx").function("ngx_http_log_request") | |
{ | |
if (pid() == target()) { | |
/* start */ | |
begin = gettimeofday_us() | |
/* | |
Target variables | |
Refernece | |
- https://www.sourceware.org/systemtap/SystemTap_Beginners_Guide/targetvariables.html | |
*/ | |
ngx_http_core_module = &@var("ngx_http_core_module") | |
/* Typecasting ngx_http_core_module as a pointer ot ngx_module_t type, and accessing its ctx_index variable */ | |
ctx_index = @cast(ngx_http_core_module, "ngx_module_t")->ctx_index | |
/* | |
Current request | |
*/ | |
cmcf = $r->main_conf[ctx_index] | |
/* 3 rewrite phase */ | |
use_rewrite = @cast(cmcf, "ngx_http_core_main_conf_t", "/usr/local/openresty/nginx/sbin/nginx")->phases[3]->handlers->nelts ? 1 : 0 | |
/* 6 access phase */ | |
use_access = @cast(cmcf, "ngx_http_core_main_conf_t", "/usr/local/openresty/nginx/sbin/nginx")->phases[6]->handlers->nelts ? 1 : 0 | |
n = 0 | |
/* | |
There're total 11 phases, including last `log` phase. | |
Since `log` is the last executed phase, all previous phases may be executed(including been escaped) | |
*/ | |
for ( i = 0; i < 10; i++) { | |
if (i == 2) { /* find_config: find location config via uri */ | |
n++ | |
continue | |
} | |
if ( i == 4) { /* post-rewrite: check rewrite result */ | |
if(use_rewrite) { | |
n++ | |
} | |
continue | |
} | |
if ( i == 7){ /* post-access: execute access result */ | |
if(use_access) { | |
n++ | |
} | |
continue | |
} | |
if ( i == 8 ){ /* try-files */ | |
if ( @cast(cmcf, "ngx_http_core_main_conf_t", "/usr/local/openresty/nginx/sbin/nginx")->try_files ) { | |
n++ | |
} | |
continue | |
} | |
/* | |
Each phase is designed to allow registering handlers (although some phases are actually not, e.g. post-access) | |
*/ | |
phase_len = @cast(cmcf, "ngx_http_core_main_conf_t", "/usr/local/openresty/nginx/sbin/nginx")->phases[i]->handlers->nelts | |
if ( phase_len == 0 ){ | |
continue | |
} | |
if ( i == 0 ) { | |
println("post-read phase") | |
} else if ( i == 1 ) { | |
println("server-rewrite phase") | |
} else if ( i == 3 ) { | |
println("rewrite-phase") | |
} else if ( i == 5 ) { | |
println("pre-access phase") | |
} else if ( i == 6) { | |
println("access phase") | |
} else if (i == 9) { | |
println("content phase") | |
if ($r->content_handler) { | |
printf(" %s (request content handler)\n", usymname($r->content_handler)) | |
} | |
} else { | |
printf("unknown phase (%d)\n", i) | |
} | |
/* Registered handlers in current phase */ | |
for (j = 0; j < phase_len; j++) { | |
handler = @cast(cmcf, "ngx_http_core_main_conf_t", "/usr/local/openresty/nginx/sbin/nginx")->phase_engine->handlers[n++]->handler | |
if (handler == 0 ) { | |
continue | |
} | |
printf(" %s\n", usymname(handler)) | |
} | |
printf("\n") | |
} | |
/* log phase */ | |
println("log phase") | |
print_phase(cmcf, 10) | |
elapsed = gettimeofday_us() - begin | |
printf("\n%d microseconds elapsed in the probe handler.\n", elapsed) | |
exit() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ngx-phase-handlers
This tool dumps all the handlers registered by all the nginx modules for every nginx running phase in the order they actually run.
This is very useful in debugging Nginx configuration issues caused by misinterpreting the running order of the Nginx configuration directives.
Reference