Skip to content

Commit

Permalink
Fix Remote AsyncBreak (#1399)
Browse files Browse the repository at this point in the history
5f6213c accidently broke async-break for gdb remote scenarios as we send "-exec-interrupt" for async-break instead of sending a 'kill SIGTRAP'.

This PR modifies the `IsAsyncBreakSignal` to return a newly created enum `AsyncBreakSignal`, and renames it to `GetAsyncBreakSignal`. `GetAsyncBreakSignal` will now return if it saw a `SIGINT`, `SIGTRAP`, or `None` if its an unknown signal related to async break or no signal was retrieved at all.

This will be used along with a new flag called `IsUsingExecInterrupt`, which will be set before `-exec-interrupt` is sent to the debugger.

`IsUsingExecInterrupt` will be reset when the engine resolves the `async-break` from the user (see DebuggedProcess.cs changes) or when we are resolving an internal async break (See Debugger.cs DoInternalBreakActions).

Resolves: #1382
  • Loading branch information
WardenGnaw authored May 9, 2023
1 parent c4ad01a commit f530168
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
26 changes: 20 additions & 6 deletions src/MICore/CommandFactories/MICommandFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ public enum ExceptionBreakpointStates
BreakThrown = 0x2
}

/// <summary>
/// The signals that are using for async-break.
/// None will be used for no signal or signals that are not listed in the enum
/// </summary>
public enum AsyncBreakSignal
{
None = 0,
SIGTRAP = 2,
SIGINT = 5
}

public abstract class MICommandFactory
{
protected Debugger _debugger;
Expand Down Expand Up @@ -652,19 +663,22 @@ public virtual bool SupportsFrameFormatting
get { return false; }
}

public virtual bool IsAsyncBreakSignal(Results results)
public virtual AsyncBreakSignal GetAsyncBreakSignal(Results results)
{
bool isAsyncBreak = false;

if (results.TryFindString("reason") == "signal-received")
{
if (results.TryFindString("signal-name") == "SIGTRAP")
string signalName = results.TryFindString("signal-name");
if (signalName == "SIGTRAP")
{
return MICore.AsyncBreakSignal.SIGTRAP;
}
else if (signalName == "SIGINT")
{
isAsyncBreak = true;
return MICore.AsyncBreakSignal.SIGINT;
}
}

return isAsyncBreak;
return MICore.AsyncBreakSignal.None;
}

public Results IsModuleLoad(string cmd)
Expand Down
15 changes: 12 additions & 3 deletions src/MICore/Debugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,9 @@ private async void OnStopped(Results results)
results = results.Add("frame", frameResult.Find("frame"));
}

bool fIsAsyncBreak = MICommandFactory.IsAsyncBreakSignal(results);
if (await DoInternalBreakActions(fIsAsyncBreak))
AsyncBreakSignal signal = MICommandFactory.GetAsyncBreakSignal(results);
bool isAsyncBreak = signal == AsyncBreakSignal.SIGTRAP || (IsUsingExecInterrupt && signal == AsyncBreakSignal.SIGINT);
if (await DoInternalBreakActions(isAsyncBreak))
{
return;
}
Expand Down Expand Up @@ -409,6 +410,8 @@ private async Task<bool> DoInternalBreakActions(bool fIsAsyncBreak)
{
CmdContinueAsync();
processContinued = true;
// Reset since this -exec-interrupt was for an internal breakpoint.
IsUsingExecInterrupt = false;
}

if (firstException != null)
Expand Down Expand Up @@ -591,7 +594,7 @@ internal bool IsLocalGdbTarget()
_launchOptions is LocalLaunchOptions && !IsLocalLaunchUsingServer());
}

private bool IsRemoteGdbTarget()
internal bool IsRemoteGdbTarget()
{
return MICommandFactory.Mode == MIMode.Gdb &&
(_launchOptions is PipeLaunchOptions || _launchOptions is UnixShellPortLaunchOptions ||
Expand All @@ -606,6 +609,11 @@ protected bool IsCoreDump
}
}

/// <summary>
/// Flag to indicate that '-exec-interrupt' was used for async-break scenarios.
/// </summary>
public bool IsUsingExecInterrupt { get; protected set; } = false;

public async Task<Results> CmdTerminate()
{
if (!_terminating)
Expand Down Expand Up @@ -749,6 +757,7 @@ public Task CmdBreakInternal()
}
}

IsUsingExecInterrupt = true;
var res = CmdAsync("-exec-interrupt", ResultClass.done);
return res.ContinueWith((t) =>
{
Expand Down
6 changes: 5 additions & 1 deletion src/MIDebugEngine/Engine.Impl/DebuggedProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1332,14 +1332,18 @@ private async Task HandleBreakModeEvent(ResultEventArgs results, BreakRequest br
else if (reason == "signal-received")
{
string name = results.Results.TryFindString("signal-name");
AsyncBreakSignal signal = MICommandFactory.GetAsyncBreakSignal(results.Results);
bool isAsyncBreak = signal == AsyncBreakSignal.SIGTRAP || (IsUsingExecInterrupt && signal == AsyncBreakSignal.SIGINT);
if ((name == "SIG32") || (name == "SIG33"))
{
// we are going to ignore these (Sigma) signals for now
CmdContinueAsyncConditional(breakRequest);
}
else if (MICommandFactory.IsAsyncBreakSignal(results.Results))
else if (isAsyncBreak)
{
_callback.OnAsyncBreakComplete(thread);
// Reset flag for real async break
IsUsingExecInterrupt = false;
}
else
{
Expand Down

0 comments on commit f530168

Please sign in to comment.