Injecting tracing code into arbitrary functions
aexl_konzepto.net - April 16, 2008 - 11:14
| Project: | Trace |
| Version: | 5.x-1.0 |
| Component: | Tracing - Hook invocations |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs work |
| Issue tags: | runkit |
Jump to:
Description
(I'm quite new to drupal and no php wizard so i might not know the right wording...)
I'd like to do some cck debugging and trace might be great for that.
As far as i can tell trace can only be configured to listen to "broadcast hooks" and log what is broadcasted.
for instance, trace can dynamically define a function trace_menu which gives us a trace.
from trace.api.inc:170
<?php
function trace_hook_define($module, $hook) {
if (!trace_hook_defined($module, $hook)) {
eval("function {$module}_$hook() { trace_hook('$hook'); }");
return TRUE;
}
return FALSE;
}
?>It would be nice if trace could be configured as to inject log code between content.module and some my.development.module
so trace would re-define my_development_field_info() and log who calls, what is passed, and what back.
(the config might be a primitive "list of observed functions")
something like:
<?php
function trace_hook_insert($function) {
if (!trace_hook_inserted($function)) {
eval("
//save original function
\${$function}_saved = {$function};
function {$function}() {
trace_log_backtrace('$function'); //log who calls
trace_log_arguments('$function'); //log arguments passed
\${$function}_saved();
trace_log_arguments('$function'); //log arguments returned
}
");
return TRUE;
}
return FALSE;
}
?>
#1
Trying to refine the codesnippet above.
learned that php can redefine functions with the runkit_* extension functions.
so we might get something like:
<?php
define('TRACE_HOOKPREFIX','trace_copyof_');
function trace_hook_insert($functionname) {
if (!function_exists(TRACE_HOOKPREFIX . $functionname)) {
runkit_function_rename($functionname, TRACE_HOOKPREFIX . $functionname);
$argumentss = func_get_arg();
$code="
\$args = func_get_arg();
trace_log_backtrace('$functionname'); //log who calls
trace_log_arguments('Before $functionname', \$args); //log arguments passed
\$return = call_user_func_array({TRACE_HOOKPREFIX . $functionname}, \$args); //run copy of function
trace_log_arguments('After $functionname', \$args, \$return); //log arguments returned
return \$return;
";
runkit_function_add($functionname, $arguments, $code);
return TRUE;
}
return FALSE;
}
?>
#2
This feature would be very welcome as a patch for the 6.x branch.