Skip to content

Commit

Permalink
Wed Jan 13 15:54:53 CET 2010 Paolo Molaro <lupus@ximian.com>
Browse files Browse the repository at this point in the history
	* jit.h, method-to-ir.c: added ability to set the policy for
	inserting breakpoints from the break IL instruction or the
	Debugger.Break () API call.


svn path=/branches/mono-2-6/mono/; revision=149473
  • Loading branch information
illupus committed Jan 13, 2010
1 parent a5f096e commit 77d0633
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 2 deletions.
7 changes: 7 additions & 0 deletions mono/mini/ChangeLog
@@ -1,3 +1,10 @@

Wed Jan 13 15:54:53 CET 2010 Paolo Molaro <lupus@ximian.com>

* jit.h, method-to-ir.c: added ability to set the policy for
inserting breakpoints from the break IL instruction or the
Debugger.Break () API call.

2010-01-11 Zoltan Varga <vargaz@gmail.com>

* debugger-agent.c (mono_debugger_agent_parse_options): Allow onthrow without
Expand Down
19 changes: 19 additions & 0 deletions mono/mini/jit.h
Expand Up @@ -33,6 +33,25 @@ mono_set_signal_chaining (gboolean chain_signals);
void
mono_jit_set_aot_only (gboolean aot_only);

/* Allow embedders to decide wherther to actually obey breakpoint instructions
* in specific methods (works for both break IL instructions and Debugger.Break ()
* method calls).
*/
typedef enum {
/* the default is to always obey the breakpoint */
MONO_BREAK_POLICY_ALWAYS,
/* a nop is inserted instead of a breakpoint */
MONO_BREAK_POLICY_NEVER,
/* the breakpoint is executed only if the program has ben started under
* the debugger (that is if a debugger was attached at the time the method
* was compiled).
*/
MONO_BREAK_POLICY_ON_DBG
} MonoBreakPolicy;

typedef MonoBreakPolicy (*MonoBreakPolicyFunc) (MonoMethod *method);
void mono_set_break_policy (MonoBreakPolicyFunc policy_callback);

void
mono_jit_parse_options (int argc, char * argv[]);

Expand Down
58 changes: 56 additions & 2 deletions mono/mini/method-to-ir.c
Expand Up @@ -57,6 +57,7 @@
#include "ir-emit.h"

#include "jit-icalls.h"
#include "jit.h"
#include "debugger-agent.h"

#define BRANCH_COST 100
Expand Down Expand Up @@ -3772,6 +3773,53 @@ mini_emit_ldelema_ins (MonoCompile *cfg, MonoMethod *cmethod, MonoInst **sp, uns
return addr;
}

static MonoBreakPolicy
always_insert_breakpoint (MonoMethod *method)
{
return MONO_BREAK_POLICY_ALWAYS;
}

static MonoBreakPolicyFunc break_policy_func = always_insert_breakpoint;

/**
* mono_set_break_policy:
* policy_callback: the new callback function
*
* Allow embedders to decide wherther to actually obey breakpoint instructions
* (both break IL instructions and Debugger.Break () method calls), for example
* to not allow an app to be aborted by a perfectly valid IL opcode when executing
* untrusted or semi-trusted code.
*
* @policy_callback will be called every time a break point instruction needs to
* be inserted with the method argument being the method that calls Debugger.Break()
* or has the IL break instruction. The callback should return #MONO_BREAK_POLICY_NEVER
* if it wants the breakpoint to not be effective in the given method.
* #MONO_BREAK_POLICY_ALWAYS is the default.
*/
void
mono_set_break_policy (MonoBreakPolicyFunc policy_callback)
{
if (policy_callback)
break_policy_func = policy_callback;
else
break_policy_func = always_insert_breakpoint;
}

static gboolean
should_insert_brekpoint (MonoMethod *method) {
switch (break_policy_func (method)) {
case MONO_BREAK_POLICY_ALWAYS:
return TRUE;
case MONO_BREAK_POLICY_NEVER:
return FALSE;
case MONO_BREAK_POLICY_ON_DBG:
return mono_debug_using_mono_debugger ();
default:
g_warning ("Incorrect value returned from break policy callback");
return FALSE;
}
}

static MonoInst*
mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
Expand Down Expand Up @@ -4130,7 +4178,10 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
} else if (cmethod->klass->image == mono_defaults.corlib) {
if (cmethod->name [0] == 'B' && strcmp (cmethod->name, "Break") == 0
&& strcmp (cmethod->klass->name, "Debugger") == 0) {
MONO_INST_NEW (cfg, ins, OP_BREAK);
if (should_insert_brekpoint (cfg->method))
MONO_INST_NEW (cfg, ins, OP_BREAK);
else
MONO_INST_NEW (cfg, ins, OP_NOP);
MONO_ADD_INS (cfg->cbb, ins);
return ins;
}
Expand Down Expand Up @@ -5842,7 +5893,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
MONO_ADD_INS (bblock, ins);
break;
case CEE_BREAK:
MONO_INST_NEW (cfg, ins, OP_BREAK);
if (should_insert_brekpoint (cfg->method))
MONO_INST_NEW (cfg, ins, OP_BREAK);
else
MONO_INST_NEW (cfg, ins, OP_NOP);
ip++;
MONO_ADD_INS (bblock, ins);
break;
Expand Down

0 comments on commit 77d0633

Please sign in to comment.