Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 

328 рядки
10 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. // Package debug provides the portable interface to a program being debugged.
  15. package debug
  16. import (
  17. "fmt"
  18. "io"
  19. "strings"
  20. )
  21. // Program is the interface to a (possibly remote) program being debugged.
  22. // The process (if any) and text file associated with it may change during
  23. // the session, but many resources are associated with the Program rather
  24. // than process or text file so they persist across debuggging runs.
  25. type Program interface {
  26. // Open opens a virtual file associated with the process.
  27. // Names are things like "text", "mem", "fd/2".
  28. // Mode is one of "r", "w", "rw".
  29. // Return values are open File and error.
  30. // When the target binary is re-run, open files are
  31. // automatically updated to refer to the corresponding
  32. // file in the new process.
  33. Open(name string, mode string) (File, error)
  34. // Run abandons the current running process, if any,
  35. // and execs a new instance of the target binary file
  36. // (which may have changed underfoot).
  37. // Breakpoints and open files are re-established.
  38. // The call hangs until the program stops executing,
  39. // at which point it returns the program status.
  40. // args contains the command-line arguments for the process.
  41. Run(args ...string) (Status, error)
  42. // Stop stops execution of the current process but
  43. // does not kill it.
  44. Stop() (Status, error)
  45. // Resume resumes execution of a stopped process.
  46. // The call hangs until the program stops executing,
  47. // at which point it returns the program status.
  48. Resume() (Status, error)
  49. // TODO: Step(). Where does the granularity happen,
  50. // on the proxy end or the debugging control end?
  51. // Kill kills the current process.
  52. Kill() (Status, error)
  53. // Breakpoint sets a breakpoint at the specified address.
  54. Breakpoint(address uint64) (PCs []uint64, err error)
  55. // BreakpointAtFunction sets a breakpoint at the start of the specified function.
  56. BreakpointAtFunction(name string) (PCs []uint64, err error)
  57. // BreakpointAtLine sets a breakpoint at the specified source line.
  58. BreakpointAtLine(file string, line uint64) (PCs []uint64, err error)
  59. // DeleteBreakpoints removes the breakpoints at the specified addresses.
  60. // Addresses where no breakpoint is set are ignored.
  61. DeleteBreakpoints(pcs []uint64) error
  62. // Eval evaluates the expression (typically an address) and returns
  63. // its string representation(s). Multivalued expressions such as
  64. // matches for regular expressions return multiple values.
  65. // TODO: change this to multiple functions with more specific names.
  66. // Syntax:
  67. // re:regexp
  68. // Returns a list of symbol names that match the expression
  69. // addr:symbol
  70. // Returns a one-element list holding the hexadecimal
  71. // ("0x1234") value of the address of the symbol
  72. // val:symbol
  73. // Returns a one-element list holding the formatted
  74. // value of the symbol
  75. // 0x1234, 01234, 467
  76. // Returns a one-element list holding the name of the
  77. // symbol ("main.foo") at that address (hex, octal, decimal).
  78. Eval(expr string) ([]string, error)
  79. // Evaluate evaluates an expression. Accepts a subset of Go expression syntax:
  80. // basic literals, identifiers, parenthesized expressions, and most operators.
  81. // Only the len function call is available.
  82. //
  83. // The expression can refer to local variables and function parameters of the
  84. // function where the program is stopped.
  85. //
  86. // On success, the type of the value returned will be one of:
  87. // int8, int16, int32, int64, uint8, uint16, uint32, uint64, float32, float64,
  88. // complex64, complex128, bool, Pointer, Array, Slice, String, Map, Struct,
  89. // Channel, Func, or Interface.
  90. Evaluate(e string) (Value, error)
  91. // Frames returns up to count stack frames from where the program
  92. // is currently stopped.
  93. Frames(count int) ([]Frame, error)
  94. // VarByName returns a Var referring to a global variable with the given name.
  95. // TODO: local variables
  96. VarByName(name string) (Var, error)
  97. // Value gets the value of a variable by reading the program's memory.
  98. Value(v Var) (Value, error)
  99. // MapElement returns Vars for the key and value of a map element specified by
  100. // a 0-based index.
  101. MapElement(m Map, index uint64) (Var, Var, error)
  102. // Goroutines gets the current goroutines.
  103. Goroutines() ([]*Goroutine, error)
  104. }
  105. type Goroutine struct {
  106. ID int64
  107. Status GoroutineStatus
  108. StatusString string // A human-readable string explaining the status in more detail.
  109. Function string // Name of the goroutine function.
  110. Caller string // Name of the function that created this goroutine.
  111. StackFrames []Frame
  112. }
  113. type GoroutineStatus byte
  114. const (
  115. Running GoroutineStatus = iota
  116. Queued
  117. Blocked
  118. )
  119. func (g GoroutineStatus) String() string {
  120. switch g {
  121. case Running:
  122. return "running"
  123. case Queued:
  124. return "queued"
  125. case Blocked:
  126. return "blocked"
  127. }
  128. return "invalid status"
  129. }
  130. func (g *Goroutine) String() string {
  131. return fmt.Sprintf("goroutine %d [%s] %s -> %s", g.ID, g.StatusString, g.Caller, g.Function)
  132. }
  133. // A reference to a variable in a program.
  134. // TODO: handle variables stored in registers
  135. type Var struct {
  136. TypeID uint64 // A type identifier, opaque to the user.
  137. Address uint64 // The address of the variable.
  138. }
  139. // A value read from a remote program.
  140. type Value interface{}
  141. // Pointer is a Value representing a pointer.
  142. // Note that the TypeID field will be the type of the variable being pointed to,
  143. // not the type of this pointer.
  144. type Pointer struct {
  145. TypeID uint64 // A type identifier, opaque to the user.
  146. Address uint64 // The address of the variable.
  147. }
  148. // Array is a Value representing an array.
  149. type Array struct {
  150. ElementTypeID uint64
  151. Address uint64
  152. Length uint64 // Number of elements in the array
  153. StrideBits uint64 // Number of bits between array entries
  154. }
  155. // Len returns the number of elements in the array.
  156. func (a Array) Len() uint64 {
  157. return a.Length
  158. }
  159. // Element returns a Var referring to the given element of the array.
  160. func (a Array) Element(index uint64) Var {
  161. return Var{
  162. TypeID: a.ElementTypeID,
  163. Address: a.Address + index*(a.StrideBits/8),
  164. }
  165. }
  166. // Slice is a Value representing a slice.
  167. type Slice struct {
  168. Array
  169. Capacity uint64
  170. }
  171. // String is a Value representing a string.
  172. // TODO: a method to access more of a truncated string.
  173. type String struct {
  174. // Length contains the length of the remote string, in bytes.
  175. Length uint64
  176. // String contains the string itself; it may be truncated to fewer bytes than the value of the Length field.
  177. String string
  178. }
  179. // Map is a Value representing a map.
  180. type Map struct {
  181. TypeID uint64
  182. Address uint64
  183. Length uint64 // Number of elements in the map.
  184. }
  185. // Struct is a Value representing a struct.
  186. type Struct struct {
  187. Fields []StructField
  188. }
  189. // StructField represents a field in a struct object.
  190. type StructField struct {
  191. Name string
  192. Var Var
  193. }
  194. // Channel is a Value representing a channel.
  195. type Channel struct {
  196. ElementTypeID uint64
  197. Address uint64 // Location of the channel struct in memory.
  198. Buffer uint64 // Location of the buffer; zero for nil channels.
  199. Length uint64 // Number of elements stored in the channel buffer.
  200. Capacity uint64 // Capacity of the buffer; zero for unbuffered channels.
  201. Stride uint64 // Number of bytes between buffer entries.
  202. BufferStart uint64 // Index in the buffer of the element at the head of the queue.
  203. }
  204. // Element returns a Var referring to the given element of the channel's queue.
  205. // If the channel is unbuffered, nil, or if the index is too large, returns a Var with Address == 0.
  206. func (m Channel) Element(index uint64) Var {
  207. if index >= m.Length {
  208. return Var{
  209. TypeID: m.ElementTypeID,
  210. Address: 0,
  211. }
  212. }
  213. if index < m.Capacity-m.BufferStart {
  214. // The element is in the part of the queue that occurs later in the buffer
  215. // than the head of the queue.
  216. return Var{
  217. TypeID: m.ElementTypeID,
  218. Address: m.Buffer + (m.BufferStart+index)*m.Stride,
  219. }
  220. }
  221. // The element is in the part of the queue that has wrapped around to the
  222. // start of the buffer.
  223. return Var{
  224. TypeID: m.ElementTypeID,
  225. Address: m.Buffer + (m.BufferStart+index-m.Capacity)*m.Stride,
  226. }
  227. }
  228. // Func is a Value representing a func.
  229. type Func struct {
  230. Address uint64
  231. }
  232. // Interface is a Value representing an interface.
  233. type Interface struct{}
  234. // The File interface provides access to file-like resources in the program.
  235. // It implements only ReaderAt and WriterAt, not Reader and Writer, because
  236. // random access is a far more common pattern for things like symbol tables,
  237. // and because enormous address space of virtual memory makes routines
  238. // like io.Copy dangerous.
  239. type File interface {
  240. io.ReaderAt
  241. io.WriterAt
  242. io.Closer
  243. }
  244. type Status struct {
  245. PC, SP uint64
  246. }
  247. type Frame struct {
  248. // PC is the hardware program counter.
  249. PC uint64
  250. // SP is the hardware stack pointer.
  251. SP uint64
  252. // File and Line are the source code location of the PC.
  253. File string
  254. Line uint64
  255. // Function is the name of this frame's function.
  256. Function string
  257. // FunctionStart is the starting PC of the function.
  258. FunctionStart uint64
  259. // Params contains the function's parameters.
  260. Params []Param
  261. // Vars contains the function's local variables.
  262. Vars []LocalVar
  263. }
  264. func (f Frame) String() string {
  265. params := make([]string, len(f.Params))
  266. for i, p := range f.Params {
  267. params[i] = p.Name // TODO: more information
  268. }
  269. p := strings.Join(params, ", ")
  270. off := f.PC - f.FunctionStart
  271. return fmt.Sprintf("%s(%s)\n\t%s:%d +0x%x", f.Function, p, f.File, f.Line, off)
  272. }
  273. // Param is a parameter of a function.
  274. type Param struct {
  275. Name string
  276. Var Var
  277. }
  278. // LocalVar is a local variable of a function.
  279. type LocalVar struct {
  280. Name string
  281. Var Var
  282. }