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.
 
 
 

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