Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
Cosmetic changes.
Browse files Browse the repository at this point in the history
svn path=/trunk/debugger/; revision=152395
  • Loading branch information
Martin Baulig committed Feb 24, 2010
1 parent 4c4f667 commit bd96310
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 40 deletions.
125 changes: 88 additions & 37 deletions backend/SingleSteppingEngine.cs
Expand Up @@ -1367,6 +1367,44 @@ void update_current_frame (StackFrame new_frame)
current_frame = new_frame;
}

StackFrame compute_frame (TargetAddress address)
{
var method = Lookup (address);

var iframe = inferior.GetCurrentFrame ();
var registers = inferior.GetRegisters ();

if ((method != null) && method.HasLineNumbers) {
var source = method.LineNumberTable.Lookup (address);

if (source != null)
return new StackFrame (
thread, FrameType.Normal, iframe.Address, iframe.StackPointer,
iframe.FrameAddress, registers, method, source);
else
return new StackFrame (
thread, FrameType.Normal, iframe.Address, iframe.StackPointer,
iframe.FrameAddress, registers, method);
} else {
if (method != null)
return new StackFrame (
thread, FrameType.Normal, iframe.Address, iframe.StackPointer,
iframe.FrameAddress, registers, method);
else {
Symbol name;
try {
name = SimpleLookup (address, false);
} catch {
name = null;
}
return new StackFrame (
thread, FrameType.Normal, iframe.Address, iframe.StackPointer,
iframe.FrameAddress, registers, thread.NativeLanguage,
name);
}
}
}

TemporaryBreakpointData temp_breakpoint = null;

void insert_temporary_breakpoint (TargetAddress address)
Expand Down Expand Up @@ -2241,7 +2279,7 @@ public bool ManagedCallback (ManagedCallbackFunction func, CommandResult result)

AcquireThreadLock ();

