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.
 
 
 

261 lines
6.9 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
  16. import (
  17. "fmt"
  18. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug"
  19. "cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/dwarf"
  20. )
  21. // value peeks the program's memory at the given address, parsing it as a value of type t.
  22. func (s *Server) value(t dwarf.Type, addr uint64) (debug.Value, error) {
  23. // readBasic reads the memory for a basic type of size n bytes.
  24. readBasic := func(n int64) ([]byte, error) {
  25. switch n {
  26. case 1, 2, 4, 8, 16:
  27. default:
  28. return nil, fmt.Errorf("invalid size: %d", n)
  29. }
  30. buf := make([]byte, n)
  31. if err := s.peek(uintptr(addr), buf); err != nil {
  32. return nil, err
  33. }
  34. return buf, nil
  35. }
  36. switch t := t.(type) {
  37. case *dwarf.CharType, *dwarf.IntType:
  38. bs := t.Common().ByteSize
  39. buf, err := readBasic(bs)
  40. if err != nil {
  41. return nil, fmt.Errorf("reading integer: %s", err)
  42. }
  43. x := s.arch.IntN(buf)
  44. switch bs {
  45. case 1:
  46. return int8(x), nil
  47. case 2:
  48. return int16(x), nil
  49. case 4:
  50. return int32(x), nil
  51. case 8:
  52. return int64(x), nil
  53. default:
  54. return nil, fmt.Errorf("invalid integer size: %d", bs)
  55. }
  56. case *dwarf.UcharType, *dwarf.UintType, *dwarf.AddrType:
  57. bs := t.Common().ByteSize
  58. buf, err := readBasic(bs)
  59. if err != nil {
  60. return nil, fmt.Errorf("reading unsigned integer: %s", err)
  61. }
  62. x := s.arch.UintN(buf)
  63. switch bs {
  64. case 1:
  65. return uint8(x), nil
  66. case 2:
  67. return uint16(x), nil
  68. case 4:
  69. return uint32(x), nil
  70. case 8:
  71. return uint64(x), nil
  72. default:
  73. return nil, fmt.Errorf("invalid unsigned integer size: %d", bs)
  74. }
  75. case *dwarf.BoolType:
  76. bs := t.Common().ByteSize
  77. buf, err := readBasic(bs)
  78. if err != nil {
  79. return nil, fmt.Errorf("reading boolean: %s", err)
  80. }
  81. for _, b := range buf {
  82. if b != 0 {
  83. return true, nil
  84. }
  85. }
  86. return false, nil
  87. case *dwarf.FloatType:
  88. bs := t.Common().ByteSize
  89. buf, err := readBasic(bs)
  90. if err != nil {
  91. return nil, fmt.Errorf("reading float: %s", err)
  92. }
  93. switch bs {
  94. case 4:
  95. return s.arch.Float32(buf), nil
  96. case 8:
  97. return s.arch.Float64(buf), nil
  98. default:
  99. return nil, fmt.Errorf("invalid float size: %d", bs)
  100. }
  101. case *dwarf.ComplexType:
  102. bs := t.Common().ByteSize
  103. buf, err := readBasic(bs)
  104. if err != nil {
  105. return nil, fmt.Errorf("reading complex: %s", err)
  106. }
  107. switch bs {
  108. case 8:
  109. return s.arch.Complex64(buf), nil
  110. case 16:
  111. return s.arch.Complex128(buf), nil
  112. default:
  113. return nil, fmt.Errorf("invalid complex size: %d", bs)
  114. }
  115. case *dwarf.PtrType:
  116. bs := t.Common().ByteSize
  117. if bs != int64(s.arch.PointerSize) {
  118. return nil, fmt.Errorf("invalid pointer size: %d", bs)
  119. }
  120. buf, err := readBasic(bs)
  121. if err != nil {
  122. return nil, fmt.Errorf("reading pointer: %s", err)
  123. }
  124. return debug.Pointer{
  125. TypeID: uint64(t.Type.Common().Offset),
  126. Address: uint64(s.arch.Uintptr(buf)),
  127. }, nil
  128. case *dwarf.SliceType:
  129. if s, err := s.peekSlice(t, addr); err != nil {
  130. return nil, err
  131. } else {
  132. return s, nil
  133. }
  134. case *dwarf.ArrayType:
  135. length := t.Count
  136. stride := t.StrideBitSize
  137. if stride%8 != 0 {
  138. return nil, fmt.Errorf("array is not byte-aligned")
  139. }
  140. return debug.Array{
  141. ElementTypeID: uint64(t.Type.Common().Offset),
  142. Address: uint64(addr),
  143. Length: uint64(length),
  144. StrideBits: uint64(stride),
  145. }, nil
  146. case *dwarf.StructType:
  147. fields := make([]debug.StructField, len(t.Field))
  148. for i, field := range t.Field {
  149. fields[i] = debug.StructField{
  150. Name: field.Name,
  151. Var: debug.Var{
  152. TypeID: uint64(field.Type.Common().Offset),
  153. Address: uint64(addr) + uint64(field.ByteOffset),
  154. },
  155. }
  156. }
  157. return debug.Struct{fields}, nil
  158. case *dwarf.TypedefType:
  159. return s.value(t.Type, addr)
  160. case *dwarf.MapType:
  161. length, err := s.peekMapLength(t, addr)
  162. if err != nil {
  163. return nil, err
  164. }
  165. return debug.Map{
  166. TypeID: uint64(t.Common().Offset),
  167. Address: addr,
  168. Length: length,
  169. }, nil
  170. case *dwarf.StringType:
  171. ptr, err := s.peekPtrStructField(&t.StructType, addr, "str")
  172. if err != nil {
  173. return nil, fmt.Errorf("reading string location: %s", err)
  174. }
  175. length, err := s.peekUintOrIntStructField(&t.StructType, addr, "len")
  176. if err != nil {
  177. return nil, fmt.Errorf("reading string length: %s", err)
  178. }
  179. const maxStringSize = 256
  180. n := length
  181. if n > maxStringSize {
  182. n = maxStringSize
  183. }
  184. tmp := make([]byte, n)
  185. if err := s.peekBytes(ptr, tmp); err != nil {
  186. return nil, fmt.Errorf("reading string contents: %s", err)
  187. }
  188. return debug.String{Length: length, String: string(tmp)}, nil
  189. case *dwarf.ChanType:
  190. pt, ok := t.TypedefType.Type.(*dwarf.PtrType)
  191. if !ok {
  192. return nil, fmt.Errorf("reading channel: type is not a pointer")
  193. }
  194. st, ok := pt.Type.(*dwarf.StructType)
  195. if !ok {
  196. return nil, fmt.Errorf("reading channel: type is not a pointer to struct")
  197. }
  198. a, err := s.peekPtr(addr)
  199. if err != nil {
  200. return nil, fmt.Errorf("reading channel pointer: %s", err)
  201. }
  202. if a == 0 {
  203. // This channel is nil.
  204. return debug.Channel{
  205. ElementTypeID: uint64(t.ElemType.Common().Offset),
  206. Address: 0,
  207. Buffer: 0,
  208. Length: 0,
  209. Capacity: 0,
  210. Stride: uint64(t.ElemType.Common().ByteSize),
  211. BufferStart: 0,
  212. }, nil
  213. }
  214. buf, err := s.peekPtrStructField(st, a, "buf")
  215. if err != nil {
  216. return nil, fmt.Errorf("reading channel buffer location: %s", err)
  217. }
  218. qcount, err := s.peekUintOrIntStructField(st, a, "qcount")
  219. if err != nil {
  220. return nil, fmt.Errorf("reading channel length: %s", err)
  221. }
  222. capacity, err := s.peekUintOrIntStructField(st, a, "dataqsiz")
  223. if err != nil {
  224. return nil, fmt.Errorf("reading channel capacity: %s", err)
  225. }
  226. recvx, err := s.peekUintOrIntStructField(st, a, "recvx")
  227. if err != nil {
  228. return nil, fmt.Errorf("reading channel buffer index: %s", err)
  229. }
  230. return debug.Channel{
  231. ElementTypeID: uint64(t.ElemType.Common().Offset),
  232. Address: a,
  233. Buffer: buf,
  234. Length: qcount,
  235. Capacity: capacity,
  236. Stride: uint64(t.ElemType.Common().ByteSize),
  237. BufferStart: recvx,
  238. }, nil
  239. case *dwarf.FuncType:
  240. a, err := s.peekPtr(addr)
  241. if err != nil {
  242. return nil, fmt.Errorf("reading func: %s", err)
  243. }
  244. return debug.Func{Address: a}, nil
  245. case *dwarf.InterfaceType:
  246. return debug.Interface{}, nil
  247. // TODO: more types
  248. }
  249. return nil, fmt.Errorf("Unsupported type %T", t)
  250. }