Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
HugeYuan
delve
提交
c7fe4e3e
D
delve
项目概览
HugeYuan
/
delve
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
delve
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
c7fe4e3e
编写于
2月 02, 2015
作者:
E
epipho
提交者:
Derek Parker
2月 04, 2015
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added limit to array size (64) and struct member recursion (2) when printing
上级
fe8e85e3
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
49 addition
and
16 deletion
+49
-16
_fixtures/testvariables.go
_fixtures/testvariables.go
+8
-1
proctl/variables.go
proctl/variables.go
+33
-11
proctl/variables_test.go
proctl/variables_test.go
+8
-4
未找到文件。
_fixtures/testvariables.go
浏览文件 @
c7fe4e3e
...
...
@@ -13,6 +13,11 @@ type FooBar2 struct {
Baz
string
}
type
Nest
struct
{
Level
int
Nest
*
Nest
}
func
barfoo
()
{
a1
:=
"bur"
fmt
.
Println
(
a1
)
...
...
@@ -45,10 +50,12 @@ func foobar(baz string, bar FooBar) {
f32
=
float32
(
1.2
)
i32
=
[
2
]
int32
{
1
,
2
}
f
=
barfoo
ms
=
Nest
{
0
,
&
Nest
{
1
,
&
Nest
{
2
,
&
Nest
{
3
,
&
Nest
{
4
,
nil
}}}}}
// Test recursion capping
ba
=
make
([]
int
,
200
,
200
)
// Test array size capping
)
barfoo
()
fmt
.
Println
(
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
,
a10
,
a11
,
a12
,
a13
,
b1
,
b2
,
baz
,
neg
,
i8
,
u8
,
u16
,
u32
,
u64
,
up
,
f32
,
i32
,
bar
,
f
)
fmt
.
Println
(
a1
,
a2
,
a3
,
a4
,
a5
,
a6
,
a7
,
a8
,
a9
,
a10
,
a11
,
a12
,
a13
,
b1
,
b2
,
baz
,
neg
,
i8
,
u8
,
u16
,
u32
,
u64
,
up
,
f32
,
i32
,
bar
,
f
,
ms
,
ba
)
}
func
main
()
{
...
...
proctl/variables.go
浏览文件 @
c7fe4e3e
...
...
@@ -13,6 +13,11 @@ import (
"github.com/derekparker/delve/dwarf/reader"
)
const
(
maxVariableRecurse
=
1
maxArrayValues
=
64
)
type
Variable
struct
{
Name
string
Value
string
...
...
@@ -558,6 +563,10 @@ func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, read
// We execute the stack program described in the DW_OP_* instruction stream, and
// then grab the value from the other processes memory.
func
(
thread
*
ThreadContext
)
extractValue
(
instructions
[]
byte
,
addr
int64
,
typ
interface
{},
printStructName
bool
)
(
string
,
error
)
{
return
thread
.
extractValueInternal
(
instructions
,
addr
,
typ
,
printStructName
,
0
)
}
func
(
thread
*
ThreadContext
)
extractValueInternal
(
instructions
[]
byte
,
addr
int64
,
typ
interface
{},
printStructName
bool
,
recurseLevel
int
)
(
string
,
error
)
{
var
err
error
if
addr
==
0
{
...
...
@@ -590,7 +599,8 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i
return
fmt
.
Sprintf
(
"%s nil"
,
t
.
String
()),
nil
}
val
,
err
:=
thread
.
extractValue
(
nil
,
intaddr
,
t
.
Type
,
printStructName
)
// Don't increase the recursion level when dereferencing pointers
val
,
err
:=
thread
.
extractValueInternal
(
nil
,
intaddr
,
t
.
Type
,
printStructName
,
recurseLevel
)
if
err
!=
nil
{
return
""
,
err
}
...
...
@@ -605,20 +615,26 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i
default
:
// Recursively call extractValue to grab
// the value of all the members of the struct.
fields
:=
make
([]
string
,
0
,
len
(
t
.
Field
))
for
_
,
field
:=
range
t
.
Field
{
val
,
err
:=
thread
.
extractValue
(
nil
,
field
.
ByteOffset
+
addr
,
field
.
Type
,
printStructName
)
if
err
!=
nil
{
return
""
,
err
if
recurseLevel
<=
maxVariableRecurse
{
fields
:=
make
([]
string
,
0
,
len
(
t
.
Field
))
for
_
,
field
:=
range
t
.
Field
{
val
,
err
:=
thread
.
extractValueInternal
(
nil
,
field
.
ByteOffset
+
addr
,
field
.
Type
,
printStructName
,
recurseLevel
+
1
)
if
err
!=
nil
{
return
""
,
err
}
fields
=
append
(
fields
,
fmt
.
Sprintf
(
"%s: %s"
,
field
.
Name
,
val
))
}
fields
=
append
(
fields
,
fmt
.
Sprintf
(
"%s: %s"
,
field
.
Name
,
val
))
if
printStructName
{
return
fmt
.
Sprintf
(
"%s {%s}"
,
t
.
StructName
,
strings
.
Join
(
fields
,
", "
)),
nil
}
return
fmt
.
Sprintf
(
"{%s}"
,
strings
.
Join
(
fields
,
", "
)),
nil
}
// no fields
if
printStructName
{
return
fmt
.
Sprintf
(
"%s {%s}"
,
t
.
StructName
,
strings
.
Join
(
fields
,
", "
)),
nil
}
else
{
return
fmt
.
Sprintf
(
"{%s}"
,
strings
.
Join
(
fields
,
", "
)),
nil
return
fmt
.
Sprintf
(
"%s {...}"
,
t
.
StructName
),
nil
}
return
"{...}"
,
nil
}
case
*
dwarf
.
ArrayType
:
return
thread
.
readArray
(
ptraddress
,
t
)
...
...
@@ -736,6 +752,12 @@ func (thread *ThreadContext) readArrayValues(addr uintptr, count int64, stride i
vals
:=
make
([]
string
,
0
)
for
i
:=
int64
(
0
);
i
<
count
;
i
++
{
// Cap number of elements
if
i
>=
maxArrayValues
{
vals
=
append
(
vals
,
fmt
.
Sprintf
(
"...+%d more"
,
count
-
maxArrayValues
))
break
}
val
,
err
:=
thread
.
extractValue
(
nil
,
int64
(
addr
+
uintptr
(
i
*
stride
)),
t
,
false
)
if
err
!=
nil
{
return
nil
,
err
...
...
proctl/variables_test.go
浏览文件 @
c7fe4e3e
...
...
@@ -68,11 +68,13 @@ func TestVariableEvaluation(t *testing.T) {
{
"u8"
,
"255"
,
"uint8"
,
nil
},
{
"up"
,
"5"
,
"uintptr"
,
nil
},
{
"f"
,
"main.barfoo"
,
"func()"
,
nil
},
{
"ba"
,
"[]int len: 200, cap: 200, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+136 more]"
,
"struct []int"
,
nil
},
{
"ms"
,
"main.Nest {Level: 0, Nest: *main.Nest {Level: 1, Nest: *main.Nest {...}}}"
,
"main.Nest"
,
nil
},
{
"NonExistent"
,
""
,
""
,
errors
.
New
(
"could not find symbol value for NonExistent"
)},
}
withTestProcess
(
executablePath
,
t
,
func
(
p
*
DebuggedProcess
)
{
pc
,
_
,
_
:=
p
.
GoSymTable
.
LineToPC
(
fp
,
5
0
)
pc
,
_
,
_
:=
p
.
GoSymTable
.
LineToPC
(
fp
,
5
7
)
_
,
err
:=
p
.
Break
(
pc
)
assertNoError
(
err
,
t
,
"Break() returned an error"
)
...
...
@@ -103,7 +105,7 @@ func TestVariableFunctionScoping(t *testing.T) {
}
withTestProcess
(
executablePath
,
t
,
func
(
p
*
DebuggedProcess
)
{
pc
,
_
,
_
:=
p
.
GoSymTable
.
LineToPC
(
fp
,
5
0
)
pc
,
_
,
_
:=
p
.
GoSymTable
.
LineToPC
(
fp
,
5
7
)
_
,
err
:=
p
.
Break
(
pc
)
assertNoError
(
err
,
t
,
"Break() returned an error"
)
...
...
@@ -118,7 +120,7 @@ func TestVariableFunctionScoping(t *testing.T) {
assertNoError
(
err
,
t
,
"Unable to find variable a1"
)
// Move scopes, a1 exists here by a2 does not
pc
,
_
,
_
=
p
.
GoSymTable
.
LineToPC
(
fp
,
18
)
pc
,
_
,
_
=
p
.
GoSymTable
.
LineToPC
(
fp
,
23
)
_
,
err
=
p
.
Break
(
pc
)
assertNoError
(
err
,
t
,
"Break() returned an error"
)
...
...
@@ -182,10 +184,12 @@ func TestLocalVariables(t *testing.T) {
{
"a9"
,
"*main.FooBar nil"
,
"*main.FooBar"
,
nil
},
{
"b1"
,
"true"
,
"bool"
,
nil
},
{
"b2"
,
"false"
,
"bool"
,
nil
},
{
"ba"
,
"[]int len: 200, cap: 200, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+136 more]"
,
"struct []int"
,
nil
},
{
"f"
,
"main.barfoo"
,
"func()"
,
nil
},
{
"f32"
,
"1.2"
,
"float32"
,
nil
},
{
"i32"
,
"[2]int32 [1,2]"
,
"[2]int32"
,
nil
},
{
"i8"
,
"1"
,
"int8"
,
nil
},
{
"ms"
,
"main.Nest {Level: 0, Nest: *main.Nest {Level: 1, Nest: *main.Nest {...}}}"
,
"main.Nest"
,
nil
},
{
"neg"
,
"-1"
,
"int"
,
nil
},
{
"u16"
,
"65535"
,
"uint16"
,
nil
},
{
"u32"
,
"4294967295"
,
"uint32"
,
nil
},
...
...
@@ -199,7 +203,7 @@ func TestLocalVariables(t *testing.T) {
}
withTestProcess
(
executablePath
,
t
,
func
(
p
*
DebuggedProcess
)
{
pc
,
_
,
_
:=
p
.
GoSymTable
.
LineToPC
(
fp
,
5
0
)
pc
,
_
,
_
:=
p
.
GoSymTable
.
LineToPC
(
fp
,
5
7
)
_
,
err
:=
p
.
Break
(
pc
)
assertNoError
(
err
,
t
,
"Break() returned an error"
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录