The following variables are altered by C during its execution. They are "stacked" via C, enabling recursive calls to C. =over 4 =item C<@res> - used to capture output from actual C. =item C<$otrace> - saved value of C<$trace>. =item C<$osingle> - saved value of C<$single>. =item C<$od> - saved value of C<$^D>. =item C<$saved[0]> - saved value of C<$@>. =item $\ - for output of C<$@> if there is an evaluation error. =back =head3 The problem of lexicals The context of C presents us with some problems. Obviously, we want to be 'sandboxed' away from the debugger's internals when we do the eval, but we need some way to control how punctuation variables and debugger globals are used. We can't use local, because the code inside C can see localized variables; and we can't use C either for the same reason. The code in this routine compromises and uses C. After this routine is over, we don't have user code executing in the debugger's context, so we can use C freely. =cut ############################################## Begin lexical danger zone # 'my' variables used here could leak into (that is, be visible in) # the context that the code being evaluated is executing in. This means that # the code could modify the debugger's variables. # # Fiddling with the debugger's context could be Bad. We insulate things as # much as we can. sub eval { # 'my' would make it visible from user code # but so does local! --tchrist # Remember: this localizes @DB::res, not @main::res. local @res; { # Try to keep the user code from messing with us. Save these so that # even if the eval'ed code changes them, we can put them back again. # Needed because the user could refer directly to the debugger's # package globals (and any 'my' variables in this containing scope) # inside the eval(), and we want to try to stay safe. local $otrace = $trace; local $osingle = $single; local $od = $^D; # Untaint the incoming eval() argument. { ($evalarg) = $evalarg =~ /(.*)/s; } # $usercontext built in DB::DB near the comment # "set up the context for DB::eval ..." # Evaluate and save any results. @res = eval "$usercontext $evalarg;\n"; # '\n' for nice recursive debug # Restore those old values. $trace = $otrace; $single = $osingle; $^D = $od; } #### { local( $trace, $single, $^D ); ($evalarg) = $evalarg =~ /(.*)/s; # Untaint # $usercontext built in DB::DB @res = eval "$usercontext $evalarg;\n"; # '\n' for nice recursive debug } #### # 'my' would make it visible from user code # but so does local! --tchrist