Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
HugeYuan
delve
提交
e5233e72
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 搜索 >>
提交
e5233e72
编写于
6月 12, 2015
作者:
D
Derek Parker
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Rename: s/ThreadContext/Thread/
上级
bfca6114
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
83 addition
and
83 deletion
+83
-83
proc/breakpoints.go
proc/breakpoints.go
+1
-1
proc/proc.go
proc/proc.go
+5
-5
proc/proc_darwin.go
proc/proc_darwin.go
+5
-5
proc/proc_linux.go
proc/proc_linux.go
+4
-4
proc/proc_test.go
proc/proc_test.go
+1
-1
proc/registers.go
proc/registers.go
+3
-3
proc/registers_darwin_amd64.go
proc/registers_darwin_amd64.go
+2
-2
proc/registers_linux_amd64.go
proc/registers_linux_amd64.go
+2
-2
proc/stack.go
proc/stack.go
+1
-1
proc/threads.go
proc/threads.go
+15
-15
proc/threads_darwin.go
proc/threads_darwin.go
+8
-8
proc/threads_linux.go
proc/threads_linux.go
+8
-8
proc/variables.go
proc/variables.go
+24
-24
proc/variables_test.go
proc/variables_test.go
+3
-3
service/debugger/debugger.go
service/debugger/debugger.go
+1
-1
未找到文件。
proc/breakpoints.go
浏览文件 @
e5233e72
...
...
@@ -28,7 +28,7 @@ func (bp *Breakpoint) String() string {
// Clear this breakpoint appropriately depending on whether it is a
// hardware or software breakpoint.
func
(
bp
*
Breakpoint
)
Clear
(
thread
*
Thread
Context
)
(
*
Breakpoint
,
error
)
{
func
(
bp
*
Breakpoint
)
Clear
(
thread
*
Thread
)
(
*
Breakpoint
,
error
)
{
if
bp
.
hardware
{
if
err
:=
clearHardwareBreakpoint
(
bp
.
reg
,
thread
.
Id
);
err
!=
nil
{
return
nil
,
err
...
...
proc/proc.go
浏览文件 @
e5233e72
...
...
@@ -29,11 +29,11 @@ type DebuggedProcess struct {
// Software breakpoint table. Hardware breakpoints are stored in proc/arch.go, as they are architecture dependant.
Breakpoints
map
[
uint64
]
*
Breakpoint
// List of threads mapped as such: pid -> *Thread
Context
Threads
map
[
int
]
*
Thread
Context
// List of threads mapped as such: pid -> *Thread
Threads
map
[
int
]
*
Thread
// Active thread. This is the default thread used for setting breakpoints, evaluating variables, etc..
CurrentThread
*
Thread
Context
CurrentThread
*
Thread
dwarf
*
dwarf
.
Data
goSymTable
*
gosym
.
Table
...
...
@@ -74,7 +74,7 @@ func (pe ProcessExitedError) Error() string {
func
Attach
(
pid
int
)
(
*
DebuggedProcess
,
error
)
{
dbp
:=
&
DebuggedProcess
{
Pid
:
pid
,
Threads
:
make
(
map
[
int
]
*
Thread
Context
),
Threads
:
make
(
map
[
int
]
*
Thread
),
Breakpoints
:
make
(
map
[
uint64
]
*
Breakpoint
),
os
:
new
(
OSProcessDetails
),
ast
:
source
.
New
(),
...
...
@@ -565,7 +565,7 @@ func (dbp *DebuggedProcess) clearTempBreakpoints() error {
return
nil
}
func
(
dbp
*
DebuggedProcess
)
handleBreakpointOnThread
(
id
int
)
(
*
Thread
Context
,
error
)
{
func
(
dbp
*
DebuggedProcess
)
handleBreakpointOnThread
(
id
int
)
(
*
Thread
,
error
)
{
thread
,
ok
:=
dbp
.
Threads
[
id
]
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"could not find thread for %d"
,
id
)
...
...
proc/proc_darwin.go
浏览文件 @
e5233e72
...
...
@@ -45,7 +45,7 @@ func Launch(cmd []string) (*DebuggedProcess, error) {
argv
=
&
argvSlice
[
0
]
dbp
:=
&
DebuggedProcess
{
Threads
:
make
(
map
[
int
]
*
Thread
Context
),
Threads
:
make
(
map
[
int
]
*
Thread
),
Breakpoints
:
make
(
map
[
uint64
]
*
Breakpoint
),
firstStart
:
true
,
os
:
new
(
OSProcessDetails
),
...
...
@@ -116,11 +116,11 @@ func (dbp *DebuggedProcess) updateThreadList() error {
return
nil
}
func
(
dbp
*
DebuggedProcess
)
addThread
(
port
int
,
attach
bool
)
(
*
Thread
Context
,
error
)
{
func
(
dbp
*
DebuggedProcess
)
addThread
(
port
int
,
attach
bool
)
(
*
Thread
,
error
)
{
if
thread
,
ok
:=
dbp
.
Threads
[
port
];
ok
{
return
thread
,
nil
}
thread
:=
&
Thread
Context
{
thread
:=
&
Thread
{
Id
:
port
,
dbp
:
dbp
,
os
:
new
(
OSSpecificDetails
),
...
...
@@ -216,9 +216,9 @@ func (dbp *DebuggedProcess) findExecutable(path string) (*macho.File, error) {
return
exe
,
nil
}
func
(
dbp
*
DebuggedProcess
)
trapWait
(
pid
int
)
(
*
Thread
Context
,
error
)
{
func
(
dbp
*
DebuggedProcess
)
trapWait
(
pid
int
)
(
*
Thread
,
error
)
{
var
(
th
*
Thread
Context
th
*
Thread
err
error
)
for
{
...
...
proc/proc_linux.go
浏览文件 @
e5233e72
...
...
@@ -46,7 +46,7 @@ func Launch(cmd []string) (*DebuggedProcess, error) {
}
dbp
:=
&
DebuggedProcess
{
Pid
:
proc
.
Process
.
Pid
,
Threads
:
make
(
map
[
int
]
*
Thread
Context
),
Threads
:
make
(
map
[
int
]
*
Thread
),
Breakpoints
:
make
(
map
[
uint64
]
*
Breakpoint
),
os
:
new
(
OSProcessDetails
),
ast
:
source
.
New
(),
...
...
@@ -61,7 +61,7 @@ func (dbp *DebuggedProcess) requestManualStop() (err error) {
// Attach to a newly created thread, and store that thread in our list of
// known threads.
func
(
dbp
*
DebuggedProcess
)
addThread
(
tid
int
,
attach
bool
)
(
*
Thread
Context
,
error
)
{
func
(
dbp
*
DebuggedProcess
)
addThread
(
tid
int
,
attach
bool
)
(
*
Thread
,
error
)
{
if
thread
,
ok
:=
dbp
.
Threads
[
tid
];
ok
{
return
thread
,
nil
}
...
...
@@ -99,7 +99,7 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err
}
}
dbp
.
Threads
[
tid
]
=
&
Thread
Context
{
dbp
.
Threads
[
tid
]
=
&
Thread
{
Id
:
tid
,
dbp
:
dbp
,
os
:
new
(
OSSpecificDetails
),
...
...
@@ -221,7 +221,7 @@ func (dbp *DebuggedProcess) parseDebugLineInfo(exe *elf.File, wg *sync.WaitGroup
}
}
func
(
dbp
*
DebuggedProcess
)
trapWait
(
pid
int
)
(
*
Thread
Context
,
error
)
{
func
(
dbp
*
DebuggedProcess
)
trapWait
(
pid
int
)
(
*
Thread
,
error
)
{
for
{
wpid
,
status
,
err
:=
wait
(
pid
,
0
)
if
err
!=
nil
{
...
...
proc/proc_test.go
浏览文件 @
e5233e72
...
...
@@ -37,7 +37,7 @@ func getRegisters(p *DebuggedProcess, t *testing.T) Registers {
return
regs
}
func
dataAtAddr
(
thread
*
Thread
Context
,
addr
uint64
)
([]
byte
,
error
)
{
func
dataAtAddr
(
thread
*
Thread
,
addr
uint64
)
([]
byte
,
error
)
{
data
:=
make
([]
byte
,
1
)
_
,
err
:=
readMemory
(
thread
,
uintptr
(
addr
),
data
)
if
err
!=
nil
{
...
...
proc/registers.go
浏览文件 @
e5233e72
...
...
@@ -10,11 +10,11 @@ type Registers interface {
PC
()
uint64
SP
()
uint64
CX
()
uint64
SetPC
(
*
Thread
Context
,
uint64
)
error
SetPC
(
*
Thread
,
uint64
)
error
}
// Obtains register values from the debugged process.
func
(
thread
*
Thread
Context
)
Registers
()
(
Registers
,
error
)
{
func
(
thread
*
Thread
)
Registers
()
(
Registers
,
error
)
{
regs
,
err
:=
registers
(
thread
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"could not get registers: %s"
,
err
)
...
...
@@ -23,7 +23,7 @@ func (thread *ThreadContext) Registers() (Registers, error) {
}
// Returns the current PC for this thread.
func
(
thread
*
Thread
Context
)
PC
()
(
uint64
,
error
)
{
func
(
thread
*
Thread
)
PC
()
(
uint64
,
error
)
{
regs
,
err
:=
thread
.
Registers
()
if
err
!=
nil
{
return
0
,
err
...
...
proc/registers_darwin_amd64.go
浏览文件 @
e5233e72
...
...
@@ -20,7 +20,7 @@ func (r *Regs) CX() uint64 {
return
r
.
cx
}
func
(
r
*
Regs
)
SetPC
(
thread
*
Thread
Context
,
pc
uint64
)
error
{
func
(
r
*
Regs
)
SetPC
(
thread
*
Thread
,
pc
uint64
)
error
{
kret
:=
C
.
set_pc
(
thread
.
os
.
thread_act
,
C
.
uint64_t
(
pc
))
if
kret
!=
C
.
KERN_SUCCESS
{
return
fmt
.
Errorf
(
"could not set pc"
)
...
...
@@ -28,7 +28,7 @@ func (r *Regs) SetPC(thread *ThreadContext, pc uint64) error {
return
nil
}
func
registers
(
thread
*
Thread
Context
)
(
Registers
,
error
)
{
func
registers
(
thread
*
Thread
)
(
Registers
,
error
)
{
var
state
C
.
x86_thread_state64_t
kret
:=
C
.
get_registers
(
C
.
mach_port_name_t
(
thread
.
os
.
thread_act
),
&
state
)
if
kret
!=
C
.
KERN_SUCCESS
{
...
...
proc/registers_linux_amd64.go
浏览文件 @
e5233e72
...
...
@@ -18,12 +18,12 @@ func (r *Regs) CX() uint64 {
return
r
.
regs
.
Rcx
}
func
(
r
*
Regs
)
SetPC
(
thread
*
Thread
Context
,
pc
uint64
)
error
{
func
(
r
*
Regs
)
SetPC
(
thread
*
Thread
,
pc
uint64
)
error
{
r
.
regs
.
SetPC
(
pc
)
return
sys
.
PtraceSetRegs
(
thread
.
Id
,
r
.
regs
)
}
func
registers
(
thread
*
Thread
Context
)
(
Registers
,
error
)
{
func
registers
(
thread
*
Thread
)
(
Registers
,
error
)
{
var
regs
sys
.
PtraceRegs
err
:=
sys
.
PtraceGetRegs
(
thread
.
Id
,
&
regs
)
if
err
!=
nil
{
...
...
proc/stack.go
浏览文件 @
e5233e72
...
...
@@ -14,7 +14,7 @@ type stackLocation struct {
// Takes an offset from RSP and returns the address of the
// instruction the currect function is going to return to.
func
(
thread
*
Thread
Context
)
ReturnAddress
()
(
uint64
,
error
)
{
func
(
thread
*
Thread
)
ReturnAddress
()
(
uint64
,
error
)
{
regs
,
err
:=
thread
.
Registers
()
if
err
!=
nil
{
return
0
,
err
...
...
proc/threads.go
浏览文件 @
e5233e72
...
...
@@ -10,12 +10,12 @@ import (
sys
"golang.org/x/sys/unix"
)
// Thread
Context
represents a single thread in the traced process
// Id represents the thread id, Process holds a reference to the
// Thread represents a single thread in the traced process
// Id represents the thread id
or port
, Process holds a reference to the
// DebuggedProcess struct that contains info on the process as
// a whole, and Status represents the last result of a `wait` call
// on this thread.
type
Thread
Context
struct
{
type
Thread
struct
{
Id
int
Status
*
sys
.
WaitStatus
CurrentBreakpoint
*
Breakpoint
...
...
@@ -36,7 +36,7 @@ type Location struct {
// software breakpoints into consideration and ensures that
// we step over any breakpoints. It will restore the instruction,
// step, and then restore the breakpoint and continue.
func
(
thread
*
Thread
Context
)
Continue
()
error
{
func
(
thread
*
Thread
)
Continue
()
error
{
pc
,
err
:=
thread
.
PC
()
if
err
!=
nil
{
return
err
...
...
@@ -54,7 +54,7 @@ func (thread *ThreadContext) Continue() error {
// Single steps this thread a single instruction, ensuring that
// we correctly handle the likely case that we are at a breakpoint.
func
(
thread
*
Thread
Context
)
Step
()
(
err
error
)
{
func
(
thread
*
Thread
)
Step
()
(
err
error
)
{
thread
.
singleStepping
=
true
defer
func
()
{
thread
.
singleStepping
=
false
}()
pc
,
err
:=
thread
.
PC
()
...
...
@@ -86,21 +86,21 @@ func (thread *ThreadContext) Step() (err error) {
}
// Set breakpoint using this thread.
func
(
thread
*
Thread
Context
)
Break
(
addr
uint64
)
(
*
Breakpoint
,
error
)
{
func
(
thread
*
Thread
)
Break
(
addr
uint64
)
(
*
Breakpoint
,
error
)
{
return
thread
.
dbp
.
setBreakpoint
(
thread
.
Id
,
addr
,
false
)
}
// Set breakpoint using this thread.
func
(
thread
*
Thread
Context
)
TempBreak
(
addr
uint64
)
(
*
Breakpoint
,
error
)
{
func
(
thread
*
Thread
)
TempBreak
(
addr
uint64
)
(
*
Breakpoint
,
error
)
{
return
thread
.
dbp
.
setBreakpoint
(
thread
.
Id
,
addr
,
true
)
}
// Clear breakpoint using this thread.
func
(
thread
*
Thread
Context
)
Clear
(
addr
uint64
)
(
*
Breakpoint
,
error
)
{
func
(
thread
*
Thread
)
Clear
(
addr
uint64
)
(
*
Breakpoint
,
error
)
{
return
thread
.
dbp
.
clearBreakpoint
(
thread
.
Id
,
addr
)
}
func
(
thread
*
Thread
Context
)
Location
()
(
*
Location
,
error
)
{
func
(
thread
*
Thread
)
Location
()
(
*
Location
,
error
)
{
pc
,
err
:=
thread
.
PC
()
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -117,7 +117,7 @@ func (thread *ThreadContext) Location() (*Location, error) {
// This functionality is implemented by finding all possible next lines
// and setting a breakpoint at them. Once we've set a breakpoint at each
// potential line, we continue the thread.
func
(
thread
*
Thread
Context
)
SetNextBreakpoints
()
(
err
error
)
{
func
(
thread
*
Thread
)
SetNextBreakpoints
()
(
err
error
)
{
curpc
,
err
:=
thread
.
PC
()
if
err
!=
nil
{
return
err
...
...
@@ -158,7 +158,7 @@ func (ge GoroutineExitingError) Error() string {
// This version of next uses the AST from the current source file to figure out all of the potential source lines
// we could end up at.
func
(
thread
*
Thread
Context
)
next
(
curpc
uint64
,
fde
*
frame
.
FrameDescriptionEntry
,
file
string
,
line
int
)
error
{
func
(
thread
*
Thread
)
next
(
curpc
uint64
,
fde
*
frame
.
FrameDescriptionEntry
,
file
string
,
line
int
)
error
{
lines
,
err
:=
thread
.
dbp
.
ast
.
NextLines
(
file
,
line
)
if
err
!=
nil
{
if
_
,
ok
:=
err
.
(
source
.
NoNodeError
);
!
ok
{
...
...
@@ -201,7 +201,7 @@ func (thread *ThreadContext) next(curpc uint64, fde *frame.FrameDescriptionEntry
// Set a breakpoint at every reachable location, as well as the return address. Without
// the benefit of an AST we can't be sure we're not at a branching statement and thus
// cannot accurately predict where we may end up.
func
(
thread
*
Thread
Context
)
cnext
(
curpc
uint64
,
fde
*
frame
.
FrameDescriptionEntry
)
error
{
func
(
thread
*
Thread
)
cnext
(
curpc
uint64
,
fde
*
frame
.
FrameDescriptionEntry
)
error
{
pcs
:=
thread
.
dbp
.
lineInfo
.
AllPCsBetween
(
fde
.
Begin
(),
fde
.
End
())
ret
,
err
:=
thread
.
ReturnAddress
()
if
err
!=
nil
{
...
...
@@ -211,7 +211,7 @@ func (thread *ThreadContext) cnext(curpc uint64, fde *frame.FrameDescriptionEntr
return
thread
.
setNextTempBreakpoints
(
curpc
,
pcs
)
}
func
(
thread
*
Thread
Context
)
setNextTempBreakpoints
(
curpc
uint64
,
pcs
[]
uint64
)
error
{
func
(
thread
*
Thread
)
setNextTempBreakpoints
(
curpc
uint64
,
pcs
[]
uint64
)
error
{
for
i
:=
range
pcs
{
if
pcs
[
i
]
==
curpc
||
pcs
[
i
]
==
curpc
-
1
{
continue
...
...
@@ -226,7 +226,7 @@ func (thread *ThreadContext) setNextTempBreakpoints(curpc uint64, pcs []uint64)
}
// Sets the PC for this thread.
func
(
thread
*
Thread
Context
)
SetPC
(
pc
uint64
)
error
{
func
(
thread
*
Thread
)
SetPC
(
pc
uint64
)
error
{
regs
,
err
:=
thread
.
Registers
()
if
err
!=
nil
{
return
err
...
...
@@ -252,7 +252,7 @@ func (thread *ThreadContext) SetPC(pc uint64) error {
// current instruction stream. The instructions are obviously arch/os dependant, as they
// vary on how thread local storage is implemented, which MMU register is used and
// what the offset into thread local storage is.
func
(
thread
*
Thread
Context
)
getG
()
(
g
*
G
,
err
error
)
{
func
(
thread
*
Thread
)
getG
()
(
g
*
G
,
err
error
)
{
var
pcInt
uint64
pcInt
,
err
=
thread
.
PC
()
if
err
!=
nil
{
...
...
proc/threads_darwin.go
浏览文件 @
e5233e72
...
...
@@ -12,7 +12,7 @@ type OSSpecificDetails struct {
registers
C
.
x86_thread_state64_t
}
func
(
t
*
Thread
Context
)
Halt
()
error
{
func
(
t
*
Thread
)
Halt
()
error
{
var
kret
C
.
kern_return_t
kret
=
C
.
thread_suspend
(
t
.
os
.
thread_act
)
if
kret
!=
C
.
KERN_SUCCESS
{
...
...
@@ -21,7 +21,7 @@ func (t *ThreadContext) Halt() error {
return
nil
}
func
(
t
*
Thread
Context
)
singleStep
()
error
{
func
(
t
*
Thread
)
singleStep
()
error
{
kret
:=
C
.
single_step
(
t
.
os
.
thread_act
)
if
kret
!=
C
.
KERN_SUCCESS
{
return
fmt
.
Errorf
(
"could not single step"
)
...
...
@@ -34,7 +34,7 @@ func (t *ThreadContext) singleStep() error {
return
nil
}
func
(
t
*
Thread
Context
)
resume
()
error
{
func
(
t
*
Thread
)
resume
()
error
{
// TODO(dp) set flag for ptrace stops
if
PtraceCont
(
t
.
dbp
.
Pid
,
0
)
==
nil
{
return
nil
...
...
@@ -46,7 +46,7 @@ func (t *ThreadContext) resume() error {
return
nil
}
func
(
t
*
Thread
Context
)
blocked
()
bool
{
func
(
t
*
Thread
)
blocked
()
bool
{
// TODO(dp) cache the func pc to remove this lookup
pc
,
_
:=
t
.
PC
()
fn
:=
t
.
dbp
.
goSymTable
.
PCToFunc
(
pc
)
...
...
@@ -56,7 +56,7 @@ func (t *ThreadContext) blocked() bool {
return
false
}
func
writeMemory
(
thread
*
Thread
Context
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
func
writeMemory
(
thread
*
Thread
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
if
len
(
data
)
==
0
{
return
0
,
nil
}
...
...
@@ -71,7 +71,7 @@ func writeMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error)
return
len
(
data
),
nil
}
func
readMemory
(
thread
*
Thread
Context
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
func
readMemory
(
thread
*
Thread
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
if
len
(
data
)
==
0
{
return
0
,
nil
}
...
...
@@ -88,7 +88,7 @@ func readMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error) {
return
len
(
data
),
nil
}
func
(
thread
*
Thread
Context
)
saveRegisters
()
(
Registers
,
error
)
{
func
(
thread
*
Thread
)
saveRegisters
()
(
Registers
,
error
)
{
kret
:=
C
.
get_registers
(
C
.
mach_port_name_t
(
thread
.
os
.
thread_act
),
&
thread
.
os
.
registers
)
if
kret
!=
C
.
KERN_SUCCESS
{
return
nil
,
fmt
.
Errorf
(
"could not save register contents"
)
...
...
@@ -96,7 +96,7 @@ func (thread *ThreadContext) saveRegisters() (Registers, error) {
return
&
Regs
{
pc
:
uint64
(
thread
.
os
.
registers
.
__rip
),
sp
:
uint64
(
thread
.
os
.
registers
.
__rsp
)},
nil
}
func
(
thread
*
Thread
Context
)
restoreRegisters
()
error
{
func
(
thread
*
Thread
)
restoreRegisters
()
error
{
kret
:=
C
.
set_registers
(
C
.
mach_port_name_t
(
thread
.
os
.
thread_act
),
&
thread
.
os
.
registers
)
if
kret
!=
C
.
KERN_SUCCESS
{
return
fmt
.
Errorf
(
"could not save register contents"
)
...
...
proc/threads_linux.go
浏览文件 @
e5233e72
...
...
@@ -12,7 +12,7 @@ type OSSpecificDetails struct {
registers
sys
.
PtraceRegs
}
func
(
t
*
Thread
Context
)
Halt
()
error
{
func
(
t
*
Thread
)
Halt
()
error
{
if
stopped
(
t
.
Id
)
{
return
nil
}
...
...
@@ -27,11 +27,11 @@ func (t *ThreadContext) Halt() error {
return
nil
}
func
(
t
*
Thread
Context
)
resume
()
error
{
func
(
t
*
Thread
)
resume
()
error
{
return
PtraceCont
(
t
.
Id
,
0
)
}
func
(
t
*
Thread
Context
)
singleStep
()
error
{
func
(
t
*
Thread
)
singleStep
()
error
{
err
:=
sys
.
PtraceSingleStep
(
t
.
Id
)
if
err
!=
nil
{
return
err
...
...
@@ -40,7 +40,7 @@ func (t *ThreadContext) singleStep() error {
return
err
}
func
(
t
*
Thread
Context
)
blocked
()
bool
{
func
(
t
*
Thread
)
blocked
()
bool
{
// TODO(dp) cache the func pc to remove this lookup
pc
,
_
:=
t
.
PC
()
fn
:=
t
.
dbp
.
goSymTable
.
PCToFunc
(
pc
)
...
...
@@ -50,25 +50,25 @@ func (t *ThreadContext) blocked() bool {
return
false
}
func
(
thread
*
Thread
Context
)
saveRegisters
()
(
Registers
,
error
)
{
func
(
thread
*
Thread
)
saveRegisters
()
(
Registers
,
error
)
{
if
err
:=
sys
.
PtraceGetRegs
(
thread
.
Id
,
&
thread
.
os
.
registers
);
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"could not save register contents"
)
}
return
&
Regs
{
&
thread
.
os
.
registers
},
nil
}
func
(
thread
*
Thread
Context
)
restoreRegisters
()
error
{
func
(
thread
*
Thread
)
restoreRegisters
()
error
{
return
sys
.
PtraceSetRegs
(
thread
.
Id
,
&
thread
.
os
.
registers
)
}
func
writeMemory
(
thread
*
Thread
Context
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
func
writeMemory
(
thread
*
Thread
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
if
len
(
data
)
==
0
{
return
0
,
nil
}
return
sys
.
PtracePokeData
(
thread
.
Id
,
addr
,
data
)
}
func
readMemory
(
thread
*
Thread
Context
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
func
readMemory
(
thread
*
Thread
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
if
len
(
data
)
==
0
{
return
0
,
nil
}
...
...
proc/variables.go
浏览文件 @
e5233e72
...
...
@@ -81,7 +81,7 @@ func (ng NoGError) Error() string {
return
fmt
.
Sprintf
(
"no G executing on thread %d"
,
ng
.
tid
)
}
func
parseG
(
thread
*
Thread
Context
,
gaddr
uint64
,
deref
bool
)
(
*
G
,
error
)
{
func
parseG
(
thread
*
Thread
,
gaddr
uint64
,
deref
bool
)
(
*
G
,
error
)
{
initialInstructions
:=
make
([]
byte
,
thread
.
dbp
.
arch
.
PtrSize
()
+
1
)
initialInstructions
[
0
]
=
op
.
DW_OP_addr
binary
.
LittleEndian
.
PutUint64
(
initialInstructions
[
1
:
],
gaddr
)
...
...
@@ -198,7 +198,7 @@ func parseG(thread *ThreadContext, gaddr uint64, deref bool) (*G, error) {
}
// Returns the value of the named variable.
func
(
thread
*
Thread
Context
)
EvalVariable
(
name
string
)
(
*
Variable
,
error
)
{
func
(
thread
*
Thread
)
EvalVariable
(
name
string
)
(
*
Variable
,
error
)
{
pc
,
err
:=
thread
.
PC
()
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -241,17 +241,17 @@ func (thread *ThreadContext) EvalVariable(name string) (*Variable, error) {
}
// LocalVariables returns all local variables from the current function scope.
func
(
thread
*
Thread
Context
)
LocalVariables
()
([]
*
Variable
,
error
)
{
func
(
thread
*
Thread
)
LocalVariables
()
([]
*
Variable
,
error
)
{
return
thread
.
variablesByTag
(
dwarf
.
TagVariable
)
}
// FunctionArguments returns the name, value, and type of all current function arguments.
func
(
thread
*
Thread
Context
)
FunctionArguments
()
([]
*
Variable
,
error
)
{
func
(
thread
*
Thread
)
FunctionArguments
()
([]
*
Variable
,
error
)
{
return
thread
.
variablesByTag
(
dwarf
.
TagFormalParameter
)
}
// PackageVariables returns the name, value, and type of all package variables in the application.
func
(
thread
*
Thread
Context
)
PackageVariables
()
([]
*
Variable
,
error
)
{
func
(
thread
*
Thread
)
PackageVariables
()
([]
*
Variable
,
error
)
{
reader
:=
thread
.
dbp
.
DwarfReader
()
vars
:=
make
([]
*
Variable
,
0
)
...
...
@@ -272,7 +272,7 @@ func (thread *ThreadContext) PackageVariables() ([]*Variable, error) {
return
vars
,
nil
}
func
(
thread
*
Thread
Context
)
evaluateStructMember
(
parentEntry
*
dwarf
.
Entry
,
rdr
*
reader
.
Reader
,
memberName
string
)
(
*
Variable
,
error
)
{
func
(
thread
*
Thread
)
evaluateStructMember
(
parentEntry
*
dwarf
.
Entry
,
rdr
*
reader
.
Reader
,
memberName
string
)
(
*
Variable
,
error
)
{
parentAddr
,
err
:=
thread
.
extractVariableDataAddress
(
parentEntry
,
rdr
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -339,7 +339,7 @@ func (thread *ThreadContext) evaluateStructMember(parentEntry *dwarf.Entry, rdr
}
// Extracts the name, type, and value of a variable from a dwarf entry
func
(
thread
*
Thread
Context
)
extractVariableFromEntry
(
entry
*
dwarf
.
Entry
)
(
*
Variable
,
error
)
{
func
(
thread
*
Thread
)
extractVariableFromEntry
(
entry
*
dwarf
.
Entry
)
(
*
Variable
,
error
)
{
if
entry
==
nil
{
return
nil
,
fmt
.
Errorf
(
"invalid entry"
)
}
...
...
@@ -378,7 +378,7 @@ func (thread *ThreadContext) extractVariableFromEntry(entry *dwarf.Entry) (*Vari
}
// Execute the stack program taking into account the current stack frame
func
(
thread
*
Thread
Context
)
executeStackProgram
(
instructions
[]
byte
)
(
int64
,
error
)
{
func
(
thread
*
Thread
)
executeStackProgram
(
instructions
[]
byte
)
(
int64
,
error
)
{
regs
,
err
:=
thread
.
Registers
()
if
err
!=
nil
{
return
0
,
err
...
...
@@ -399,7 +399,7 @@ func (thread *ThreadContext) executeStackProgram(instructions []byte) (int64, er
}
// Extracts the address of a variable, dereferencing any pointers
func
(
thread
*
Thread
Context
)
extractVariableDataAddress
(
entry
*
dwarf
.
Entry
,
rdr
*
reader
.
Reader
)
(
int64
,
error
)
{
func
(
thread
*
Thread
)
extractVariableDataAddress
(
entry
*
dwarf
.
Entry
,
rdr
*
reader
.
Reader
)
(
int64
,
error
)
{
instructions
,
err
:=
rdr
.
InstructionsForEntry
(
entry
)
if
err
!=
nil
{
return
0
,
err
...
...
@@ -435,11 +435,11 @@ func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, rdr
// Extracts the value from the instructions given in the DW_AT_location entry.
// We execute the stack program described in the DW_OP_* instruction stream, and
// then grab the value from the other processes memory.
func
(
thread
*
Thread
Context
)
extractValue
(
instructions
[]
byte
,
addr
int64
,
typ
interface
{},
printStructName
bool
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
extractValue
(
instructions
[]
byte
,
addr
int64
,
typ
interface
{},
printStructName
bool
)
(
string
,
error
)
{
return
thread
.
extractValueInternal
(
instructions
,
addr
,
typ
,
printStructName
,
0
)
}
func
(
thread
*
Thread
Context
)
extractValueInternal
(
instructions
[]
byte
,
addr
int64
,
typ
interface
{},
printStructName
bool
,
recurseLevel
int
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
extractValueInternal
(
instructions
[]
byte
,
addr
int64
,
typ
interface
{},
printStructName
bool
,
recurseLevel
int
)
(
string
,
error
)
{
var
err
error
if
addr
==
0
{
...
...
@@ -532,7 +532,7 @@ func (thread *ThreadContext) extractValueInternal(instructions []byte, addr int6
return
""
,
fmt
.
Errorf
(
"could not find value for type %s"
,
typ
)
}
func
(
thread
*
Thread
Context
)
readString
(
addr
uintptr
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readString
(
addr
uintptr
)
(
string
,
error
)
{
// string data structure is always two ptrs in size. Addr, followed by len
// http://research.swtch.com/godata
...
...
@@ -561,7 +561,7 @@ func (thread *ThreadContext) readString(addr uintptr) (string, error) {
return
*
(
*
string
)(
unsafe
.
Pointer
(
&
val
)),
nil
}
func
(
thread
*
Thread
Context
)
readSlice
(
addr
uintptr
,
t
*
dwarf
.
StructType
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readSlice
(
addr
uintptr
,
t
*
dwarf
.
StructType
)
(
string
,
error
)
{
var
sliceLen
,
sliceCap
int64
var
arrayAddr
uintptr
var
arrayType
dwarf
.
Type
...
...
@@ -612,7 +612,7 @@ func (thread *ThreadContext) readSlice(addr uintptr, t *dwarf.StructType) (strin
return
fmt
.
Sprintf
(
"[]%s len: %d, cap: %d, [%s]"
,
arrayType
,
sliceLen
,
sliceCap
,
strings
.
Join
(
vals
,
","
)),
nil
}
func
(
thread
*
Thread
Context
)
readArray
(
addr
uintptr
,
t
*
dwarf
.
ArrayType
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readArray
(
addr
uintptr
,
t
*
dwarf
.
ArrayType
)
(
string
,
error
)
{
if
t
.
Count
>
0
{
vals
,
err
:=
thread
.
readArrayValues
(
addr
,
t
.
Count
,
t
.
ByteSize
/
t
.
Count
,
t
.
Type
)
if
err
!=
nil
{
...
...
@@ -624,7 +624,7 @@ func (thread *ThreadContext) readArray(addr uintptr, t *dwarf.ArrayType) (string
return
fmt
.
Sprintf
(
"%s []"
,
t
),
nil
}
func
(
thread
*
Thread
Context
)
readArrayValues
(
addr
uintptr
,
count
int64
,
stride
int64
,
t
dwarf
.
Type
)
([]
string
,
error
)
{
func
(
thread
*
Thread
)
readArrayValues
(
addr
uintptr
,
count
int64
,
stride
int64
,
t
dwarf
.
Type
)
([]
string
,
error
)
{
vals
:=
make
([]
string
,
0
)
for
i
:=
int64
(
0
);
i
<
count
;
i
++
{
...
...
@@ -643,7 +643,7 @@ func (thread *ThreadContext) readArrayValues(addr uintptr, count int64, stride i
return
vals
,
nil
}
func
(
thread
*
Thread
Context
)
readInt
(
addr
uintptr
,
size
int64
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readInt
(
addr
uintptr
,
size
int64
)
(
string
,
error
)
{
n
,
err
:=
thread
.
readIntRaw
(
addr
,
size
)
if
err
!=
nil
{
return
""
,
err
...
...
@@ -651,7 +651,7 @@ func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) {
return
strconv
.
FormatInt
(
n
,
10
),
nil
}
func
(
thread
*
Thread
Context
)
readIntRaw
(
addr
uintptr
,
size
int64
)
(
int64
,
error
)
{
func
(
thread
*
Thread
)
readIntRaw
(
addr
uintptr
,
size
int64
)
(
int64
,
error
)
{
var
n
int64
val
,
err
:=
thread
.
readMemory
(
addr
,
int
(
size
))
...
...
@@ -673,7 +673,7 @@ func (thread *ThreadContext) readIntRaw(addr uintptr, size int64) (int64, error)
return
n
,
nil
}
func
(
thread
*
Thread
Context
)
readUint
(
addr
uintptr
,
size
int64
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readUint
(
addr
uintptr
,
size
int64
)
(
string
,
error
)
{
n
,
err
:=
thread
.
readUintRaw
(
addr
,
size
)
if
err
!=
nil
{
return
""
,
err
...
...
@@ -681,7 +681,7 @@ func (thread *ThreadContext) readUint(addr uintptr, size int64) (string, error)
return
strconv
.
FormatUint
(
n
,
10
),
nil
}
func
(
thread
*
Thread
Context
)
readUintRaw
(
addr
uintptr
,
size
int64
)
(
uint64
,
error
)
{
func
(
thread
*
Thread
)
readUintRaw
(
addr
uintptr
,
size
int64
)
(
uint64
,
error
)
{
var
n
uint64
val
,
err
:=
thread
.
readMemory
(
addr
,
int
(
size
))
...
...
@@ -703,7 +703,7 @@ func (thread *ThreadContext) readUintRaw(addr uintptr, size int64) (uint64, erro
return
n
,
nil
}
func
(
thread
*
Thread
Context
)
readFloat
(
addr
uintptr
,
size
int64
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readFloat
(
addr
uintptr
,
size
int64
)
(
string
,
error
)
{
val
,
err
:=
thread
.
readMemory
(
addr
,
int
(
size
))
if
err
!=
nil
{
return
""
,
err
...
...
@@ -724,7 +724,7 @@ func (thread *ThreadContext) readFloat(addr uintptr, size int64) (string, error)
return
""
,
fmt
.
Errorf
(
"could not read float"
)
}
func
(
thread
*
Thread
Context
)
readBool
(
addr
uintptr
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readBool
(
addr
uintptr
)
(
string
,
error
)
{
val
,
err
:=
thread
.
readMemory
(
addr
,
1
)
if
err
!=
nil
{
return
""
,
err
...
...
@@ -737,7 +737,7 @@ func (thread *ThreadContext) readBool(addr uintptr) (string, error) {
return
"true"
,
nil
}
func
(
thread
*
Thread
Context
)
readFunctionPtr
(
addr
uintptr
)
(
string
,
error
)
{
func
(
thread
*
Thread
)
readFunctionPtr
(
addr
uintptr
)
(
string
,
error
)
{
val
,
err
:=
thread
.
readMemory
(
addr
,
thread
.
dbp
.
arch
.
PtrSize
())
if
err
!=
nil
{
return
""
,
err
...
...
@@ -763,7 +763,7 @@ func (thread *ThreadContext) readFunctionPtr(addr uintptr) (string, error) {
return
fn
.
Name
,
nil
}
func
(
thread
*
Thread
Context
)
readMemory
(
addr
uintptr
,
size
int
)
([]
byte
,
error
)
{
func
(
thread
*
Thread
)
readMemory
(
addr
uintptr
,
size
int
)
([]
byte
,
error
)
{
if
size
==
0
{
return
nil
,
nil
}
...
...
@@ -777,7 +777,7 @@ func (thread *ThreadContext) readMemory(addr uintptr, size int) ([]byte, error)
}
// Fetches all variables of a specific type in the current function scope
func
(
thread
*
Thread
Context
)
variablesByTag
(
tag
dwarf
.
Tag
)
([]
*
Variable
,
error
)
{
func
(
thread
*
Thread
)
variablesByTag
(
tag
dwarf
.
Tag
)
([]
*
Variable
,
error
)
{
pc
,
err
:=
thread
.
PC
()
if
err
!=
nil
{
return
nil
,
err
...
...
proc/variables_test.go
浏览文件 @
e5233e72
...
...
@@ -145,10 +145,10 @@ func (s varArray) Less(i, j int) bool {
func
TestLocalVariables
(
t
*
testing
.
T
)
{
testcases
:=
[]
struct
{
fn
func
(
*
Thread
Context
)
([]
*
Variable
,
error
)
fn
func
(
*
Thread
)
([]
*
Variable
,
error
)
output
[]
varTest
}{
{(
*
Thread
Context
)
.
LocalVariables
,
{(
*
Thread
)
.
LocalVariables
,
[]
varTest
{
{
"a1"
,
"foofoofoofoofoofoo"
,
"struct string"
,
nil
},
{
"a10"
,
"ofo"
,
"struct string"
,
nil
},
...
...
@@ -177,7 +177,7 @@ func TestLocalVariables(t *testing.T) {
{
"u64"
,
"18446744073709551615"
,
"uint64"
,
nil
},
{
"u8"
,
"255"
,
"uint8"
,
nil
},
{
"up"
,
"5"
,
"uintptr"
,
nil
}}},
{(
*
Thread
Context
)
.
FunctionArguments
,
{(
*
Thread
)
.
FunctionArguments
,
[]
varTest
{
{
"bar"
,
"main.FooBar {Baz: 10, Bur: lorem}"
,
"main.FooBar"
,
nil
},
{
"baz"
,
"bazburzum"
,
"struct string"
,
nil
}}},
...
...
service/debugger/debugger.go
浏览文件 @
e5233e72
...
...
@@ -471,7 +471,7 @@ func convertBreakpoint(bp *proc.Breakpoint) *api.Breakpoint {
}
// convertThread converts an internal thread to an API Thread.
func
convertThread
(
th
*
proc
.
Thread
Context
)
*
api
.
Thread
{
func
convertThread
(
th
*
proc
.
Thread
)
*
api
.
Thread
{
var
(
function
*
api
.
Function
file
string
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录