You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1158 lines
32 KiB

  1. // Copyright 2018 Google Inc. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // +build linux
  15. // Package server provides RPC access to a local program being debugged.
  16. // It is the remote end of the client implementation of the Program interface.
  17. package server
  18. //go:generate sh -c "m4 -P eval.m4 > eval.go"
  19. import (
  20. "bytes"
  21. "errors"
  22. "fmt"
  23. "os"
  24. "regexp"
  25. "strconv"
  26. "strings"
  27. "sync"
  28. "syscall"
  29. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug"
  30. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/arch"
  31. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf"
  32. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf"
  33. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/macho"
  34. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server/protocol"
  35. )
  36. type breakpoint struct {
  37. pc uint64
  38. origInstr [arch.MaxBreakpointSize]byte
  39. }
  40. type call struct {
  41. req, resp interface{}
  42. errc chan error
  43. }
  44. type Server struct {
  45. arch arch.Architecture
  46. executable string // Name of executable.
  47. dwarfData *dwarf.Data
  48. breakpointc chan call
  49. otherc chan call
  50. fc chan func() error
  51. ec chan error
  52. proc *os.Process
  53. procIsUp bool
  54. stoppedPid int
  55. stoppedRegs syscall.PtraceRegs
  56. topOfStackAddrs []uint64
  57. breakpoints map[uint64]breakpoint
  58. files []*file // Index == file descriptor.
  59. printer *Printer
  60. // goroutineStack reads the stack of a (non-running) goroutine.
  61. goroutineStack func(uint64) ([]debug.Frame, error)
  62. goroutineStackOnce sync.Once
  63. }
  64. // peek implements the Peeker interface required by the printer.
  65. func (s *Server) peek(offset uintptr, buf []byte) error {
  66. return s.ptracePeek(s.stoppedPid, offset, buf)
  67. }
  68. // New parses the executable and builds local data structures for answering requests.
  69. // It returns a Server ready to serve requests about the executable.
  70. func New(executable string) (*Server, error) {
  71. fd, err := os.Open(executable)
  72. if err != nil {
  73. return nil, err
  74. }
  75. defer fd.Close()
  76. architecture, dwarfData, err := loadExecutable(fd)
  77. if err != nil {
  78. return nil, err
  79. }
  80. srv := &Server{
  81. arch: *architecture,
  82. executable: executable,
  83. dwarfData: dwarfData,
  84. breakpointc: make(chan call),
  85. otherc: make(chan call),
  86. fc: make(chan func() error),
  87. ec: make(chan error),
  88. breakpoints: make(map[uint64]breakpoint),
  89. }
  90. srv.printer = NewPrinter(architecture, dwarfData, srv)
  91. go ptraceRun(srv.fc, srv.ec)
  92. go srv.loop()
  93. return srv, nil
  94. }
  95. func loadExecutable(f *os.File) (*arch.Architecture, *dwarf.Data, error) {
  96. // TODO: How do we detect NaCl?
  97. if obj, err := elf.NewFile(f); err == nil {
  98. dwarfData, err := obj.DWARF()
  99. if err != nil {
  100. return nil, nil, err
  101. }
  102. switch obj.Machine {
  103. case elf.EM_ARM:
  104. return &arch.ARM, dwarfData, nil
  105. case elf.EM_386:
  106. switch obj.Class {
  107. case elf.ELFCLASS32:
  108. return &arch.X86, dwarfData, nil
  109. case elf.ELFCLASS64:
  110. return &arch.AMD64, dwarfData, nil
  111. }
  112. case elf.EM_X86_64:
  113. return &arch.AMD64, dwarfData, nil
  114. }
  115. return nil, nil, fmt.Errorf("unrecognized ELF architecture")
  116. }
  117. if obj, err := macho.NewFile(f); err == nil {
  118. dwarfData, err := obj.DWARF()
  119. if err != nil {
  120. return nil, nil, err
  121. }
  122. /* TODO
  123. table, err := parseMachO(obj)
  124. if err != nil {
  125. return nil, nil, err
  126. }
  127. */
  128. switch obj.Cpu {
  129. case macho.Cpu386:
  130. return &arch.X86, dwarfData, nil
  131. case macho.CpuAmd64:
  132. return &arch.AMD64, dwarfData, nil
  133. }
  134. return nil, nil, fmt.Errorf("unrecognized Mach-O architecture")
  135. }
  136. return nil, nil, fmt.Errorf("unrecognized binary format")
  137. }
  138. func (s *Server) loop() {
  139. for {
  140. var c call
  141. select {
  142. case c = <-s.breakpointc:
  143. case c = <-s.otherc:
  144. }
  145. s.dispatch(c)
  146. }
  147. }
  148. func (s *Server) dispatch(c call) {
  149. switch req := c.req.(type) {
  150. case *protocol.BreakpointRequest:
  151. c.errc <- s.handleBreakpoint(req, c.resp.(*protocol.BreakpointResponse))
  152. case *protocol.BreakpointAtFunctionRequest:
  153. c.errc <- s.handleBreakpointAtFunction(req, c.resp.(*protocol.BreakpointResponse))
  154. case *protocol.BreakpointAtLineRequest:
  155. c.errc <- s.handleBreakpointAtLine(req, c.resp.(*protocol.BreakpointResponse))
  156. case *protocol.DeleteBreakpointsRequest:
  157. c.errc <- s.handleDeleteBreakpoints(req, c.resp.(*protocol.DeleteBreakpointsResponse))
  158. case *protocol.CloseRequest:
  159. c.errc <- s.handleClose(req, c.resp.(*protocol.CloseResponse))
  160. case *protocol.EvalRequest:
  161. c.errc <- s.handleEval(req, c.resp.(*protocol.EvalResponse))
  162. case *protocol.EvaluateRequest:
  163. c.errc <- s.handleEvaluate(req, c.resp.(*protocol.EvaluateResponse))
  164. case *protocol.FramesRequest:
  165. c.errc <- s.handleFrames(req, c.resp.(*protocol.FramesResponse))
  166. case *protocol.OpenRequest:
  167. c.errc <- s.handleOpen(req, c.resp.(*protocol.OpenResponse))
  168. case *protocol.ReadAtRequest:
  169. c.errc <- s.handleReadAt(req, c.resp.(*protocol.ReadAtResponse))
  170. case *protocol.ResumeRequest:
  171. c.errc <- s.handleResume(req, c.resp.(*protocol.ResumeResponse))
  172. case *protocol.RunRequest:
  173. c.errc <- s.handleRun(req, c.resp.(*protocol.RunResponse))
  174. case *protocol.VarByNameRequest:
  175. c.errc <- s.handleVarByName(req, c.resp.(*protocol.VarByNameResponse))
  176. case *protocol.ValueRequest:
  177. c.errc <- s.handleValue(req, c.resp.(*protocol.ValueResponse))
  178. case *protocol.MapElementRequest:
  179. c.errc <- s.handleMapElement(req, c.resp.(*protocol.MapElementResponse))
  180. case *protocol.GoroutinesRequest:
  181. c.errc <- s.handleGoroutines(req, c.resp.(*protocol.GoroutinesResponse))
  182. default:
  183. panic(fmt.Sprintf("unexpected call request type %T", c.req))
  184. }
  185. }
  186. func (s *Server) call(c chan call, req, resp interface{}) error {
  187. errc := make(chan error)
  188. c <- call{req, resp, errc}
  189. return <-errc
  190. }
  191. type file struct {
  192. mode string
  193. index int
  194. f debug.File
  195. }
  196. func (s *Server) Open(req *protocol.OpenRequest, resp *protocol.OpenResponse) error {
  197. return s.call(s.otherc, req, resp)
  198. }
  199. func (s *Server) handleOpen(req *protocol.OpenRequest, resp *protocol.OpenResponse) error {
  200. // TODO: Better simulation. For now we just open the named OS file.
  201. var flag int
  202. switch req.Mode {
  203. case "r":
  204. flag = os.O_RDONLY
  205. case "w":
  206. flag = os.O_WRONLY
  207. case "rw":
  208. flag = os.O_RDWR
  209. default:
  210. return fmt.Errorf("Open: bad open mode %q", req.Mode)
  211. }
  212. osFile, err := os.OpenFile(req.Name, flag, 0)
  213. if err != nil {
  214. return err
  215. }
  216. // Find a file descriptor (index) slot.
  217. index := 0
  218. for ; index < len(s.files) && s.files[index] != nil; index++ {
  219. }
  220. f := &file{
  221. mode: req.Mode,
  222. index: index,
  223. f: osFile,
  224. }
  225. if index == len(s.files) {
  226. s.files = append(s.files, f)
  227. } else {
  228. s.files[index] = f
  229. }
  230. return nil
  231. }
  232. func (s *Server) ReadAt(req *protocol.ReadAtRequest, resp *protocol.ReadAtResponse) error {
  233. return s.call(s.otherc, req, resp)
  234. }
  235. func (s *Server) handleReadAt(req *protocol.ReadAtRequest, resp *protocol.ReadAtResponse) error {
  236. fd := req.FD
  237. if fd < 0 || len(s.files) <= fd || s.files[fd] == nil {
  238. return fmt.Errorf("ReadAt: bad file descriptor %d", fd)
  239. }
  240. f := s.files[fd]
  241. buf := make([]byte, req.Len) // TODO: Don't allocate every time
  242. n, err := f.f.ReadAt(buf, req.Offset)
  243. resp.Data = buf[:n]
  244. return err
  245. }
  246. func (s *Server) Close(req *protocol.CloseRequest, resp *protocol.CloseResponse) error {
  247. return s.call(s.otherc, req, resp)
  248. }
  249. func (s *Server) handleClose(req *protocol.CloseRequest, resp *protocol.CloseResponse) error {
  250. fd := req.FD
  251. if fd < 0 || fd >= len(s.files) || s.files[fd] == nil {
  252. return fmt.Errorf("Close: bad file descriptor %d", fd)
  253. }
  254. err := s.files[fd].f.Close()
  255. // Remove it regardless
  256. s.files[fd] = nil
  257. return err
  258. }
  259. func (s *Server) Run(req *protocol.RunRequest, resp *protocol.RunResponse) error {
  260. return s.call(s.otherc, req, resp)
  261. }
  262. func (s *Server) handleRun(req *protocol.RunRequest, resp *protocol.RunResponse) error {
  263. if s.proc != nil {
  264. s.proc.Kill()
  265. s.proc = nil
  266. s.procIsUp = false
  267. s.stoppedPid = 0
  268. s.stoppedRegs = syscall.PtraceRegs{}
  269. s.topOfStackAddrs = nil
  270. }
  271. argv := append([]string{s.executable}, req.Args...)
  272. p, err := s.startProcess(s.executable, argv, &os.ProcAttr{
  273. Files: []*os.File{
  274. nil, // TODO: be able to feed the target's stdin.
  275. os.Stderr, // TODO: be able to capture the target's stdout.
  276. os.Stderr,
  277. },
  278. Sys: &syscall.SysProcAttr{
  279. Pdeathsig: syscall.SIGKILL,
  280. Ptrace: true,
  281. },
  282. })
  283. if err != nil {
  284. return err
  285. }
  286. s.proc = p
  287. s.stoppedPid = p.Pid
  288. return nil
  289. }
  290. func (s *Server) Resume(req *protocol.ResumeRequest, resp *protocol.ResumeResponse) error {
  291. return s.call(s.otherc, req, resp)
  292. }
  293. func (s *Server) handleResume(req *protocol.ResumeRequest, resp *protocol.ResumeResponse) error {
  294. if s.proc == nil {
  295. return fmt.Errorf("Resume: Run did not successfully start a process")
  296. }
  297. if !s.procIsUp {
  298. s.procIsUp = true
  299. if _, err := s.waitForTrap(s.stoppedPid, false); err != nil {
  300. return err
  301. }
  302. if err := s.ptraceSetOptions(s.stoppedPid, syscall.PTRACE_O_TRACECLONE); err != nil {
  303. return fmt.Errorf("ptraceSetOptions: %v", err)
  304. }
  305. } else if _, ok := s.breakpoints[s.stoppedRegs.Rip]; ok {
  306. if err := s.ptraceSingleStep(s.stoppedPid); err != nil {
  307. return fmt.Errorf("ptraceSingleStep: %v", err)
  308. }
  309. if _, err := s.waitForTrap(s.stoppedPid, false); err != nil {
  310. return err
  311. }
  312. }
  313. for {
  314. if err := s.setBreakpoints(); err != nil {
  315. return err
  316. }
  317. if err := s.ptraceCont(s.stoppedPid, 0); err != nil {
  318. return fmt.Errorf("ptraceCont: %v", err)
  319. }
  320. wpid, err := s.waitForTrap(-1, true)
  321. if err == nil {
  322. s.stoppedPid = wpid
  323. break
  324. }
  325. bce, ok := err.(*breakpointsChangedError)
  326. if !ok {
  327. return err
  328. }
  329. if err := syscall.Kill(s.stoppedPid, syscall.SIGSTOP); err != nil {
  330. return fmt.Errorf("kill(SIGSTOP): %v", err)
  331. }
  332. _, status, err := s.wait(s.stoppedPid, false)
  333. if err != nil {
  334. return fmt.Errorf("wait (after SIGSTOP): %v", err)
  335. }
  336. if !status.Stopped() || status.StopSignal() != syscall.SIGSTOP {
  337. return fmt.Errorf("wait (after SIGSTOP): unexpected wait status 0x%x", status)
  338. }
  339. if err := s.liftBreakpoints(); err != nil {
  340. return err
  341. }
  342. loop:
  343. for c := bce.call; ; {
  344. s.dispatch(c)
  345. select {
  346. case c = <-s.breakpointc:
  347. default:
  348. break loop
  349. }
  350. }
  351. }
  352. if err := s.liftBreakpoints(); err != nil {
  353. return err
  354. }
  355. if err := s.ptraceGetRegs(s.stoppedPid, &s.stoppedRegs); err != nil {
  356. return fmt.Errorf("ptraceGetRegs: %v", err)
  357. }
  358. s.stoppedRegs.Rip -= uint64(s.arch.BreakpointSize)
  359. if err := s.ptraceSetRegs(s.stoppedPid, &s.stoppedRegs); err != nil {
  360. return fmt.Errorf("ptraceSetRegs: %v", err)
  361. }
  362. resp.Status.PC = s.stoppedRegs.Rip
  363. resp.Status.SP = s.stoppedRegs.Rsp
  364. return nil
  365. }
  366. func (s *Server) waitForTrap(pid int, allowBreakpointsChange bool) (wpid int, err error) {
  367. for {
  368. wpid, status, err := s.wait(pid, allowBreakpointsChange)
  369. if err != nil {
  370. if _, ok := err.(*breakpointsChangedError); !ok {
  371. err = fmt.Errorf("wait: %v", err)
  372. }
  373. return 0, err
  374. }
  375. if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != syscall.PTRACE_EVENT_CLONE {
  376. return wpid, nil
  377. }
  378. if status.StopSignal() == syscall.SIGPROF {
  379. err = s.ptraceCont(wpid, int(syscall.SIGPROF))
  380. } else {
  381. err = s.ptraceCont(wpid, 0) // TODO: non-zero when wait catches other signals?
  382. }
  383. if err != nil {
  384. return 0, fmt.Errorf("ptraceCont: %v", err)
  385. }
  386. }
  387. }
  388. func (s *Server) Breakpoint(req *protocol.BreakpointRequest, resp *protocol.BreakpointResponse) error {
  389. return s.call(s.breakpointc, req, resp)
  390. }
  391. func (s *Server) handleBreakpoint(req *protocol.BreakpointRequest, resp *protocol.BreakpointResponse) error {
  392. return s.addBreakpoints([]uint64{req.Address}, resp)
  393. }
  394. func (s *Server) BreakpointAtFunction(req *protocol.BreakpointAtFunctionRequest, resp *protocol.BreakpointResponse) error {
  395. return s.call(s.breakpointc, req, resp)
  396. }
  397. func (s *Server) handleBreakpointAtFunction(req *protocol.BreakpointAtFunctionRequest, resp *protocol.BreakpointResponse) error {
  398. pc, err := s.functionStartAddress(req.Function)
  399. if err != nil {
  400. return err
  401. }
  402. return s.addBreakpoints([]uint64{pc}, resp)
  403. }
  404. func (s *Server) BreakpointAtLine(req *protocol.BreakpointAtLineRequest, resp *protocol.BreakpointResponse) error {
  405. return s.call(s.breakpointc, req, resp)
  406. }
  407. func (s *Server) handleBreakpointAtLine(req *protocol.BreakpointAtLineRequest, resp *protocol.BreakpointResponse) error {
  408. if s.dwarfData == nil {
  409. return fmt.Errorf("no DWARF data")
  410. }
  411. if pcs, err := s.dwarfData.LineToBreakpointPCs(req.File, req.Line); err != nil {
  412. return err
  413. } else {
  414. return s.addBreakpoints(pcs, resp)
  415. }
  416. }
  417. // addBreakpoints adds breakpoints at the addresses in pcs, then stores pcs in the response.
  418. func (s *Server) addBreakpoints(pcs []uint64, resp *protocol.BreakpointResponse) error {
  419. // Get the original code at each address with ptracePeek.
  420. bps := make([]breakpoint, 0, len(pcs))
  421. for _, pc := range pcs {
  422. if _, alreadySet := s.breakpoints[pc]; alreadySet {
  423. continue
  424. }
  425. var bp breakpoint
  426. if err := s.ptracePeek(s.stoppedPid, uintptr(pc), bp.origInstr[:s.arch.BreakpointSize]); err != nil {
  427. return fmt.Errorf("ptracePeek: %v", err)
  428. }
  429. bp.pc = pc
  430. bps = append(bps, bp)
  431. }
  432. // If all the peeks succeeded, update the list of breakpoints.
  433. for _, bp := range bps {
  434. s.breakpoints[bp.pc] = bp
  435. }
  436. resp.PCs = pcs
  437. return nil
  438. }
  439. func (s *Server) DeleteBreakpoints(req *protocol.DeleteBreakpointsRequest, resp *protocol.DeleteBreakpointsResponse) error {
  440. return s.call(s.breakpointc, req, resp)
  441. }
  442. func (s *Server) handleDeleteBreakpoints(req *protocol.DeleteBreakpointsRequest, resp *protocol.DeleteBreakpointsResponse) error {
  443. for _, pc := range req.PCs {
  444. delete(s.breakpoints, pc)
  445. }
  446. return nil
  447. }
  448. func (s *Server) setBreakpoints() error {
  449. for pc := range s.breakpoints {
  450. err := s.ptracePoke(s.stoppedPid, uintptr(pc), s.arch.BreakpointInstr[:s.arch.BreakpointSize])
  451. if err != nil {
  452. return fmt.Errorf("setBreakpoints: %v", err)
  453. }
  454. }
  455. return nil
  456. }
  457. func (s *Server) liftBreakpoints() error {
  458. for pc, breakpoint := range s.breakpoints {
  459. err := s.ptracePoke(s.stoppedPid, uintptr(pc), breakpoint.origInstr[:s.arch.BreakpointSize])
  460. if err != nil {
  461. return fmt.Errorf("liftBreakpoints: %v", err)
  462. }
  463. }
  464. return nil
  465. }
  466. func (s *Server) Eval(req *protocol.EvalRequest, resp *protocol.EvalResponse) error {
  467. return s.call(s.otherc, req, resp)
  468. }
  469. func (s *Server) handleEval(req *protocol.EvalRequest, resp *protocol.EvalResponse) (err error) {
  470. resp.Result, err = s.eval(req.Expr)
  471. return err
  472. }
  473. // eval evaluates an expression.
  474. // TODO: very weak.
  475. func (s *Server) eval(expr string) ([]string, error) {
  476. switch {
  477. case strings.HasPrefix(expr, "re:"):
  478. // Regular expression. Return list of symbols.
  479. re, err := regexp.Compile(expr[3:])
  480. if err != nil {
  481. return nil, err
  482. }
  483. return s.dwarfData.LookupMatchingSymbols(re)
  484. case strings.HasPrefix(expr, "addr:"):
  485. // Symbol lookup. Return address.
  486. addr, err := s.functionStartAddress(expr[5:])
  487. if err != nil {
  488. return nil, err
  489. }
  490. return []string{fmt.Sprintf("%#x", addr)}, nil
  491. case strings.HasPrefix(expr, "val:"):
  492. // Symbol lookup. Return formatted value.
  493. value, err := s.printer.Sprint(expr[4:])
  494. if err != nil {
  495. return nil, err
  496. }
  497. return []string{value}, nil
  498. case strings.HasPrefix(expr, "src:"):
  499. // Numerical address. Return file.go:123.
  500. addr, err := strconv.ParseUint(expr[4:], 0, 0)
  501. if err != nil {
  502. return nil, err
  503. }
  504. file, line, err := s.lookupSource(addr)
  505. if err != nil {
  506. return nil, err
  507. }
  508. return []string{fmt.Sprintf("%s:%d", file, line)}, nil
  509. case len(expr) > 0 && '0' <= expr[0] && expr[0] <= '9':
  510. // Numerical address. Return symbol.
  511. addr, err := strconv.ParseUint(expr, 0, 0)
  512. if err != nil {
  513. return nil, err
  514. }
  515. entry, _, err := s.dwarfData.PCToFunction(addr)
  516. if err != nil {
  517. return nil, err
  518. }
  519. name, ok := entry.Val(dwarf.AttrName).(string)
  520. if !ok {
  521. return nil, fmt.Errorf("function at 0x%x has no name", addr)
  522. }
  523. return []string{name}, nil
  524. }
  525. return nil, fmt.Errorf("bad expression syntax: %q", expr)
  526. }
  527. func (s *Server) Evaluate(req *protocol.EvaluateRequest, resp *protocol.EvaluateResponse) error {
  528. return s.call(s.otherc, req, resp)
  529. }
  530. func (s *Server) handleEvaluate(req *protocol.EvaluateRequest, resp *protocol.EvaluateResponse) (err error) {
  531. resp.Result, err = s.evalExpression(req.Expression, s.stoppedRegs.Rip, s.stoppedRegs.Rsp)
  532. return err
  533. }
  534. func (s *Server) lookupSource(pc uint64) (file string, line uint64, err error) {
  535. if s.dwarfData == nil {
  536. return
  537. }
  538. // TODO: The gosym equivalent also returns the relevant Func. Do that when
  539. // DWARF has the same facility.
  540. return s.dwarfData.PCToLine(pc)
  541. }
  542. func (s *Server) Frames(req *protocol.FramesRequest, resp *protocol.FramesResponse) error {
  543. return s.call(s.otherc, req, resp)
  544. }
  545. func (s *Server) handleFrames(req *protocol.FramesRequest, resp *protocol.FramesResponse) error {
  546. // TODO: verify that we're stopped.
  547. if s.topOfStackAddrs == nil {
  548. if err := s.evaluateTopOfStackAddrs(); err != nil {
  549. return err
  550. }
  551. }
  552. regs := syscall.PtraceRegs{}
  553. err := s.ptraceGetRegs(s.stoppedPid, &regs)
  554. if err != nil {
  555. return err
  556. }
  557. resp.Frames, err = s.walkStack(regs.Rip, regs.Rsp, req.Count)
  558. return err
  559. }
  560. // walkStack returns up to the requested number of stack frames.
  561. func (s *Server) walkStack(pc, sp uint64, count int) ([]debug.Frame, error) {
  562. var frames []debug.Frame
  563. var buf [8]byte
  564. b := new(bytes.Buffer)
  565. r := s.dwarfData.Reader()
  566. // TODO: handle walking over a split stack.
  567. for i := 0; i < count; i++ {
  568. b.Reset()
  569. file, line, err := s.dwarfData.PCToLine(pc)
  570. if err != nil {
  571. return frames, err
  572. }
  573. fpOffset, err := s.dwarfData.PCToSPOffset(pc)
  574. if err != nil {
  575. return frames, err
  576. }
  577. fp := sp + uint64(fpOffset)
  578. entry, funcEntry, err := s.dwarfData.PCToFunction(pc)
  579. if err != nil {
  580. return frames, err
  581. }
  582. frame := debug.Frame{
  583. PC: pc,
  584. SP: sp,
  585. File: file,
  586. Line: line,
  587. FunctionStart: funcEntry,
  588. }
  589. frame.Function, _ = entry.Val(dwarf.AttrName).(string)
  590. r.Seek(entry.Offset)
  591. for {
  592. entry, err := r.Next()
  593. if err != nil {
  594. return frames, err
  595. }
  596. if entry.Tag == 0 {
  597. break
  598. }
  599. // TODO: report variables we couldn't parse?
  600. if entry.Tag == dwarf.TagFormalParameter {
  601. if v, err := s.parseParameterOrLocal(entry, fp); err == nil {
  602. frame.Params = append(frame.Params, debug.Param(v))
  603. }
  604. }
  605. if entry.Tag == dwarf.TagVariable {
  606. if v, err := s.parseParameterOrLocal(entry, fp); err == nil {
  607. frame.Vars = append(frame.Vars, v)
  608. }
  609. }
  610. }
  611. frames = append(frames, frame)
  612. // Walk to the caller's PC and SP.
  613. if s.topOfStack(funcEntry) {
  614. break
  615. }
  616. err = s.ptracePeek(s.stoppedPid, uintptr(fp-uint64(s.arch.PointerSize)), buf[:s.arch.PointerSize])
  617. if err != nil {
  618. return frames, fmt.Errorf("ptracePeek: %v", err)
  619. }
  620. pc, sp = s.arch.Uintptr(buf[:s.arch.PointerSize]), fp
  621. }
  622. return frames, nil
  623. }
  624. // parseParameterOrLocal parses the entry for a function parameter or local
  625. // variable, which are both specified the same way. fp contains the frame
  626. // pointer, which is used to calculate the variable location.
  627. func (s *Server) parseParameterOrLocal(entry *dwarf.Entry, fp uint64) (debug.LocalVar, error) {
  628. var v debug.LocalVar
  629. v.Name, _ = entry.Val(dwarf.AttrName).(string)
  630. if off, err := s.dwarfData.EntryTypeOffset(entry); err != nil {
  631. return v, err
  632. } else {
  633. v.Var.TypeID = uint64(off)
  634. }
  635. if i := entry.Val(dwarf.AttrLocation); i == nil {
  636. return v, fmt.Errorf("missing location description")
  637. } else if locationDescription, ok := i.([]uint8); !ok {
  638. return v, fmt.Errorf("unsupported location description")
  639. } else if offset, err := evalLocation(locationDescription); err != nil {
  640. return v, err
  641. } else {
  642. v.Var.Address = fp + uint64(offset)
  643. }
  644. return v, nil
  645. }
  646. func (s *Server) evaluateTopOfStackAddrs() error {
  647. var (
  648. lookup func(name string) (uint64, error)
  649. indirect bool
  650. names []string
  651. )
  652. if _, err := s.dwarfData.LookupVariable("runtime.rt0_goPC"); err != nil {
  653. // Look for a Go 1.3 binary (or earlier version).
  654. lookup, indirect, names = s.functionStartAddress, false, []string{
  655. "runtime.goexit",
  656. "runtime.mstart",
  657. "runtime.mcall",
  658. "runtime.morestack",
  659. "runtime.lessstack",
  660. "_rt0_go",
  661. }
  662. } else {
  663. // Look for a Go 1.4 binary (or later version).
  664. lookup = func(name string) (uint64, error) {
  665. entry, err := s.dwarfData.LookupVariable(name)
  666. if err != nil {
  667. return 0, err
  668. }
  669. return s.dwarfData.EntryLocation(entry)
  670. }
  671. indirect, names = true, []string{
  672. "runtime.goexitPC",
  673. "runtime.mstartPC",
  674. "runtime.mcallPC",
  675. "runtime.morestackPC",
  676. "runtime.rt0_goPC",
  677. }
  678. }
  679. // TODO: also look for runtime.externalthreadhandlerp, on Windows.
  680. addrs := make([]uint64, 0, len(names))
  681. for _, name := range names {
  682. addr, err := lookup(name)
  683. if err != nil {
  684. return err
  685. }
  686. addrs = append(addrs, addr)
  687. }
  688. if indirect {
  689. buf := make([]byte, s.arch.PointerSize)
  690. for i, addr := range addrs {
  691. if err := s.ptracePeek(s.stoppedPid, uintptr(addr), buf); err != nil {
  692. return fmt.Errorf("ptracePeek: %v", err)
  693. }
  694. addrs[i] = s.arch.Uintptr(buf)
  695. }
  696. }
  697. s.topOfStackAddrs = addrs
  698. return nil
  699. }
  700. // topOfStack is the out-of-process equivalent of runtime·topofstack.
  701. func (s *Server) topOfStack(funcEntry uint64) bool {
  702. for _, addr := range s.topOfStackAddrs {
  703. if addr == funcEntry {
  704. return true
  705. }
  706. }
  707. return false
  708. }
  709. func (s *Server) VarByName(req *protocol.VarByNameRequest, resp *protocol.VarByNameResponse) error {
  710. return s.call(s.otherc, req, resp)
  711. }
  712. func (s *Server) handleVarByName(req *protocol.VarByNameRequest, resp *protocol.VarByNameResponse) error {
  713. entry, err := s.dwarfData.LookupVariable(req.Name)
  714. if err != nil {
  715. return fmt.Errorf("variable %s: %s", req.Name, err)
  716. }
  717. loc, err := s.dwarfData.EntryLocation(entry)
  718. if err != nil {
  719. return fmt.Errorf("variable %s: %s", req.Name, err)
  720. }
  721. off, err := s.dwarfData.EntryTypeOffset(entry)
  722. if err != nil {
  723. return fmt.Errorf("variable %s: %s", req.Name, err)
  724. }
  725. resp.Var.TypeID = uint64(off)
  726. resp.Var.Address = loc
  727. return nil
  728. }
  729. func (s *Server) Value(req *protocol.ValueRequest, resp *protocol.ValueResponse) error {
  730. return s.call(s.otherc, req, resp)
  731. }
  732. func (s *Server) handleValue(req *protocol.ValueRequest, resp *protocol.ValueResponse) error {
  733. t, err := s.dwarfData.Type(dwarf.Offset(req.Var.TypeID))
  734. if err != nil {
  735. return err
  736. }
  737. resp.Value, err = s.value(t, req.Var.Address)
  738. return err
  739. }
  740. func (s *Server) MapElement(req *protocol.MapElementRequest, resp *protocol.MapElementResponse) error {
  741. return s.call(s.otherc, req, resp)
  742. }
  743. func (s *Server) handleMapElement(req *protocol.MapElementRequest, resp *protocol.MapElementResponse) error {
  744. t, err := s.dwarfData.Type(dwarf.Offset(req.Map.TypeID))
  745. if err != nil {
  746. return err
  747. }
  748. m, ok := t.(*dwarf.MapType)
  749. if !ok {
  750. return fmt.Errorf("variable is not a map")
  751. }
  752. var count uint64
  753. // fn will be called for each element of the map.
  754. // When we reach the requested element, we fill in *resp and stop.
  755. // TODO: cache locations of elements.
  756. fn := func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool {
  757. count++
  758. if count == req.Index+1 {
  759. resp.Key = debug.Var{TypeID: uint64(keyType.Common().Offset), Address: keyAddr}
  760. resp.Value = debug.Var{TypeID: uint64(valType.Common().Offset), Address: valAddr}
  761. return false
  762. }
  763. return true
  764. }
  765. if err := s.peekMapValues(m, req.Map.Address, fn); err != nil {
  766. return err
  767. }
  768. if count <= req.Index {
  769. // There weren't enough elements.
  770. return fmt.Errorf("map has no element %d", req.Index)
  771. }
  772. return nil
  773. }
  774. func (s *Server) Goroutines(req *protocol.GoroutinesRequest, resp *protocol.GoroutinesResponse) error {
  775. return s.call(s.otherc, req, resp)
  776. }
  777. const invalidStatus debug.GoroutineStatus = 99
  778. var (
  779. gStatus = [...]debug.GoroutineStatus{
  780. 0: debug.Queued, // _Gidle
  781. 1: debug.Queued, // _Grunnable
  782. 2: debug.Running, // _Grunning
  783. 3: debug.Blocked, // _Gsyscall
  784. 4: debug.Blocked, // _Gwaiting
  785. 5: invalidStatus, // _Gmoribund_unused
  786. 6: invalidStatus, // _Gdead
  787. 7: invalidStatus, // _Genqueue
  788. 8: debug.Running, // _Gcopystack
  789. }
  790. gScanStatus = [...]debug.GoroutineStatus{
  791. 0: invalidStatus, // _Gscan + _Gidle
  792. 1: debug.Queued, // _Gscanrunnable
  793. 2: debug.Running, // _Gscanrunning
  794. 3: debug.Blocked, // _Gscansyscall
  795. 4: debug.Blocked, // _Gscanwaiting
  796. 5: invalidStatus, // _Gscan + _Gmoribund_unused
  797. 6: invalidStatus, // _Gscan + _Gdead
  798. 7: debug.Queued, // _Gscanenqueue
  799. }
  800. gStatusString = [...]string{
  801. 0: "idle",
  802. 1: "runnable",
  803. 2: "running",
  804. 3: "syscall",
  805. 4: "waiting",
  806. 8: "copystack",
  807. }
  808. gScanStatusString = [...]string{
  809. 1: "scanrunnable",
  810. 2: "scanrunning",
  811. 3: "scansyscall",
  812. 4: "scanwaiting",
  813. 7: "scanenqueue",
  814. }
  815. )
  816. func (s *Server) handleGoroutines(req *protocol.GoroutinesRequest, resp *protocol.GoroutinesResponse) error {
  817. // Get DWARF type information for runtime.g.
  818. ge, err := s.dwarfData.LookupEntry("runtime.g")
  819. if err != nil {
  820. return err
  821. }
  822. t, err := s.dwarfData.Type(ge.Offset)
  823. if err != nil {
  824. return err
  825. }
  826. gType, ok := followTypedefs(t).(*dwarf.StructType)
  827. if !ok {
  828. return errors.New("runtime.g is not a struct")
  829. }
  830. var (
  831. allgPtr, allgLen uint64
  832. allgPtrOk bool
  833. )
  834. for {
  835. // Try to read the slice runtime.allgs.
  836. allgsEntry, err := s.dwarfData.LookupVariable("runtime.allgs")
  837. if err != nil {
  838. break
  839. }
  840. allgsAddr, err := s.dwarfData.EntryLocation(allgsEntry)
  841. if err != nil {
  842. break
  843. }
  844. off, err := s.dwarfData.EntryTypeOffset(allgsEntry)
  845. if err != nil {
  846. break
  847. }
  848. t, err := s.dwarfData.Type(off)
  849. if err != nil {
  850. break
  851. }
  852. allgsType, ok := followTypedefs(t).(*dwarf.SliceType)
  853. if !ok {
  854. break
  855. }
  856. allgs, err := s.peekSlice(allgsType, allgsAddr)
  857. if err != nil {
  858. break
  859. }
  860. allgPtr, allgLen, allgPtrOk = allgs.Address, allgs.Length, true
  861. break
  862. }
  863. if !allgPtrOk {
  864. // Read runtime.allg.
  865. allgEntry, err := s.dwarfData.LookupVariable("runtime.allg")
  866. if err != nil {
  867. return err
  868. }
  869. allgAddr, err := s.dwarfData.EntryLocation(allgEntry)
  870. if err != nil {
  871. return err
  872. }
  873. allgPtr, err = s.peekPtr(allgAddr)
  874. if err != nil {
  875. return fmt.Errorf("reading allg: %v", err)
  876. }
  877. // Read runtime.allglen.
  878. allglenEntry, err := s.dwarfData.LookupVariable("runtime.allglen")
  879. if err != nil {
  880. return err
  881. }
  882. off, err := s.dwarfData.EntryTypeOffset(allglenEntry)
  883. if err != nil {
  884. return err
  885. }
  886. allglenType, err := s.dwarfData.Type(off)
  887. if err != nil {
  888. return err
  889. }
  890. allglenAddr, err := s.dwarfData.EntryLocation(allglenEntry)
  891. if err != nil {
  892. return err
  893. }
  894. switch followTypedefs(allglenType).(type) {
  895. case *dwarf.UintType, *dwarf.IntType:
  896. allgLen, err = s.peekUint(allglenAddr, allglenType.Common().ByteSize)
  897. if err != nil {
  898. return fmt.Errorf("reading allglen: %v", err)
  899. }
  900. default:
  901. // Some runtimes don't specify the type for allglen. Assume it's uint32.
  902. allgLen, err = s.peekUint(allglenAddr, 4)
  903. if err != nil {
  904. return fmt.Errorf("reading allglen: %v", err)
  905. }
  906. if allgLen != 0 {
  907. break
  908. }
  909. // Zero? Let's try uint64.
  910. allgLen, err = s.peekUint(allglenAddr, 8)
  911. if err != nil {
  912. return fmt.Errorf("reading allglen: %v", err)
  913. }
  914. }
  915. }
  916. // Initialize s.goroutineStack.
  917. s.goroutineStackOnce.Do(func() { s.goroutineStackInit(gType) })
  918. for i := uint64(0); i < allgLen; i++ {
  919. // allg is an array of pointers to g structs. Read allg[i].
  920. g, err := s.peekPtr(allgPtr + i*uint64(s.arch.PointerSize))
  921. if err != nil {
  922. return err
  923. }
  924. gr := debug.Goroutine{}
  925. // Read status from the field named "atomicstatus" or "status".
  926. status, err := s.peekUintStructField(gType, g, "atomicstatus")
  927. if err != nil {
  928. status, err = s.peekUintOrIntStructField(gType, g, "status")
  929. }
  930. if err != nil {
  931. return err
  932. }
  933. if status == 6 {
  934. // _Gdead.
  935. continue
  936. }
  937. gr.Status = invalidStatus
  938. if status < uint64(len(gStatus)) {
  939. gr.Status = gStatus[status]
  940. gr.StatusString = gStatusString[status]
  941. } else if status^0x1000 < uint64(len(gScanStatus)) {
  942. gr.Status = gScanStatus[status^0x1000]
  943. gr.StatusString = gScanStatusString[status^0x1000]
  944. }
  945. if gr.Status == invalidStatus {
  946. return fmt.Errorf("unexpected goroutine status 0x%x", status)
  947. }
  948. if status == 4 || status == 0x1004 {
  949. // _Gwaiting or _Gscanwaiting.
  950. // Try reading waitreason to get a better value for StatusString.
  951. // Depending on the runtime, waitreason may be a Go string or a C string.
  952. if waitreason, err := s.peekStringStructField(gType, g, "waitreason", 80); err == nil {
  953. if waitreason != "" {
  954. gr.StatusString = waitreason
  955. }
  956. } else if ptr, err := s.peekPtrStructField(gType, g, "waitreason"); err == nil {
  957. waitreason := s.peekCString(ptr, 80)
  958. if waitreason != "" {
  959. gr.StatusString = waitreason
  960. }
  961. }
  962. }
  963. gr.ID, err = s.peekIntStructField(gType, g, "goid")
  964. if err != nil {
  965. return err
  966. }
  967. // Best-effort attempt to get the names of the goroutine function and the
  968. // function that created the goroutine. They aren't always available.
  969. functionName := func(pc uint64) string {
  970. entry, _, err := s.dwarfData.PCToFunction(pc)
  971. if err != nil {
  972. return ""
  973. }
  974. name, _ := entry.Val(dwarf.AttrName).(string)
  975. return name
  976. }
  977. if startpc, err := s.peekUintStructField(gType, g, "startpc"); err == nil {
  978. gr.Function = functionName(startpc)
  979. }
  980. if gopc, err := s.peekUintStructField(gType, g, "gopc"); err == nil {
  981. gr.Caller = functionName(gopc)
  982. }
  983. if gr.Status != debug.Running {
  984. // TODO: running goroutines too.
  985. gr.StackFrames, _ = s.goroutineStack(g)
  986. }
  987. resp.Goroutines = append(resp.Goroutines, &gr)
  988. }
  989. return nil
  990. }
  991. // TODO: let users specify how many frames they want. 10 will be enough to
  992. // determine the reason a goroutine is blocked.
  993. const goroutineStackFrameCount = 10
  994. // goroutineStackInit initializes s.goroutineStack.
  995. func (s *Server) goroutineStackInit(gType *dwarf.StructType) {
  996. // If we fail to read the DWARF data needed for s.goroutineStack, calling it
  997. // will always return the error that occurred during initialization.
  998. var err error // err is captured by the func below.
  999. s.goroutineStack = func(gAddr uint64) ([]debug.Frame, error) {
  1000. return nil, err
  1001. }
  1002. // Get g field "sched", which contains fields pc and sp.
  1003. schedField, err := getField(gType, "sched")
  1004. if err != nil {
  1005. return
  1006. }
  1007. schedOffset := uint64(schedField.ByteOffset)
  1008. schedType, ok := followTypedefs(schedField.Type).(*dwarf.StructType)
  1009. if !ok {
  1010. err = errors.New(`g field "sched" has the wrong type`)
  1011. return
  1012. }
  1013. // Get the size of the pc and sp fields and their offsets inside the g struct,
  1014. // so we can quickly peek those values for each goroutine later.
  1015. var (
  1016. schedPCOffset, schedSPOffset uint64
  1017. schedPCByteSize, schedSPByteSize int64
  1018. )
  1019. for _, x := range []struct {
  1020. field string
  1021. offset *uint64
  1022. bytesize *int64
  1023. }{
  1024. {"pc", &schedPCOffset, &schedPCByteSize},
  1025. {"sp", &schedSPOffset, &schedSPByteSize},
  1026. } {
  1027. var f *dwarf.StructField
  1028. f, err = getField(schedType, x.field)
  1029. if err != nil {
  1030. return
  1031. }
  1032. *x.offset = schedOffset + uint64(f.ByteOffset)
  1033. switch t := followTypedefs(f.Type).(type) {
  1034. case *dwarf.UintType, *dwarf.IntType:
  1035. *x.bytesize = t.Common().ByteSize
  1036. default:
  1037. err = fmt.Errorf("gobuf field %q has the wrong type", x.field)
  1038. return
  1039. }
  1040. }
  1041. s.goroutineStack = func(gAddr uint64) ([]debug.Frame, error) {
  1042. schedPC, err := s.peekUint(gAddr+schedPCOffset, schedPCByteSize)
  1043. if err != nil {
  1044. return nil, err
  1045. }
  1046. schedSP, err := s.peekUint(gAddr+schedSPOffset, schedSPByteSize)
  1047. if err != nil {
  1048. return nil, err
  1049. }
  1050. return s.walkStack(schedPC, schedSP, goroutineStackFrameCount)
  1051. }
  1052. }