34
34
* @ingroup APR_Util
39
* @defgroup apr_hook_probes Hook probe capability
40
* APR hooks provide a trace probe capability for capturing
41
* the flow of control and return values with hooks.
43
* In order to use this facility, the application must define
44
* the symbol APR_HOOK_PROBES_ENABLED and the four APR_HOOK_PROBE_
45
* macros described below before including apr_hooks.h in files
46
* that use the APR_IMPLEMENT_EXTERNAL_HOOK_* macros.
48
* This probe facility is not provided for APR optional hooks.
52
#ifdef APR_HOOK_PROBES_ENABLED
53
#define APR_HOOK_INT_DCL_UD void *ud = NULL
55
/** internal implementation detail to avoid the ud declaration when
56
* hook probes are not used
58
#define APR_HOOK_INT_DCL_UD
60
* User-defined hook probe macro that is invoked when the hook
61
* is run, before calling any hook functions.
62
* @param ud A void * user data field that should be filled in by
63
* this macro, and will be provided to the other hook probe macros.
64
* @param ns The namespace prefix of the hook functions
65
* @param name The name of the hook
66
* @param args The argument list to the hook functions, with enclosing
69
#define APR_HOOK_PROBE_ENTRY(ud,ns,name,args)
71
* User-defined hook probe macro that is invoked after the hook
73
* @param ud A void * user data field that was filled in by the user-
74
* provided APR_HOOK_PROBE_ENTRY().
75
* @param ns The namespace prefix of the hook functions
76
* @param name The name of the hook
77
* @param rv The return value of the hook, or 0 if the hook is void.
78
* @param args The argument list to the hook functions, with enclosing
81
#define APR_HOOK_PROBE_RETURN(ud,ns,name,rv,args)
83
* User-defined hook probe macro that is invoked before calling a
85
* @param ud A void * user data field that was filled in by the user-
86
* provided APR_HOOK_PROBE_ENTRY().
87
* @param ns The namespace prefix of the hook functions
88
* @param name The name of the hook
89
* @param src The value of apr_hook_debug_current at the time the function
90
* was hooked (usually the source file implementing the hook function).
91
* @param args The argument list to the hook functions, with enclosing
94
#define APR_HOOK_PROBE_INVOKE(ud,ns,name,src,args)
96
* User-defined hook probe macro that is invoked after calling a
98
* @param ud A void * user data field that was filled in by the user-
99
* provided APR_HOOK_PROBE_ENTRY().
100
* @param ns The namespace prefix of the hook functions
101
* @param name The name of the hook
102
* @param src The value of apr_hook_debug_current at the time the function
103
* was hooked (usually the source file implementing the hook function).
104
* @param rv The return value of the hook function, or 0 if the hook is void.
105
* @param args The argument list to the hook functions, with enclosing
108
#define APR_HOOK_PROBE_COMPLETE(ud,ns,name,src,rv,args)
37
113
/** macro to return the prototype of the hook function */
38
114
#define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name) \
39
115
link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)
107
183
ns##_LINK_##name##_t *pHook; \
110
if(!_hooks.link_##name) \
113
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
114
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
115
pHook[n].pFunc args_use; \
185
APR_HOOK_INT_DCL_UD; \
187
APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
189
if(_hooks.link_##name) \
191
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
192
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
194
APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
195
pHook[n].pFunc args_use; \
196
APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, 0, args_use); \
200
APR_HOOK_PROBE_RETURN(ud, ns, name, 0, args_use); \
118
204
/* FIXME: note that this returns ok when nothing is run. I suspect it should
140
226
ns##_LINK_##name##_t *pHook; \
144
if(!_hooks.link_##name) \
147
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
148
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
150
rv=pHook[n].pFunc args_use; \
152
if(rv != ok && rv != decline) \
229
APR_HOOK_INT_DCL_UD; \
231
APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
233
if(_hooks.link_##name) \
235
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
236
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
238
APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
239
rv=pHook[n].pFunc args_use; \
240
APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
241
if(rv != ok && rv != decline) \
247
APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
177
271
ns##_LINK_##name##_t *pHook; \
181
if(!_hooks.link_##name) \
184
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
185
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
187
rv=pHook[n].pFunc args_use; \
274
APR_HOOK_INT_DCL_UD; \
276
APR_HOOK_PROBE_ENTRY(ud, ns, name, args_use); \
278
if(_hooks.link_##name) \
280
pHook=(ns##_LINK_##name##_t *)_hooks.link_##name->elts; \
281
for(n=0 ; n < _hooks.link_##name->nelts ; ++n) \
283
APR_HOOK_PROBE_INVOKE(ud, ns, name, (char *)pHook[n].szName, args_use); \
284
rv=pHook[n].pFunc args_use; \
285
APR_HOOK_PROBE_COMPLETE(ud, ns, name, (char *)pHook[n].szName, rv, args_use); \
292
APR_HOOK_PROBE_RETURN(ud, ns, name, rv, args_use); \
195
297
/* Hook orderings */