Apacheã¢ã¸ã¥ã¼ã«ã®ä½æã¨gdbã¨loggerã§ã®ãããã°æ¹æ³
Apacheã®Filterã¢ã¸ã¥ã¼ã«ãä½ã£ã話ãããããid:c9katayamaã«æ å ±å ¬éããã¨è¨ãããã¾ã¾ã§ããã®ã§å ¬éãã¾ãã
Cè¨èªã®åå¼·ãããããªãApache2.xã®ã¢ã¸ã¥ã¼ã«ãä½ã£ã¦ã¿ããããªãgdb使ã£ã¦ãããã°ãã¦ã¿ããããªã¨èãã¦ã人ã«ãå§ãã§ãã
Javaã§ã®Servletã®éçºçµé¨ã®ãã人ã§ããã°ãFilterã®å¦çã®åãããªã¯ã¨ã¹ãã³ã³ããã¹ãã®èãæ¹ã¯åããæãã¯ããªã®ã§ãã¨ã³ããªãèªã¿çµããé ã«ã¯Apacheã®ã¢ã¸ã¥ã¼ã«ãgdbã§ãããã°ããªããä½ãäºãåºæ¥ãã¯ãã§ãã
mod_orzãä½æ
ä»åã¯mod_orzã¨ããApacheã¢ã¸ã¥ã¼ã«ãä½æãã¾ãã
Apacheã¢ã¸ã¥ã¼ã«ãä½æããéã«ã¯ãapxsã¨ããã¢ã¸ã¥ã¼ã«éçºç¨ã®ã³ãã³ãã使ç¨ããã³ãã¬ã¼ããä½ãã¾ãã
# apxs -g -n orz Creating [DIR] orz Creating [FILE] orz/Makefile Creating [FILE] orz/modules.mk Creating [FILE] orz/mod_orz.c Creating [FILE] orz/.deps # ls orz Makefile mod_orz.c modules.mk
ã³ãã³ãå¼æ°-gã§ãã³ãã¬ã¼ãåºåã-nã§ã¢ã¸ã¥ã¼ã«åãæå®ããã¨orzãã©ã«ããä½æããããã®ä¸ã«ã¢ã¸ã¥ã¼ã«ã®ãã³ãã¬ã¼ããåºæ¥ä¸ããã¾ãã
ãã®ã¾ã¾ã§ããµã³ãã«ã¨ãã¦åãã¾ããmod_orzããã表示ããããã®ã§mod_orz.cã®orz_handlerã以ä¸ã®ããã«å¤ãã¾ãã
static int orz_handler(request_rec *r) { if (strcmp(r->handler, "orz")) { return DECLINED; } r->content_type = "text/html"; if (!r->header_only) { int i = 0; for (i = 0; i <= 100; i++) { ap_rputs("orz ", r); } } return OK; }
ã³ã³ãã¤ã«ããéã«ã¯make installã§ãå¯è½ã§ãããapacheã®è¨å®ãã¡ã¤ã«(httpd.conf)ã«LoadModuleãã£ã¬ã¯ãã£ãã追å ãmodulesãã£ã¬ã¯ããªã«ã¢ã¸ã¥ã¼ã«ãã³ãã¼ãããã®ã§apxsã³ãã³ãã使ç¨ãã¾ãã
# apxs -i -a -c mod_orz.c
ã³ãã³ãå¼æ°-iã§modulesã«ã³ãã¼ã-aã§httpd.confã«LodModuleãã£ã¬ã¯ãã£ã追å ã-cã§ã³ã³ãã¤ã«ã§ãã
ä¸å¿ãnmã§ç¢ºèªãã¾ãããã
# nm /usr/local/apache2/modules/mod_orz.so | grep orz 00000470 t orz_handler 000016a0 D orz_module 00000430 t orz_register_hooks
ããã¾ã§æ¥ããããã¨ã¯httpd.confã«ä»¥ä¸ã®è¨å®ã追å ãã¾ãã
<Location "/orz/"> SetHandler orz </Location>
ãã㧠/orz/ ã®ãªã¯ã¨ã¹ãã«å¯¾ãä½æããmod_orzã¢ã¸ã¥ã¼ã«ãå¼ã³åºããã¾ãã
apacheãåèµ·åããhttp://ã¢ãããã®ãµã¼ã/orz/ãã«ã¢ã¯ã»ã¹ããã¨orzã100å表示ããã¦ããã®ãåããã¨æãã¾ãã
表示ããã¦ãã¾ããï¼
Cè¨èªãApacheã¢ã¸ã¥ã¼ã«ä½æãåãã¦ã®äººã§ã5å足ããã§ã¢ã¸ã¥ã¼ã«ä½æåºæ¥ãã¨æãã¾ãã
Apacheã¢ã¸ã¥ã¼ã«ã®ãããã°æ¹æ³(stderr/ap_log_rerror/customlog/gdb)
Error Log
gdbã§ãããã°ããåã«ãã¾ãã¯fprintfã使ã£ã¦ãããã°ãã¦ã¿ã¾ãã
mod_orz.cã®foræã®ä¸ã«ä»¥ä¸ã追å ãã«ã¼ãã«ã¦ã³ã¿ããããã°ãã¾ãã
fprintf(stderr, "i=[%d]\n", i);
追å å¾ã«apxs -i -a -c mod_orz.cãå®è¡ããerror_logãtailããªãããããã°ãã¾ã
å
ã»ã©ã®ãã¼ã¸ã«ã¢ã¯ã»ã¹ããã¨ãerror_logã«ã«ã¼ãã«ã¦ã³ã¿ã表示ãããã®ãåããã¨æãã¾ãã
â»apacheã-Xä»ãã®å
é¨ãããã°ç¨ã¨ãã¦ã·ã³ã°ã«ããã»ã¹ã¢ã¼ãï¼åããã»ã¹ã¯forkããªãï¼ã§å®è¡ããå¿
è¦ãããã¾ã
Apache API ap_log_rerror
httplog.hã«ãããApache APIã®ap_log_rerrorã使ãã¾ãã
#include "http_log.h" // ãã£ãã®ã«ã¼ãã«ã¦ã³ã¿ãap_log_rerrorã§åºå ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "use ap_log_error:[%d]", i);
ap_log_rerrorã使ãã¨æéä»ãã§error_logã«åºåããã¾ãã
[Mon May 11 23:10:02 2009] [crit] [client 192.168.56.101] use ap_log_error:[100]
第2å¼æ°ãåãæ¿ãã¦info,ãdebguãåºååºæ¥ã¾ãã
APLOG_MARKãã¯ãã¯ãããã°ããå ´åã«ãã¡ã¤ã«åã¨è¡æ°ãåºåããã¾ãã
#define APLOG_MARK __FILE__,__LINE__
åºåä¾
[Mon May 11 23:10:02 2009] [debug] mod_orz.c(61): [client 192.168.56.101] 111:[1]
Custom Log
Custom Logã¸ã¢ã¸ã¥ã¼ã«ãããã°ãåºåããã«ã¯ãã¡ã¢é åã§ããrequest_rec->notesï¼ãªã¯ã¨ã¹ãã³ã³ããã¹ãã®ãã¼ãï¼ã使ãã¾ãã
Apache APIï¼apr_table_set/apr_table_get)ã«ã¯ãå
é¨ã«key=valueå½¢å¼ã§å¤ãä¿æãã¦ãããã®ã§åãã§ã¼ãºã§å¤ãå
±æãããã¨ãå¯è½ã§ãã
ãã®key=valueå½¢å¼ã®tableã使ã£ã¦ã¢ã¸ã¥ã¼ã«ããCustom Logã¸ãã°åºåãè¡ãã¾ãã
- httpd.confï¼httpd.confã®LogFormatã«ã¢ã¸ã¥ã¼ã«ããã®ã¡ã¢ç¨ãã©ã¼ãããã§ãã%nãè¨å®ï¼
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{MyMessage}n\"" common
- mod_orz.cï¼ããã°ã©ã ããã¯ãã¼ã(r->notes)ã«ã¡ãã»ã¼ã¸ãè¨å®ãã¾ãï¼
apr_table_set(r->notes, "MyMessage", "CustomeMessage!!!");
192.168.56.101 - - [11/May/2009:23:35:26 +0900] "GET /orz/ HTTP/1.1" 200 404 "CustomMessage"
ãã®ãHashé åããã¯ãã¨ã©ã¼æ
å ±ãåå¾åºæ¥ã¾ãã
err_msg = apr_table_get(r->notes, "error-notes");
ä½ãããã®tabelããåå¾ããã¡ãã»ã¼ã¸ã¯ã¨ã¹ã±ã¼ãããã¦ããªãã®ã§ç´æ¥HTMLã«åºåããéã¯ã¨ã¹ã±ã¼ãå¦çãå
¥ãã¦ä¸ããã
gdbã§ãããã°
ãããã°ããéã«ããã¬ã¼ã¯ãã¤ã³ããè¨å®ããããã¹ãããå®è¡ãããã¨ããæ¹ã«ã¯gdbã§ã®ãããã°ããå§ããã¾ãã
gdbã«é¢ãã¦ã¯ããã¡ãããå§ãã§ãã
- ä½è : ãªãã£ã¼ãã¹ãã¼ã«ãã³,ãã¼ã©ã³ããã·ã¥,Richard M. Stallman,Roland H. Pesch,ã³ã¹ã¢ãã©ããã
- åºç社/ã¡ã¼ã«ã¼: ã¢ã¹ãã¼
- çºå£²æ¥: 1999/01
- ã¡ãã£ã¢: åè¡æ¬
- è³¼å ¥: 4人 ã¯ãªãã¯: 64å
- ãã®ååãå«ãããã° (14件) ãè¦ã
gdbãèµ·åãã¾ã
# gdb /usr/local/apache2/bin/httpd
orz_handlerã¡ã½ããã«ãã¬ã¤ã¯ãã¤ã³ããä»æãã¾ãï¼bã¯breakã®aliasï¼
(gdb) b orz_handler
å¼æ°-Xä»ãã§èµ·åï¼rã¯runã®aliasï¼
(gdb) r -X
ãã®ç¶æ ã§ãhttp://ã¢ããããµã¼ã/orz/ ã«ã¢ã¯ã»ã¹ããã¨ããã©ã¦ã¶ã¯å¿çå¾ ã¡ã§gdbã®ã³ã³ã½ã¼ã«ã«å¦çãæ»ãã¾ãã
Breakpoint 1, orz_handler (r=0x9feb2d0) at mod_orz.c:49 49 if (strcmp(r->handler, "orz")) { (gdb)
ããã§ãã¹ãããå®è¡ãã¾ãï¼nã¯nextã®aliasï¼
(gdb) n 54 if (!r->header_only) { (gdb) n 52 r->content_type = "text/html"; (gdb) n 54 if (!r->header_only) {
ã¹ãããå®è¡ãã¦ããã®ãåããã¨æãã¾ããã©ãã©ãå®è¡ãã¦ã«ã¼ãã«å ¥ãã¾ã
(gdb) n 58 ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, "use ap_log_error:[%d]", i);
ãã®æã«ãã«ã¼ãã«ã¦ã³ã¿ã表示ããã¦ã¿ã¾ãï¼pã¯printã®aliasï¼
(gdb) p i $1 = 1
(gdb) n 56 for (i = 0; i <= 100; i++) { (gdb) p i $4 = 4
ãããã«100åãã«ã¼ããããã®ãããã©ãã®ã§ãã«ã¼ããæãã¾ãï¼uã¯untilã®aliasï¼
(gdb) n 56 for (i = 0; i <= 100; i++) { (gdb) u 60 apr_table_set(r->notes, "MyMessage", "CustomMessage");
ããã§ãªã¯ã¨ã¹ãã³ã³ããã¹ãï¼request_recï¼ã®ä¸èº«ãè¦ã¦ã¿ã¾ããp *r ã¨æã£ã¦ãã ããã
(gdb) p *r $5 = {pool = 0x8add298, connection = 0x8ad9458, server = 0x8a2f188, next = 0x0, prev = 0x0, main = 0x0, the_request = 0x8ade0b8 "GET /orz/ HTTP/1.1", assbackwards = 0, proxyreq = 0, header_only = 0, protocol = 0x8ade128 "HTTP/1.1", proto_num = 1001, hostname = 0x8ade4c0 "192.168.56.102", request_time = 1242663142199134, status_line = 0x0, status = 200, method = 0x8ade108 "GET", method_number = 0, allowed = 0, allowed_xmethods = 0x0, allowed_methods = 0x8add470, sent_bodyct = 0, bytes_sent = 0, mtime = 0, chunked = 0, range = 0x0, clength = 0, remaining = 0, read_length = 0, read_body = 0, read_chunked = 0, expecting_100 = 0, headers_in = 0x8add4a0, headers_out = 0x8add930, err_headers_out = 0x8addad8, subprocess_env = 0x8add6e8, notes = 0x8addc30, content_type = 0xf69654 "text/html", handler = 0x8aad910 "orz", content_encoding = 0x0, content_languages = 0x0, vlist_validator = 0x0, user = 0x0, ap_auth_type = 0x0, no_cache = 0, no_local_copy = 0, unparsed_uri = 0x8ade118 "/orz/", uri = 0x8ade120 "/orz/", filename = 0x8ade7f0 "/usr/local/apache2/htdocs/orz", canonical_filename = 0x8ade7f0 "/usr/local/apache2/htdocs/orz", path_info = 0x8ade78d "/", args = 0x0, finfo = {pool = 0x8add298, valid = 7598448, protection = 1877, filetype = APR_NOFILE, user = 0, group = 0, inode = 1579484, device = 64768, nlink = 2, size = 4096, csize = 623422955655647896, atime = 1242586928000000, mtime = 1228576600000000, ctime = 1242545432000000, fname = 0x8ade7f0 "/usr/local/apache2/htdocs/orz", name = 0x8aada00 "/usr/local/apache2/htdocs", filehand = 0x8ade125}, parsed_uri = {scheme = 0x0, hostinfo = 0x0, user = 0x0, password = 0x0, hostname = 0x0, port_str = 0x0, path = 0x8ade120 "/orz/", query = 0x0, fragment = 0x0, hostent = 0x0, port = 0, is_initialized = 1, dns_looked_up = 0, dns_resolved = 0}, used_path_info = 2, per_dir_config = 0x8adeca0, request_config = 0x8addd88, htaccess = 0x0, output_filters = 0x8ade038, input_filters = 0x8ade4d0, proto_output_filters = 0x8ade038, proto_input_filters = 0x8ade4d0, eos_sent = 0}
request_recã«ã¯ãããªãã®æ
å ±ãæ ¼ç´ããã¦ãã¾ããapacheã®æ§é ã®ç解ãæ·±ããã«ã¯gdbã§é½åº¦ç¢ºèªãã¦ã¿ãã¨è¯ãã§ãããã
è¦é£ãå ´åã«ã¯ã以ä¸ã®è¨å®(set print pretty on)ã§æ¹è¡ããè¦ããããªãã¾ãã
(gdb) set print pretty on (gdb) p *r $6 = { pool = 0x8485298, connection = 0x8481458, server = 0x83d7188, next = 0x0, prev = 0x0, main = 0x0, the_request = 0x84860b8 "GET /orz/ HTTP/1.1", assbackwards = 0, proxyreq = 0, header_only = 0, protocol = 0x8486128 "HTTP/1.1", proto_num = 1001, hostname = 0x84864c0 "192.168.56.102", request_time = 1242663810469588, status_line = 0x0, status = 200, method = 0x8486108 "GET", method_number = 0, allowed = 0, allowed_xmethods = 0x0, allowed_methods = 0x8485470, sent_bodyct = 0, bytes_sent = 0, mtime = 0, chunked = 0, range = 0x0, clength = 0, remaining = 0, read_length = 0, read_body = 0, read_chunked = 0, expecting_100 = 0, headers_in = 0x84854a0, headers_out = 0x8485930, err_headers_out = 0x8485ad8, subprocess_env = 0x84856e8, notes = 0x8485c30, content_type = 0x0, handler = 0x8455910 "orz", content_encoding = 0x0, content_languages = 0x0, vlist_validator = 0x0, user = 0x0, ap_auth_type = 0x0, no_cache = 0, no_local_copy = 0, unparsed_uri = 0x8486118 "/orz/", uri = 0x8486120 "/orz/", filename = 0x84867f0 "/usr/local/apache2/htdocs/orz", canonical_filename = 0x84867f0 "/usr/local/apache2/htdocs/orz", path_info = 0x848678d "/", args = 0x0, finfo = { pool = 0x8485298, valid = 7598448, protection = 1877, filetype = APR_NOFILE, user = 0, group = 0, inode = 1579484, device = 64768, nlink = 2, size = 4096, csize = 594853245512864408, atime = 1242586928000000, mtime = 1228576600000000, ctime = 1242545432000000, fname = 0x84867f0 "/usr/local/apache2/htdocs/orz", name = 0x8455a00 "/usr/local/apache2/htdocs", filehand = 0x8486125 }, parsed_uri = { scheme = 0x0, hostinfo = 0x0, user = 0x0, password = 0x0, hostname = 0x0, port_str = 0x0, path = 0x8486120 "/orz/", query = 0x0, fragment = 0x0, hostent = 0x0, port = 0, is_initialized = 1, dns_looked_up = 0, dns_resolved = 0 }, used_path_info = 2, per_dir_config = 0x8486ca0, request_config = 0x8485d88, htaccess = 0x0, output_filters = 0x8486038, input_filters = 0x84864d0, proto_output_filters = 0x8486038, proto_input_filters = 0x84864d0, eos_sent = 0 }
æå¾ã«cï¼continueï¼ãã¦å¦çãçµããããã¨ãã©ã¦ã¶ã«orzã表示ãããã®ãåããã¨æãã¾ãã
(gdb) c Continuing.
gdbã¯ãã¨ã¦ã便å©ãªãããã¬ã§ãã®ã§è§¦ã£ã¦ã¿ããããªãã¨æã£ã¦ãã人ã«ã¯ãå§ãã§ãã
çµè«
Apache Moduleãä½æããã°ãAAA(Access,Authentication,Authorization)ModuleãFilter Moduleãªã©ãããããªç´°ããå¶å¾¡ãèªä½ããäºãå¯è½ã§ãã
Cè¨èªãããããªãã¨æã£ã¦ã人ã¯ãæ¯é触ã£ã¦ã¿ã¦ãã ãããmod_cache.cãªã©æ¢åã®ã¢ã¸ã¥ã¼ã«ã®ã½ã¼ã¹ãèªãã¨åèã«ãªãã¾ãã
çããç´ æµãªmod_xxxãä½ã£ã¦ä¸ããã
gdbã使ã£ãã¢ã¸ã¥ã¼ã«éçºã好ãã«ãªãã©ããããEclipseãNetBeansãVisual Studioããã£ã±ãåãã¨ããçµè«ã«è³ã£ã¦ãã¾ã£ããããããªããã