if (do_managed_callback (data)) {
if (is_managed_frame ()) {
//
// We found a managed frame; now let's first check whether we can do
// all the work without starting an operation.
Expand All @@ -2258,13 +2296,17 @@ public bool ManagedCallback (ManagedCallbackFunction func, CommandResult result)
return true;
}

Report.Debug (DebugFlags.SSE, "{0} managed callback needs thread lock", this);
//
// Stop all threads and check whether one of them is in managed land.
//

Report.Debug (DebugFlags.SSE, "{0} managed callback needs global thread lock", this);

bool ok = false;
process.AcquireGlobalThreadLock (this);
foreach (SingleSteppingEngine engine in process.ThreadServants) {
try {
if (engine.do_managed_callback (data)) {
if (engine.is_managed_frame ()) {
ok = true;
break;
}
Expand All @@ -2274,39 +2316,14 @@ public bool ManagedCallback (ManagedCallbackFunction func, CommandResult result)
}

if (!ok) {
TargetAddress lmf_address = inferior.ReadAddress (LMFAddress);
StackFrame lmf_frame = Architecture.GetLMF (this, inferior, ref lmf_address);

Report.Debug (DebugFlags.SSE, "{0} requesting managed callback: {1}", this, lmf_frame);
process.MonoManager.AddManagedCallback (inferior, data);

/*
* Prevent a race condition:
* If we stopped just before returning from native code,
* mono_thread_interruption_checkpoint_request() may not be called again
* before returning back to managed code; it's called next time we're entering
* native code again.
*
* This could lead to problems if the managed code does some CPU-intensive
* before going unmanaged next time - or even loops forever.
*
* I have a test case where an icall contains a sleep() and the managed code
* contains an infinite loop (`for (;;) ;) immediately after returning from
* this icall.
*
* To prevent this from happening, we insert a breakpoint on the last managed
* frame.
*/

if (lmf_frame != null)
insert_lmf_breakpoint (lmf_frame.TargetAddress);
else {
Report.Error ("{0} unable to compute LMF for managed callback: {1}",
this, inferior.CurrentFrame);
}
//
// None of the threads is currently in managed land; request a managed
// callback.
//
request_managed_callback (data);
}

Report.Debug (DebugFlags.SSE, "{0} managed callback releasing thread lock", this);
Report.Debug (DebugFlags.SSE, "{0} managed callback releasing global thread lock", this);
process.ReleaseGlobalThreadLock (this);

ReleaseThreadLock ();
Expand Down Expand Up @@ -2391,7 +2408,7 @@ void remove_lmf_breakpoint ()
lmf_breakpoint = null;
}

bool do_managed_callback (ManagedCallbackData data)
bool is_managed_frame ()
{
Inferior.StackFrame sframe = inferior.GetCurrentFrame ();
Method method = Lookup (inferior.CurrentFrame);
Expand All @@ -2408,6 +2425,40 @@ bool do_managed_callback (ManagedCallbackData data)
return true;
}

void request_managed_callback (ManagedCallbackData data)
{
TargetAddress lmf_address = inferior.ReadAddress (LMFAddress);
StackFrame lmf_frame = Architecture.GetLMF (this, inferior, ref lmf_address);

Report.Debug (DebugFlags.SSE, "{0} requesting managed callback: {1}", this, lmf_frame);
process.MonoManager.AddManagedCallback (inferior, data);

/*
* Prevent a race condition:
* If we stopped just before returning from native code,
* mono_thread_interruption_checkpoint_request() may not be called again
* before returning back to managed code; it's called next time we're entering
* native code again.
*
* This could lead to problems if the managed code does some CPU-intensive
* before going unmanaged next time - or even loops forever.
*
* I have a test case where an icall contains a sleep() and the managed code
* contains an infinite loop (`for (;;) ;) immediately after returning from
* this icall.
*
* To prevent this from happening, we insert a breakpoint on the last managed
* frame.
*/

if (lmf_frame != null)
insert_lmf_breakpoint (lmf_frame.TargetAddress);
else {
Report.Error ("{0} unable to compute LMF for managed callback: {1}",
this, inferior.CurrentFrame);
}
}

LMFBreakpointData lmf_breakpoint = null;

internal bool OnManagedCallback (Queue<ManagedCallbackData> callbacks)
Expand Down Expand Up @@ -4459,7 +4510,7 @@ protected class OperationMonoTrampoline : Operation

protected override void DoExecute ()
{
if (sse.MonoDebuggerInfo.HasNewTrampolineNotification ()) {
if (sse.MonoDebuggerInfo.HasNewTrampolineNotification) {
sse.enable_extended_notification (NotificationType.Trampoline);
sse.do_continue (CallSite.Address + CallSite.InstructionSize);
} else {
Expand All @@ -4476,7 +4527,7 @@ public override bool ResumeOperation ()

protected void TrampolineCompiled (TargetAddress mono_method, TargetAddress code)
{
if (sse.MonoDebuggerInfo.HasNewTrampolineNotification ()) {
if (sse.MonoDebuggerInfo.HasNewTrampolineNotification) {
sse.disable_extended_notification (NotificationType.Trampoline);
sse.remove_temporary_breakpoint ();
} else {
Expand Down
5 changes: 2 additions & 3 deletions backend/mono/MonoThreadManager.cs
Expand Up @@ -578,9 +578,8 @@ public bool CheckRuntimeVersion (int major, int minor)
return MinorVersion >= minor;
}

public bool HasNewTrampolineNotification ()
{
return CheckRuntimeVersion (80, 2) || CheckRuntimeVersion (81, 4);
public bool HasNewTrampolineNotification {
get { return CheckRuntimeVersion (80, 2) || CheckRuntimeVersion (81, 4); }
}

protected MonoDebuggerInfo (TargetMemoryAccess memory, TargetReader reader)
Expand Down
4 changes: 4 additions & 0 deletions classes/StackFrame.cs
Expand Up @@ -404,6 +404,10 @@ void compute_source ()
get { return exc_object; }
}

public bool IsManaged {
get { return (language != null) && language.IsManaged; }
}

internal void SetExceptionObject (TargetObject exc_object)
{
this.exc_object = exc_object;
Expand Down
2 changes: 2 additions & 0 deletions frontend/Expression.cs
Expand Up @@ -3070,6 +3070,8 @@ protected TargetObject DoInvoke (ScriptingContext context, bool debug)
} catch (TargetException ex) {
throw new ScriptingException (
"Invocation of `{0}' raised an exception: {1}", Name, ex.Message);
} catch (EvaluationTimeoutException ex) {
throw new ScriptingException ("Invocation of `{0}' timed out.", Name);
}
}

Expand Down

0 comments on commit bd96310

Please sign in to comment.