2015-06-13 04:47:30 +00:00
|
|
|
package api
|
|
|
|
|
2015-06-17 17:11:57 +00:00
|
|
|
import (
|
|
|
|
"debug/gosym"
|
2015-10-21 07:06:36 +00:00
|
|
|
"go/constant"
|
|
|
|
"reflect"
|
2015-09-26 00:04:39 +00:00
|
|
|
"strconv"
|
2015-07-01 03:16:52 +00:00
|
|
|
|
2015-06-17 17:11:57 +00:00
|
|
|
"github.com/derekparker/delve/proc"
|
|
|
|
)
|
2015-06-13 04:47:30 +00:00
|
|
|
|
|
|
|
func ConvertBreakpoint(bp *proc.Breakpoint) *Breakpoint {
|
2015-09-26 00:04:39 +00:00
|
|
|
b := &Breakpoint{
|
|
|
|
ID: bp.ID,
|
|
|
|
FunctionName: bp.FunctionName,
|
|
|
|
File: bp.File,
|
|
|
|
Line: bp.Line,
|
|
|
|
Addr: bp.Addr,
|
|
|
|
Tracepoint: bp.Tracepoint,
|
|
|
|
Stacktrace: bp.Stacktrace,
|
|
|
|
Goroutine: bp.Goroutine,
|
|
|
|
Variables: bp.Variables,
|
|
|
|
TotalHitCount: bp.TotalHitCount,
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
2015-09-26 00:04:39 +00:00
|
|
|
|
|
|
|
b.HitCount = map[string]uint64{}
|
|
|
|
for idx := range bp.HitCount {
|
|
|
|
b.HitCount[strconv.Itoa(idx)] = bp.HitCount[idx]
|
|
|
|
}
|
|
|
|
|
|
|
|
return b
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func ConvertThread(th *proc.Thread) *Thread {
|
|
|
|
var (
|
|
|
|
function *Function
|
|
|
|
file string
|
|
|
|
line int
|
|
|
|
pc uint64
|
2015-10-29 09:59:22 +00:00
|
|
|
gid int
|
2015-06-13 04:47:30 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
loc, err := th.Location()
|
|
|
|
if err == nil {
|
|
|
|
pc = loc.PC
|
|
|
|
file = loc.File
|
|
|
|
line = loc.Line
|
2015-06-17 17:11:57 +00:00
|
|
|
function = ConvertFunction(loc.Fn)
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
|
|
|
|
2015-10-29 09:59:22 +00:00
|
|
|
var bp *Breakpoint
|
|
|
|
|
2015-11-18 09:07:08 +00:00
|
|
|
if th.CurrentBreakpoint != nil && th.BreakpointConditionMet {
|
2015-10-29 09:59:22 +00:00
|
|
|
bp = ConvertBreakpoint(th.CurrentBreakpoint)
|
|
|
|
}
|
|
|
|
|
|
|
|
if g, _ := th.GetG(); g != nil {
|
|
|
|
gid = g.Id
|
|
|
|
}
|
|
|
|
|
2015-06-13 04:47:30 +00:00
|
|
|
return &Thread{
|
2015-10-29 09:59:22 +00:00
|
|
|
ID: th.Id,
|
|
|
|
PC: pc,
|
|
|
|
File: file,
|
|
|
|
Line: line,
|
|
|
|
Function: function,
|
|
|
|
GoroutineID: gid,
|
|
|
|
Breakpoint: bp,
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-18 17:37:13 +00:00
|
|
|
func ConvertVar(v *proc.Variable) *Variable {
|
|
|
|
r := Variable{
|
2015-10-30 11:39:32 +00:00
|
|
|
Addr: v.Addr,
|
|
|
|
OnlyAddr: v.OnlyAddr,
|
|
|
|
Name: v.Name,
|
|
|
|
Kind: v.Kind,
|
|
|
|
Len: v.Len,
|
|
|
|
Cap: v.Cap,
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
2015-10-18 17:37:13 +00:00
|
|
|
|
|
|
|
if v.DwarfType != nil {
|
|
|
|
r.Type = v.DwarfType.String()
|
2015-11-12 11:30:41 +00:00
|
|
|
if r.Type == "*void" {
|
|
|
|
r.Type = "unsafe.Pointer"
|
|
|
|
}
|
2015-10-18 17:37:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if v.RealType != nil {
|
|
|
|
r.RealType = v.RealType.String()
|
2015-11-12 11:30:41 +00:00
|
|
|
if r.RealType == "*void" {
|
|
|
|
r.Type = "unsafe.Pointer"
|
|
|
|
}
|
2015-10-18 17:37:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if v.Unreadable != nil {
|
|
|
|
r.Unreadable = v.Unreadable.Error()
|
|
|
|
}
|
|
|
|
|
2015-10-21 07:06:36 +00:00
|
|
|
if v.Value != nil {
|
|
|
|
switch v.Kind {
|
|
|
|
case reflect.Float32:
|
|
|
|
f, _ := constant.Float64Val(v.Value)
|
|
|
|
r.Value = strconv.FormatFloat(f, 'f', -1, 32)
|
|
|
|
case reflect.Float64:
|
|
|
|
f, _ := constant.Float64Val(v.Value)
|
|
|
|
r.Value = strconv.FormatFloat(f, 'f', -1, 64)
|
|
|
|
case reflect.String, reflect.Func:
|
|
|
|
r.Value = constant.StringVal(v.Value)
|
|
|
|
default:
|
|
|
|
r.Value = v.Value.String()
|
2015-10-18 17:37:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-30 11:39:32 +00:00
|
|
|
switch v.Kind {
|
|
|
|
case reflect.Complex64:
|
|
|
|
r.Children = make([]Variable, 2)
|
|
|
|
r.Len = 2
|
2015-10-18 17:37:13 +00:00
|
|
|
|
2015-10-30 11:39:32 +00:00
|
|
|
real, _ := constant.Float64Val(constant.Real(v.Value))
|
|
|
|
imag, _ := constant.Float64Val(constant.Imag(v.Value))
|
|
|
|
|
|
|
|
r.Children[0].Name = "real"
|
|
|
|
r.Children[0].Kind = reflect.Float32
|
|
|
|
r.Children[0].Value = strconv.FormatFloat(real, 'f', -1, 32)
|
|
|
|
|
|
|
|
r.Children[1].Name = "imaginary"
|
|
|
|
r.Children[1].Kind = reflect.Float32
|
|
|
|
r.Children[1].Value = strconv.FormatFloat(imag, 'f', -1, 32)
|
|
|
|
case reflect.Complex128:
|
|
|
|
r.Children = make([]Variable, 2)
|
|
|
|
r.Len = 2
|
|
|
|
|
|
|
|
real, _ := constant.Float64Val(constant.Real(v.Value))
|
|
|
|
imag, _ := constant.Float64Val(constant.Imag(v.Value))
|
|
|
|
|
|
|
|
r.Children[0].Name = "real"
|
|
|
|
r.Children[0].Kind = reflect.Float64
|
|
|
|
r.Children[0].Value = strconv.FormatFloat(real, 'f', -1, 64)
|
|
|
|
|
|
|
|
r.Children[1].Name = "imaginary"
|
|
|
|
r.Children[1].Kind = reflect.Float64
|
|
|
|
r.Children[1].Value = strconv.FormatFloat(imag, 'f', -1, 64)
|
|
|
|
|
|
|
|
default:
|
|
|
|
r.Children = make([]Variable, len(v.Children))
|
|
|
|
|
|
|
|
for i := range v.Children {
|
|
|
|
r.Children[i] = *ConvertVar(&v.Children[i])
|
|
|
|
}
|
2015-10-18 17:37:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &r
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
|
|
|
|
2015-06-17 17:11:57 +00:00
|
|
|
func ConvertFunction(fn *gosym.Func) *Function {
|
|
|
|
if fn == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return &Function{
|
|
|
|
Name: fn.Name,
|
|
|
|
Type: fn.Type,
|
|
|
|
Value: fn.Value,
|
|
|
|
GoType: fn.GoType,
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
2015-06-17 17:11:57 +00:00
|
|
|
}
|
2015-06-13 04:47:30 +00:00
|
|
|
|
2015-06-17 17:11:57 +00:00
|
|
|
func ConvertGoroutine(g *proc.G) *Goroutine {
|
2015-06-13 04:47:30 +00:00
|
|
|
return &Goroutine{
|
2015-10-18 22:02:14 +00:00
|
|
|
ID: g.Id,
|
|
|
|
CurrentLoc: ConvertLocation(g.CurrentLoc),
|
|
|
|
UserCurrentLoc: ConvertLocation(g.UserCurrent()),
|
|
|
|
GoStatementLoc: ConvertLocation(g.Go()),
|
2015-06-17 17:11:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func ConvertLocation(loc proc.Location) Location {
|
|
|
|
return Location{
|
|
|
|
PC: loc.PC,
|
2015-08-19 22:38:53 +00:00
|
|
|
File: loc.File,
|
2015-06-17 17:11:57 +00:00
|
|
|
Line: loc.Line,
|
|
|
|
Function: ConvertFunction(loc.Fn),
|
2015-06-13 04:47:30 +00:00
|
|
|
}
|
|
|
|
}
|