diff --git a/ap.d b/ap.d new file mode 100644 index 0000000000..6084096721 --- /dev/null +++ b/ap.d @@ -0,0 +1,102 @@ +#pragma D depends_on provider io +typedef struct request_rec { + uintptr_t pool; + uintptr_t connection; + uintptr_t server; + uintptr_t next; + uintptr_t prev; + uintptr_t main; + char *the_request; + int assbackwards; + int proxyreq; + int header_only; + char *protocol; + int proto_num; + char *hostname; + int64_t request_time; + char *status_line; + int status; + const char *method; + int method_number; + int64_t allowed; + uintptr_t allowed_xmethods; + uintptr_t allowed_methods; + offset_t sent_bodyct; + offset_t bytes_sent; + int64_t mtime; + int chunked; + char *range; + offset_t clength; + offset_t remaining; + offset_t read_length; + int read_body; + int read_chunked; + unsigned expecting_100; + uintptr_t headers_in; + uintptr_t headers_out; + uintptr_t err_headers_out; + uintptr_t subprocess_env; + uintptr_t notes; + char *content_type; /* Break these out --- we dispatch on 'em */ + char *handler; /* What we *really* dispatch on */ + char *content_encoding; + uintptr_t content_languages; + char *vlist_validator; + char *user; + char *ap_auth_type; + int no_cache; + int no_local_copy; + char *unparsed_uri; + char *uri; + char *filename; + char *canonical_filename; + char *path_info; + char *args; + /* finfo */ + uintptr_t finfo_pool; + int32_t finfo_valid; + int32_t finfo_protection; + int32_t finfo_filetype; + int finfo_user; + int finfo_group; + uint64_t finfo_inode; + uint64_t finfo_device; + int32_t finfo_nlink; + offset_t finfo_size; + offset_t finfo_csize; + int64_t finfo_atime; + int64_t finfo_mtime; + int64_t finfo_ctime; + char *finfo_fname; + char *finfo_name; + uintptr_t finfo_ffilehand; + /* parsed_uri */ + char *uri_scheme; + char *uri_hostinfo; + char *uri_user; + char *uri_password; + char *uri_hostname; + char *uri_port_str; + char *uri_path; + char *uri_query; + char *uri_fragment; + uintptr_t uri_hostent; + uint16_t uri_port; + unsigned uri_is_initialized:1; + unsigned uri_dns_looked_up:1; + unsigned uri_dns_resolved:1; + + /* back to request_rec */ + int used_path_info; + uintptr_t per_dir_config; + uintptr_t request_config; + uintptr_t htaccess; + uintptr_t output_filters; + uintptr_t input_filters; + uintptr_t proto_output_filters; + uintptr_t proto_input_filters; + int eos_sent; + uintptr_t kept_body; + uintptr_t invoke_mtx; +} request_rec; + diff --git a/apache_probes.d b/apache_probes.d new file mode 100644 index 0000000000..e7d077bdf9 --- /dev/null +++ b/apache_probes.d @@ -0,0 +1,172 @@ +provider ap { + /* Explicit, core */ + probe internal__redirect(char *, char *); + probe process__request__entry(uintptr_t, char *); + probe process__request__return(uintptr_t, char *, uint32_t); + probe read__request__entry(uintptr_t, uintptr_t); + probe read__request__success(uintptr_t, char *, char *, char *, uint32_t); + probe read__request__failure(uintptr_t); + + /* Explicit, modules */ + probe rewrite__log(uintptr_t, int, int, char *, char *); + probe proxy__run(uintptr_t); + probe proxy__run__finished(uintptr_t); + + /* Implicit, APR hooks */ + probe translate_name__entry(); + probe translate_name__dispatch__invoke(char *); + probe translate_name__dispatch__complete(char *, uint32_t); + probe translate_name__return(uint32_t); + probe map_to_storage__entry(); + probe map_to_storage__dispatch__invoke(char *); + probe map_to_storage__dispatch__complete(char *, uint32_t); + probe map_to_storage__return(uint32_t); + probe check_user_id__entry(); + probe check_user_id__dispatch__invoke(char *); + probe check_user_id__dispatch__complete(char *, uint32_t); + probe check_user_id__return(uint32_t); + probe fixups__entry(); + probe fixups__dispatch__invoke(char *); + probe fixups__dispatch__complete(char *, uint32_t); + probe fixups__return(uint32_t); + probe type_checker__entry(); + probe type_checker__dispatch__invoke(char *); + probe type_checker__dispatch__complete(char *, uint32_t); + probe type_checker__return(uint32_t); + probe access_checker__entry(); + probe access_checker__dispatch__invoke(char *); + probe access_checker__dispatch__complete(char *, uint32_t); + probe access_checker__return(uint32_t); + probe auth_checker__entry(); + probe auth_checker__dispatch__invoke(char *); + probe auth_checker__dispatch__complete(char *, uint32_t); + probe auth_checker__return(uint32_t); + probe insert_filter__entry(); + probe insert_filter__dispatch__invoke(char *); + probe insert_filter__dispatch__complete(char *, uint32_t); + probe insert_filter__return(uint32_t); + probe create_connection__entry(); + probe create_connection__dispatch__invoke(char *); + probe create_connection__dispatch__complete(char *, uint32_t); + probe create_connection__return(uint32_t); + probe pre_connection__entry(); + probe pre_connection__dispatch__invoke(char *); + probe pre_connection__dispatch__complete(char *, uint32_t); + probe pre_connection__return(uint32_t); + probe process_connection__entry(); + probe process_connection__dispatch__invoke(char *); + probe process_connection__dispatch__complete(char *, uint32_t); + probe process_connection__return(uint32_t); + probe create_request__entry(); + probe create_request__dispatch__invoke(char *); + probe create_request__dispatch__complete(char *, uint32_t); + probe create_request__return(uint32_t); + probe header_parser__entry(); + probe header_parser__dispatch__invoke(char *); + probe header_parser__dispatch__complete(char *, uint32_t); + probe header_parser__return(uint32_t); + probe pre_config__entry(); + probe pre_config__dispatch__invoke(char *); + probe pre_config__dispatch__complete(char *, uint32_t); + probe pre_config__return(uint32_t); + probe test_config__entry(); + probe test_config__dispatch__invoke(char *); + probe test_config__dispatch__complete(char *, uint32_t); + probe test_config__return(uint32_t); + probe post_config__entry(); + probe post_config__dispatch__invoke(char *); + probe post_config__dispatch__complete(char *, uint32_t); + probe post_config__return(uint32_t); + probe open_logs__entry(); + probe open_logs__dispatch__invoke(char *); + probe open_logs__dispatch__complete(char *, uint32_t); + probe open_logs__return(uint32_t); + probe child_init__entry(); + probe child_init__dispatch__invoke(char *); + probe child_init__dispatch__complete(char *, uint32_t); + probe child_init__return(uint32_t); + probe handler__entry(); + probe handler__dispatch__invoke(char *); + probe handler__dispatch__complete(char *, uint32_t); + probe handler__return(uint32_t); + probe quick_handler__entry(); + probe quick_handler__dispatch__invoke(char *); + probe quick_handler__dispatch__complete(char *, uint32_t); + probe quick_handler__return(uint32_t); + probe optional_fn_retrieve__entry(); + probe optional_fn_retrieve__dispatch__invoke(char *); + probe optional_fn_retrieve__dispatch__complete(char *, uint32_t); + probe optional_fn_retrieve__return(uint32_t); + probe get_mgmt_items__entry(); + probe get_mgmt_items__dispatch__invoke(char *); + probe get_mgmt_items__dispatch__complete(char *, uint32_t); + probe get_mgmt_items__return(uint32_t); + probe pre_mpm__entry(); + probe pre_mpm__dispatch__invoke(char *); + probe pre_mpm__dispatch__complete(char *, uint32_t); + probe pre_mpm__return(uint32_t); + probe default_port__entry(); + probe default_port__dispatch__invoke(char *); + probe default_port__dispatch__complete(char *, uint32_t); + probe default_port__return(uint32_t); + probe http_scheme__entry(); + probe http_scheme__dispatch__invoke(char *); + probe http_scheme__dispatch__complete(char *, uint32_t); + probe http_scheme__return(uint32_t); + probe error_log__entry(); + probe error_log__dispatch__invoke(char *); + probe error_log__dispatch__complete(char *, uint32_t); + probe error_log__return(uint32_t); + probe log_transaction__entry(); + probe log_transaction__dispatch__invoke(char *); + probe log_transaction__dispatch__complete(char *, uint32_t); + probe log_transaction__return(uint32_t); + probe monitor__entry(); + probe monitor__dispatch__invoke(char *); + probe monitor__dispatch__complete(char *, uint32_t); + probe monitor__return(uint32_t); + probe post_read_request__entry(); + probe post_read_request__dispatch__invoke(char *); + probe post_read_request__dispatch__complete(char *, uint32_t); + probe post_read_request__return(uint32_t); + probe get_suexec_identity__entry(); + probe get_suexec_identity__dispatch__invoke(char *); + probe get_suexec_identity__dispatch__complete(char *, uint32_t); + probe get_suexec_identity__return(uint32_t); + probe insert_error_filter__entry(); + probe insert_error_filter__dispatch__invoke(char *); + probe insert_error_filter__dispatch__complete(char *, uint32_t); + probe insert_error_filter__return(uint32_t); + + /* Implicit, APR hooks for proxy */ + probe scheme_handler__entry(); + probe scheme_handler__dispatch__invoke(char *); + probe scheme_handler__dispatch__complete(char *, uint32_t); + probe scheme_handler__return(uint32_t); + probe canon_handler__entry(); + probe canon_handler__dispatch__invoke(char *); + probe canon_handler__dispatch__complete(char *, uint32_t); + probe canon_handler__return(uint32_t); + probe pre_request__entry(); + probe pre_request__dispatch__invoke(char *); + probe pre_request__dispatch__complete(char *, uint32_t); + probe pre_request__return(uint32_t); + probe post_request__entry(); + probe post_request__dispatch__invoke(char *); + probe post_request__dispatch__complete(char *, uint32_t); + probe post_request__return(uint32_t); + + /* Implicit, APR hooks for dav */ + probe gather_propsets__entry(); + probe gather_propsets__dispatch__invoke(char *); + probe gather_propsets__dispatch__complete(char *, uint32_t); + probe gather_propsets__return(uint32_t); + probe find_liveprop__entry(); + probe find_liveprop__dispatch__invoke(char *); + probe find_liveprop__dispatch__complete(char *, uint32_t); + probe find_liveprop__return(uint32_t); + probe insert_all_liveprops__entry(); + probe insert_all_liveprops__dispatch__invoke(char *); + probe insert_all_liveprops__dispatch__complete(char *, uint32_t); + probe insert_all_liveprops__return(uint32_t); +}; diff --git a/configure.in b/configure.in index 5a98367c50..2718b2434c 100644 --- a/configure.in +++ b/configure.in @@ -380,7 +380,8 @@ grp.h \ strings.h \ sys/prctl.h \ sys/processor.h \ -sys/sem.h +sys/sem.h \ +sys/sdt.h ) AC_HEADER_SYS_WAIT @@ -446,6 +447,33 @@ AC_ARG_WITH(sslport,APACHE_HELP_STRING(--with-sslport=SSLPORT,Port on which to s [if test "$withval" = "yes"; then AC_MSG_ERROR('option --with-sslport requires a value (the SSL TCP port number)'); else SSLPORT="$withval"; fi], [SSLPORT=443]) +DTRACE=true +AC_ARG_ENABLE(dtrace,APACHE_HELP_STRING(--enable-dtrace,Enable DTrace probes), +[ + enable_dtrace=$enableval + APR_ADDTO(CPPFLAGS, -DAPR_DTRACE_PROVIDER) + AC_MSG_ERROR('DTrace Support in the build system is not complete. Patches Welcome!') +], +[ + enable_dtrace=no +]) + +dnl Disabled dtrace build for now. +enable_dtrace=no + +case $host in + *-solaris2*) + if test $enable_dtrace = "yes" -a "$ac_cv_header_sys_sdt_h" = "yes"; then + AC_DEFINE(AP_ENABLE_DTRACE, 1, + [Enable DTrace probes]) + DTRACE="/usr/sbin/dtrace $DTRACEFLAGS" + test -f include/apache_probes.h || $DTRACE -h -s apache_probes.d -o include/apache_probes.h + fi + ;; +esac + +APACHE_SUBST(DTRACE) + APR_CHECK_APR_DEFINE(APR_HAVE_IPV6) AC_ARG_ENABLE(v4-mapped,APACHE_HELP_STRING(--enable-v4-mapped,Allow IPv6 sockets to handle IPv4 connections), diff --git a/include/ap_config.h b/include/ap_config.h index dd977a6ca0..9d6a1f92b0 100644 --- a/include/ap_config.h +++ b/include/ap_config.h @@ -238,6 +238,13 @@ #define AP_NONBLOCK_WHEN_MULTI_LISTEN 1 #endif +#if AP_ENABLE_DTRACE && HAVE_SYS_SDT_H +#include +#else +#undef _DTRACE_VERSION +#endif +#include "apache_probes.h" + /* TODO - We need to put OS detection back to make all the following work */ #if defined(SUNOS4) || defined(IRIX) || defined(NEXT) || defined(AUX3) \ diff --git a/modules/http/http_request.c b/modules/http/http_request.c index 8ca18d5b4c..f3fe63fde6 100644 --- a/modules/http/http_request.c +++ b/modules/http/http_request.c @@ -260,6 +260,7 @@ void ap_process_request_after_handler(request_rec *r) c->cs->state = CONN_STATE_WRITE_COMPLETION; check_pipeline(c); + AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status); if (ap_extended_status) { ap_time_process_request(c->sbh, STOP_PREQUEST); } @@ -284,6 +285,7 @@ void ap_process_async_request(request_rec *r) * Use this hook with extreme care and only if you know what you are * doing. */ + AP_PROCESS_REQUEST_ENTRY((uintptr_t)r, r->uri); if (ap_extended_status) { ap_time_process_request(r->connection->sbh, START_PREQUEST); } @@ -299,6 +301,10 @@ void ap_process_async_request(request_rec *r) } if (access_status == SUSPENDED) { + /* TODO: Should move these steps into a generic function, so modules + * working on a suspended request can also call _ENTRY again. + */ + AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, access_status); if (ap_extended_status) { ap_time_process_request(c->sbh, STOP_PREQUEST); } @@ -536,6 +542,8 @@ AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r) request_rec *new = internal_internal_redirect(new_uri, r); int access_status; + AP_INTERNAL_REDIRECT(r->uri, new_uri); + /* ap_die was already called, if an error occured */ if (!new) { return; diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c index 84676395bc..000a6ffa13 100644 --- a/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c @@ -490,7 +490,8 @@ static void do_rewritelog(request_rec *r, int level, char *perdir, conf = ap_get_module_config(r->server->module_config, &rewrite_module); - if (!conf->rewritelogfp || level > conf->rewriteloglevel) { + if ((!conf->rewritelogfp || level > conf->rewriteloglevel) && + !AP_REWRITE_LOG_ENABLED()) { return; } @@ -524,6 +525,11 @@ static void do_rewritelog(request_rec *r, int level, char *perdir, perdir ? "] ": "", text); + AP_REWRITE_LOG((uintptr_t)r, level, r->main ? 0 : 1, (char *)ap_get_server_name(r), logline); + + if (!conf->rewritelogfp || level > conf->rewriteloglevel) + return; + rv = apr_global_mutex_lock(rewrite_log_lock); if (rv != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 39918ab845..f0254ef4a0 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -1007,6 +1007,7 @@ static int proxy_handler(request_rec *r) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Running scheme %s handler (attempt %d)", scheme, attempts); + AP_PROXY_RUN(r, worker, conf, url, attempts); access_status = proxy_run_scheme_handler(r, worker, conf, url, NULL, 0); if (access_status == OK) @@ -1054,6 +1055,7 @@ static int proxy_handler(request_rec *r) ap_proxy_post_request(worker, balancer, r, conf); proxy_run_request_status(&access_status, r); + AP_PROXY_RUN_FINISHED(r, attempts, access_status); return access_status; } diff --git a/server/protocol.c b/server/protocol.c index 8fc5c7f0c0..cabe0e69d5 100644 --- a/server/protocol.c +++ b/server/protocol.c @@ -842,9 +842,11 @@ request_rec *ap_read_request(conn_rec *conn) apr_socket_t *csd; apr_interval_time_t cur_timeout; + apr_pool_create(&p, conn->pool); apr_pool_tag(p, "request"); r = apr_pcalloc(p, sizeof(request_rec)); + AP_READ_REQUEST_ENTRY((intptr_t)r, (uintptr_t)conn); r->pool = p; r->connection = conn; r->server = conn->base_server; @@ -894,11 +896,12 @@ request_rec *ap_read_request(conn_rec *conn) ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); apr_brigade_destroy(tmp_bb); - return r; + goto traceout; } apr_brigade_destroy(tmp_bb); - return NULL; + r = NULL; + goto traceout; } /* We may have been in keep_alive_timeout mode, so toggle back @@ -921,7 +924,7 @@ request_rec *ap_read_request(conn_rec *conn) ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); apr_brigade_destroy(tmp_bb); - return r; + goto traceout; } if (apr_table_get(r->headers_in, "Transfer-Encoding") @@ -949,7 +952,7 @@ request_rec *ap_read_request(conn_rec *conn) ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); apr_brigade_destroy(tmp_bb); - return r; + goto traceout; } } @@ -1003,14 +1006,15 @@ request_rec *ap_read_request(conn_rec *conn) ap_send_error_response(r, 0); ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); - return r; + goto traceout; } if ((access_status = ap_run_post_read_request(r))) { ap_die(access_status, r); ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); - return NULL; + r = NULL; + goto traceout; } if (((expect = apr_table_get(r->headers_in, "Expect")) != NULL) @@ -1032,10 +1036,14 @@ request_rec *ap_read_request(conn_rec *conn) ap_send_error_response(r, 0); ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); - return r; + goto traceout; } } + AP_READ_REQUEST_SUCCESS((uintptr_t)r, (char *)r->method, (char *)r->uri, (char *)r->server->defn_name, r->status); + return r; + traceout: + AP_READ_REQUEST_FAILURE((uintptr_t)r); return r; }