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.
 
 
 

206 lines
5.3 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 local provides access to a local program.
  16. package local
  17. import (
  18. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug"
  19. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server"
  20. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/server/protocol"
  21. )
  22. var _ debug.Program = (*Program)(nil)
  23. var _ debug.File = (*File)(nil)
  24. // Program implements the debug.Program interface.
  25. // Through that interface it provides access to a program being debugged.
  26. type Program struct {
  27. s *server.Server
  28. }
  29. // New creates a new program from the specified file.
  30. // The program can then be started by the Run method.
  31. func New(textFile string) (*Program, error) {
  32. s, err := server.New(textFile)
  33. return &Program{s: s}, err
  34. }
  35. func (p *Program) Open(name string, mode string) (debug.File, error) {
  36. req := protocol.OpenRequest{
  37. Name: name,
  38. Mode: mode,
  39. }
  40. var resp protocol.OpenResponse
  41. err := p.s.Open(&req, &resp)
  42. if err != nil {
  43. return nil, err
  44. }
  45. f := &File{
  46. prog: p,
  47. fd: resp.FD,
  48. }
  49. return f, nil
  50. }
  51. func (p *Program) Run(args ...string) (debug.Status, error) {
  52. req := protocol.RunRequest{args}
  53. var resp protocol.RunResponse
  54. err := p.s.Run(&req, &resp)
  55. if err != nil {
  56. return debug.Status{}, err
  57. }
  58. return resp.Status, nil
  59. }
  60. func (p *Program) Stop() (debug.Status, error) {
  61. panic("unimplemented")
  62. }
  63. func (p *Program) Resume() (debug.Status, error) {
  64. req := protocol.ResumeRequest{}
  65. var resp protocol.ResumeResponse
  66. err := p.s.Resume(&req, &resp)
  67. if err != nil {
  68. return debug.Status{}, err
  69. }
  70. return resp.Status, nil
  71. }
  72. func (p *Program) Kill() (debug.Status, error) {
  73. panic("unimplemented")
  74. }
  75. func (p *Program) Breakpoint(address uint64) ([]uint64, error) {
  76. req := protocol.BreakpointRequest{
  77. Address: address,
  78. }
  79. var resp protocol.BreakpointResponse
  80. err := p.s.Breakpoint(&req, &resp)
  81. return resp.PCs, err
  82. }
  83. func (p *Program) BreakpointAtFunction(name string) ([]uint64, error) {
  84. req := protocol.BreakpointAtFunctionRequest{
  85. Function: name,
  86. }
  87. var resp protocol.BreakpointResponse
  88. err := p.s.BreakpointAtFunction(&req, &resp)
  89. return resp.PCs, err
  90. }
  91. func (p *Program) BreakpointAtLine(file string, line uint64) ([]uint64, error) {
  92. req := protocol.BreakpointAtLineRequest{
  93. File: file,
  94. Line: line,
  95. }
  96. var resp protocol.BreakpointResponse
  97. err := p.s.BreakpointAtLine(&req, &resp)
  98. return resp.PCs, err
  99. }
  100. func (p *Program) DeleteBreakpoints(pcs []uint64) error {
  101. req := protocol.DeleteBreakpointsRequest{PCs: pcs}
  102. var resp protocol.DeleteBreakpointsResponse
  103. return p.s.DeleteBreakpoints(&req, &resp)
  104. }
  105. func (p *Program) Eval(expr string) ([]string, error) {
  106. req := protocol.EvalRequest{
  107. Expr: expr,
  108. }
  109. var resp protocol.EvalResponse
  110. err := p.s.Eval(&req, &resp)
  111. return resp.Result, err
  112. }
  113. func (p *Program) Evaluate(e string) (debug.Value, error) {
  114. req := protocol.EvaluateRequest{
  115. Expression: e,
  116. }
  117. var resp protocol.EvaluateResponse
  118. err := p.s.Evaluate(&req, &resp)
  119. return resp.Result, err
  120. }
  121. func (p *Program) Frames(count int) ([]debug.Frame, error) {
  122. req := protocol.FramesRequest{
  123. Count: count,
  124. }
  125. var resp protocol.FramesResponse
  126. err := p.s.Frames(&req, &resp)
  127. return resp.Frames, err
  128. }
  129. func (p *Program) Goroutines() ([]*debug.Goroutine, error) {
  130. req := protocol.GoroutinesRequest{}
  131. var resp protocol.GoroutinesResponse
  132. err := p.s.Goroutines(&req, &resp)
  133. return resp.Goroutines, err
  134. }
  135. func (p *Program) VarByName(name string) (debug.Var, error) {
  136. req := protocol.VarByNameRequest{Name: name}
  137. var resp protocol.VarByNameResponse
  138. err := p.s.VarByName(&req, &resp)
  139. return resp.Var, err
  140. }
  141. func (p *Program) Value(v debug.Var) (debug.Value, error) {
  142. req := protocol.ValueRequest{Var: v}
  143. var resp protocol.ValueResponse
  144. err := p.s.Value(&req, &resp)
  145. return resp.Value, err
  146. }
  147. func (p *Program) MapElement(m debug.Map, index uint64) (debug.Var, debug.Var, error) {
  148. req := protocol.MapElementRequest{Map: m, Index: index}
  149. var resp protocol.MapElementResponse
  150. err := p.s.MapElement(&req, &resp)
  151. return resp.Key, resp.Value, err
  152. }
  153. // File implements the debug.File interface, providing access
  154. // to file-like resources associated with the target program.
  155. type File struct {
  156. prog *Program // The Program associated with the file.
  157. fd int // File descriptor.
  158. }
  159. func (f *File) ReadAt(p []byte, offset int64) (int, error) {
  160. req := protocol.ReadAtRequest{
  161. FD: f.fd,
  162. Len: len(p),
  163. Offset: offset,
  164. }
  165. var resp protocol.ReadAtResponse
  166. err := f.prog.s.ReadAt(&req, &resp)
  167. return copy(p, resp.Data), err
  168. }
  169. func (f *File) WriteAt(p []byte, offset int64) (int, error) {
  170. panic("unimplemented")
  171. }
  172. func (f *File) Close() error {
  173. req := protocol.CloseRequest{
  174. FD: f.fd,
  175. }
  176. var resp protocol.CloseResponse
  177. err := f.prog.s.Close(&req, &resp)
  178. return err
  179. }