proc,service/dap,proc/gdbserial: fixes for debugserver --unmask-signals (#3541)

- fix TestRefreshCurThreadSelGAfterContinueOnceError and TestBadAccess
  to work when debugserver has --unmask-signals
- when a fatal signal is received while singlestepping delay its
  delivery until the subsequent continue, otherwise debugserver will get
  stuck completely (fixes TestNilPtrDerefInBreakInstr)
This commit is contained in:
Alessandro Arzilli 2023-10-30 17:19:23 +01:00 committed by GitHub
parent cde14a46f1
commit 2187c75fb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 4 deletions

@ -650,8 +650,20 @@ func (conn *gdbConn) step(th *gdbThread, tu *threadUpdater, ignoreFaultSignal bo
if ignoreFaultSignal { // we attempting to read the TLS, a fault here should be ignored
return nil
}
if conn.isDebugserver {
// For some reason trying to deliver a signal in vCont step makes
// debugserver lockup (no errors, it just gets stuck), store the signal
// to deliver it later with the vCont;c
th.sig = sig
return nil
}
case _SIGILL, _SIGBUS, _SIGFPE:
// propagate these signals to inferior immediately
if conn.isDebugserver {
// See comment above
th.sig = sig
return nil
}
// otherwise propagate these signals to inferior immediately
case interruptSignal, breakpointSignal, stopSignal:
return nil
case childSignal: // stop on debugserver but SIGCHLD on lldb-server/linux

@ -5044,7 +5044,13 @@ func TestRefreshCurThreadSelGAfterContinueOnceError(t *testing.T) {
setFileBreakpoint(p, t, fixture.Source, 4)
assertNoError(grp.Continue(), t, "Continue() (first)")
if grp.Continue() == nil {
t.Fatalf("Second continue did not return an error")
pc := currentPC(p, t)
f, l, fn := p.BinInfo().PCToLine(pc)
t.Logf("Second continue did not return an error %s:%d %#v", f, l, fn)
if fn != nil && fn.Name == "runtime.fatalpanic" {
// this is also ok, it just means this debugserver supports --unmask-signals and it's working as intented.
return
}
}
g := p.SelectedGoroutine()
if g.CurrentLoc.Line != 9 {

@ -4874,12 +4874,12 @@ func TestBadAccess(t *testing.T) {
expectStoppedOnError := func(errorPrefix string) {
t.Helper()
se := client.ExpectStoppedEvent(t)
if se.Body.ThreadId != 1 || se.Body.Reason != "exception" || se.Body.Description != "runtime error" || !strings.HasPrefix(se.Body.Text, errorPrefix) {
if se.Body.ThreadId != 1 || se.Body.Reason != "exception" || (se.Body.Description != "runtime error" && se.Body.Description != "panic") || !strings.Contains(se.Body.Text, errorPrefix) {
t.Errorf("\ngot %#v\nwant ThreadId=1 Reason=\"exception\" Description=\"runtime error\" Text=\"%s\"", se, errorPrefix)
}
client.ExceptionInfoRequest(1)
eInfo := client.ExpectExceptionInfoResponse(t)
if eInfo.Body.ExceptionId != "runtime error" || !strings.HasPrefix(eInfo.Body.Description, errorPrefix) {
if (eInfo.Body.ExceptionId != "runtime error" && eInfo.Body.ExceptionId != "panic") || !strings.Contains(eInfo.Body.Description, errorPrefix) {
t.Errorf("\ngot %#v\nwant ExceptionId=\"runtime error\" Text=\"%s\"", eInfo, errorPrefix)
}
}
@ -4888,6 +4888,13 @@ func TestBadAccess(t *testing.T) {
client.ExpectContinueResponse(t)
expectStoppedOnError("invalid memory address or nil pointer dereference")
client.StackTraceRequest(1, 0, 2)
st := client.ExpectStackTraceResponse(t)
if len(st.Body.StackFrames) > 0 && st.Body.StackFrames[0].Name == "runtime.fatalpanic" {
// this debugserver has --unmask-signals and it works correctly
return
}
client.NextRequest(1)
client.ExpectNextResponse(t)
expectStoppedOnError("invalid memory address or nil pointer dereference")