diff options
author | David Karlaš <david.karlas@gmail.com> | 2017-01-04 09:49:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-04 09:49:11 +0300 |
commit | 41bb2b531662364fbfd1a3d763d0bc99277d2f3f (patch) | |
tree | fdca33e392c6e4107a3f945464612df566ec0442 | |
parent | ce68b90aa7bd6c88c88b63a520676e791b69eb25 (diff) | |
parent | 9a231cd18e80e46d3ad9981692015256ea816581 (diff) |
Merge pull request #4196 from DavidKarlas/stepAndCatchException
[Debugger] Fixed step-in and step-out in case of exception + unit tests
-rw-r--r-- | mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs | 52 | ||||
-rw-r--r-- | mcs/class/Mono.Debugger.Soft/Test/dtest.cs | 56 | ||||
-rw-r--r-- | mono/mini/debugger-agent.c | 35 |
3 files changed, 97 insertions, 46 deletions
diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs index 61ed822f2e1..1687bcbc72d 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs @@ -485,23 +485,49 @@ public class Tests : TestsBase, ITest2 public static void ss6_2 () { } - [MethodImplAttribute (MethodImplOptions.NoInlining)] - public static void ss7 () { - try { - ss7_2 (); - ss7_3 (); - } catch { - } - ss7_2 (); + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void ss7 () + { + ss7_2();//Used to test stepout inside ss7_2, which may not go to catch + ss7_2();//Used to test stepout inside ss7_2_1, which must go to catch + ss7_2();//Used to test stepover inside ss7_2, which must go to catch + ss7_2();//Used to test stepover inside ss7_2_1, which must go to catch + ss7_3();//Used to test stepin inside ss7_3, which must go to catch + ss7_2();//Used to test stepin inside ss7_2_1, which must go to catch } - [MethodImplAttribute (MethodImplOptions.NoInlining)] - public static void ss7_2 () { + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void ss7_2_1 () + { + throw new Exception (); } - [MethodImplAttribute (MethodImplOptions.NoInlining)] - public static void ss7_3 () { - throw new Exception (); + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void ss7_2_2 () + { + ss7_2_1(); + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void ss7_2 () + { + try { + ss7_2_2(); + } + catch + { + } + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] + public static void ss7_3 () + { + try { + throw new Exception (); + } + catch + { + } } [MethodImplAttribute (MethodImplOptions.NoInlining)] diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs index dbc13f065e6..f6312cb1703 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs @@ -723,23 +723,53 @@ public class DebuggerTests assert_location (e, "ss6"); req.Disable (); - // Check that a step over stops at an EH clause + // Testing stepping in, over and out with exception handlers in same or caller method + + //stepout in ss7_2, which may not go to catch(instead out to ss7) e = run_until ("ss7_2"); - req = create_step (e); - req.Depth = StepDepth.Out; - req.Enable (); - e = step_once (); - assert_location (e, "ss7"); - req.Disable (); - req = create_step (e); - req.Depth = StepDepth.Over; - req.Enable (); - e = step_once (); - assert_location (e, "ss7"); - req.Disable (); + create_step (e); + assert_location (step_out(), "ss7"); + + //stepout in ss7_2_1, which must go to catch + run_until ("ss7_2_1"); + assert_location (step_out (), "ss7_2"); + + //stepover over ss7_2, which must go to catch + run_until ("ss7_2"); + assert_location (step_over (), "ss7_2");//move to "try {" line + assert_location (step_over (), "ss7_2");//move to "ss7_2_2();" line + assert_location (step_over (), "ss7_2");//step over ss7_2_2();, assume we are at "catch" now + assert_location (step_over (), "ss7_2");//move to { of catch + assert_location (step_over (), "ss7_2");//move to } of catch + assert_location (step_over (), "ss7_2");//move to } of method + assert_location (step_over (), "ss7");//finish method + + //stepover over ss7_2_1, which must go to catch + run_until ("ss7_2_1"); + assert_location (step_over (), "ss7_2_1");//move from { of method to "throw new Exception ();" + assert_location (step_over (), "ss7_2");//step over exception, being in ss7_2 means we are at catch + + //stepin in ss7_3, which must go to catch + run_until ("ss7_3"); + assert_location (step_into (), "ss7_3");//move to "try {" + assert_location (step_into (), "ss7_3");//move to "throw new Exception ();" + step_req.Disable (); + step_req.AssemblyFilter = new AssemblyMirror [] { (e as BreakpointEvent).Method.DeclaringType.Assembly }; + assert_location (step_into (), "ss7_3");//call "throw new Exception ();", we assume we end up at "catch" + assert_location (step_into (), "ss7_3");//move to { of catch + assert_location (step_into (), "ss7_3");//move to } of catch + assert_location (step_into (), "ss7_3");//move to } of method + assert_location (step_into (), "ss7");//move out to ss7 + + //stepover in ss7_2_1, which must go to catch + run_until ("ss7_2_1"); + assert_location (step_into (), "ss7_2_1");//move from { of method to "throw new Exception ();" + assert_location (step_into (), "ss7_2");//step in exception, being in ss7_2 means we are at catch + step_req.Disable (); // Check that stepping stops between nested calls e = run_until ("ss_nested_2"); + req = create_step (e); e = step_out (); assert_location (e, "ss_nested"); e = step_into (); diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 7402923f8ba..0e95ae85f20 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -5236,6 +5236,21 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI nframes = tls->frame_count; } + /* Need to stop in catch clauses as well */ + for (i = ss_req->depth == STEP_DEPTH_OUT ? 1 : 0; i < nframes; ++i) { + StackFrame *frame = frames [i]; + + if (frame->ji) { + MonoJitInfo *jinfo = frame->ji; + for (j = 0; j < jinfo->num_clauses; ++j) { + MonoJitExceptionInfo *ei = &jinfo->clauses [j]; + + if (mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp)) + ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, frame->method, local_sp.il_offset); + } + } + } + /* * Find the first sequence point in the current or in a previous frame which * is not the last in its method. @@ -5322,26 +5337,6 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint* sp, MonoSeqPointI ss_req->depth = STEP_DEPTH_INTO; } - if (ss_req->depth == STEP_DEPTH_OVER) { - /* Need to stop in catch clauses as well */ - for (i = 0; i < nframes; ++i) { - StackFrame *frame = frames [i]; - - if (frame->ji) { - MonoJitInfo *jinfo = frame->ji; - for (j = 0; j < jinfo->num_clauses; ++j) { - MonoJitExceptionInfo *ei = &jinfo->clauses [j]; - - found_sp = mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp); - sp = (found_sp)? &local_sp : NULL; - - if (found_sp) - ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, frame->method, sp->il_offset); - } - } - } - } - if (ss_req->depth == STEP_DEPTH_INTO) { /* Enable global stepping so we stop at method entry too */ enable_global = TRUE; |