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
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

aexl_konzepto.net - April 18, 2008 - 20:10

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

Arto - September 18, 2009 - 16:14
Title:Trace to observe function calls» Injecting tracing code into arbitrary functions
Status:active» needs work

This feature would be very welcome as a patch for the 6.x branch.

 
 

Drupal is a registered trademark of Dries Buytaert.