diff --git a/_fixtures/test.c b/_fixtures/test.c new file mode 100644 index 0000000000..0a472e3fa9 --- /dev/null +++ b/_fixtures/test.c @@ -0,0 +1,5 @@ +#include + +int main(void) { + printf("hello world!"); +} diff --git a/pkg/proc/target_group.go b/pkg/proc/target_group.go index b7976fa5fd..2f45a88221 100644 --- a/pkg/proc/target_group.go +++ b/pkg/proc/target_group.go @@ -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}, diff --git a/pkg/proc/test/support.go b/pkg/proc/test/support.go index 11abf9bab6..bd5086738f 100644 --- a/pkg/proc/test/support.go +++ b/pkg/proc/test/support.go @@ -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 { @@ -100,9 +107,6 @@ 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] == '/' { @@ -110,7 +114,7 @@ func BuildFixture(name string, flags BuildFlags) Fixture { 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 diff --git a/service/test/integration2_test.go b/service/test/integration2_test.go index be7b2646b2..39cb6683e3 100644 --- a/service/test/integration2_test.go +++ b/service/test/integration2_test.go @@ -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) + } +}