Skip to content

Commit

Permalink
proc: make sure logical breakpoints map exists (#3115)
Browse files Browse the repository at this point in the history
The logical breakpoints map was created as a side effect of
createUnrecoveredPanicBreakpoint or createFatalThrowBreakpoint, however
with an executable with incomplete debug info (that must be incomplete
in just the right way) both will fail and the logical breakpoint map
will never be created.

It's unknown how such an executable could be created, one easy way is
to debug a non-go executable.

Fixes #3114
  • Loading branch information
aarzilli committed Aug 22, 2022
1 parent dc76cc2 commit 8178152
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 4 deletions.
5 changes: 5 additions & 0 deletions _fixtures/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include <stdio.h>

int main(void) {
printf("hello world!");
}
3 changes: 3 additions & 0 deletions pkg/proc/target_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func NewGroup(t *Target) *TargetGroup {
panic("internal error: target is already part of a group")
}
t.partOfGroup = true
if t.Breakpoints().Logical == nil {
t.Breakpoints().Logical = make(map[int]*LogicalBreakpoint)
}
return &TargetGroup{
RecordingManipulation: t.recman,
targets: []*Target{t},
Expand Down
12 changes: 8 additions & 4 deletions pkg/proc/test/support.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ const (
LinkDisableDWARF
)

// TempFile makes a (good enough) random temporary file name
func TempFile(name string) string {
r := make([]byte, 4)
rand.Read(r)
return filepath.Join(os.TempDir(), fmt.Sprintf("%s.%s", name, hex.EncodeToString(r)))
}

// BuildFixture will compile the fixture 'name' using the provided build flags.
func BuildFixture(name string, flags BuildFlags) Fixture {
if !runningWithFixtures {
Expand All @@ -100,17 +107,14 @@ func BuildFixture(name string, flags BuildFlags) Fixture {

fixturesDir := FindFixturesDir()

// Make a (good enough) random temporary file name
r := make([]byte, 4)
rand.Read(r)
dir := fixturesDir
path := filepath.Join(fixturesDir, name+".go")
if name[len(name)-1] == '/' {
dir = filepath.Join(dir, name)
path = ""
name = name[:len(name)-1]
}
tmpfile := filepath.Join(os.TempDir(), fmt.Sprintf("%s.%s", name, hex.EncodeToString(r)))
tmpfile := TempFile(name)

buildFlags := []string{"build"}
var ver goversion.GoVersion
Expand Down
39 changes: 39 additions & 0 deletions service/test/integration2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2817,3 +2817,42 @@ func TestClientServer_SinglelineStringFormattedWithBigInts(t *testing.T) {
}
})
}

func TestNonGoDebug(t *testing.T) {
// Test that we can at least set breakpoints while debugging a non-go executable.
if runtime.GOOS != "linux" {
t.Skip()
}
dir := protest.FindFixturesDir()
path := protest.TempFile("testc")
cmd := exec.Command("cc", "-g", "-o", path, filepath.Join(dir, "test.c"))
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("Error compiling %s: %s\n%s", path, err, out)
}

listener, clientConn := service.ListenerPipe()
defer listener.Close()

server := rpccommon.NewServer(&service.Config{
Listener: listener,
ProcessArgs: []string{path},
Debugger: debugger.Config{
Backend: testBackend,
ExecuteKind: debugger.ExecutingExistingFile,
},
})

if err := server.Run(); err != nil {
t.Fatal(err)
}

client := rpc2.NewClientFromConn(clientConn)
defer func() {
client.Detach(true)
}()

_, err := client.CreateBreakpoint(&api.Breakpoint{FunctionName: "C.main", Line: -1})
if err != nil {
t.Fatal(err)
}
}

0 comments on commit 8178152

Please sign in to comment.