github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/runtime-lldb_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime_test 6 7 import ( 8 "internal/testenv" 9 "os" 10 "os/exec" 11 "path/filepath" 12 "runtime" 13 "strings" 14 "testing" 15 ) 16 17 var lldbPath string 18 19 func checkLldbPython(t *testing.T) { 20 cmd := exec.Command("lldb", "-P") 21 out, err := cmd.CombinedOutput() 22 if err != nil { 23 t.Skipf("skipping due to issue running lldb: %v\n%s", err, out) 24 } 25 lldbPath = strings.TrimSpace(string(out)) 26 27 cmd = exec.Command("/usr/bin/python2.7", "-c", "import sys;sys.path.append(sys.argv[1]);import lldb; print('go lldb python support')", lldbPath) 28 out, err = cmd.CombinedOutput() 29 30 if err != nil { 31 t.Skipf("skipping due to issue running python: %v\n%s", err, out) 32 } 33 if string(out) != "go lldb python support\n" { 34 t.Skipf("skipping due to lack of python lldb support: %s", out) 35 } 36 37 if runtime.GOOS == "darwin" { 38 // Try to see if we have debugging permissions. 39 cmd = exec.Command("/usr/sbin/DevToolsSecurity", "-status") 40 out, err = cmd.CombinedOutput() 41 if err != nil { 42 t.Skipf("DevToolsSecurity failed: %v", err) 43 } else if !strings.Contains(string(out), "enabled") { 44 t.Skip(string(out)) 45 } 46 cmd = exec.Command("/usr/bin/groups") 47 out, err = cmd.CombinedOutput() 48 if err != nil { 49 t.Skipf("groups failed: %v", err) 50 } else if !strings.Contains(string(out), "_developer") { 51 t.Skip("Not in _developer group") 52 } 53 } 54 } 55 56 const lldbHelloSource = ` 57 package main 58 import "fmt" 59 func main() { 60 mapvar := make(map[string]string,5) 61 mapvar["abc"] = "def" 62 mapvar["ghi"] = "jkl" 63 intvar := 42 64 ptrvar := &intvar 65 fmt.Println("hi") // line 10 66 _ = ptrvar 67 } 68 ` 69 70 const lldbScriptSource = ` 71 import sys 72 sys.path.append(sys.argv[1]) 73 import lldb 74 import os 75 76 TIMEOUT_SECS = 5 77 78 debugger = lldb.SBDebugger.Create() 79 debugger.SetAsync(True) 80 target = debugger.CreateTargetWithFileAndArch("a.exe", None) 81 if target: 82 print "Created target" 83 main_bp = target.BreakpointCreateByLocation("main.go", 10) 84 if main_bp: 85 print "Created breakpoint" 86 process = target.LaunchSimple(None, None, os.getcwd()) 87 if process: 88 print "Process launched" 89 listener = debugger.GetListener() 90 process.broadcaster.AddListener(listener, lldb.SBProcess.eBroadcastBitStateChanged) 91 while True: 92 event = lldb.SBEvent() 93 if listener.WaitForEvent(TIMEOUT_SECS, event): 94 if lldb.SBProcess.GetRestartedFromEvent(event): 95 continue 96 state = process.GetState() 97 if state in [lldb.eStateUnloaded, lldb.eStateLaunching, lldb.eStateRunning]: 98 continue 99 else: 100 print "Timeout launching" 101 break 102 if state == lldb.eStateStopped: 103 for t in process.threads: 104 if t.GetStopReason() == lldb.eStopReasonBreakpoint: 105 print "Hit breakpoint" 106 frame = t.GetFrameAtIndex(0) 107 if frame: 108 if frame.line_entry: 109 print "Stopped at %s:%d" % (frame.line_entry.file.basename, frame.line_entry.line) 110 if frame.function: 111 print "Stopped in %s" % (frame.function.name,) 112 var = frame.FindVariable('intvar') 113 if var: 114 print "intvar = %s" % (var.GetValue(),) 115 else: 116 print "no intvar" 117 else: 118 print "Process state", state 119 process.Destroy() 120 else: 121 print "Failed to create target a.exe" 122 123 lldb.SBDebugger.Destroy(debugger) 124 sys.exit() 125 ` 126 127 const expectedLldbOutput = `Created target 128 Created breakpoint 129 Process launched 130 Hit breakpoint 131 Stopped at main.go:10 132 Stopped in main.main 133 intvar = 42 134 ` 135 136 func TestLldbPython(t *testing.T) { 137 testenv.MustHaveGoBuild(t) 138 testenv.SkipFlaky(t, 31188) 139 140 checkLldbPython(t) 141 142 dir := t.TempDir() 143 144 src := filepath.Join(dir, "main.go") 145 err := os.WriteFile(src, []byte(lldbHelloSource), 0644) 146 if err != nil { 147 t.Fatalf("failed to create src file: %v", err) 148 } 149 150 mod := filepath.Join(dir, "go.mod") 151 err = os.WriteFile(mod, []byte("module lldbtest"), 0644) 152 if err != nil { 153 t.Fatalf("failed to create mod file: %v", err) 154 } 155 156 // As of 2018-07-17, lldb doesn't support compressed DWARF, so 157 // disable it for this test. 158 cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags=all=-N -l", "-ldflags=-compressdwarf=false", "-o", "a.exe") 159 cmd.Dir = dir 160 cmd.Env = append(os.Environ(), "GOPATH=") // issue 31100 161 out, err := cmd.CombinedOutput() 162 if err != nil { 163 t.Fatalf("building source %v\n%s", err, out) 164 } 165 166 src = filepath.Join(dir, "script.py") 167 err = os.WriteFile(src, []byte(lldbScriptSource), 0755) 168 if err != nil { 169 t.Fatalf("failed to create script: %v", err) 170 } 171 172 cmd = exec.Command("/usr/bin/python2.7", "script.py", lldbPath) 173 cmd.Dir = dir 174 got, _ := cmd.CombinedOutput() 175 176 if string(got) != expectedLldbOutput { 177 if strings.Contains(string(got), "Timeout launching") { 178 t.Skip("Timeout launching") 179 } 180 t.Fatalf("Unexpected lldb output:\n%s", got) 181 } 182 }