Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
HugeYuan
delve
提交
450e5c48
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 搜索 >>
提交
450e5c48
编写于
2月 27, 2015
作者:
D
Derek Parker
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix linux compile errors
上级
35a0471f
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
70 addition
and
118 deletion
+70
-118
proctl/proctl.go
proctl/proctl.go
+39
-0
proctl/proctl_darwin.go
proctl/proctl_darwin.go
+0
-27
proctl/proctl_linux.go
proctl/proctl_linux.go
+6
-77
proctl/registers_linux_amd64.go
proctl/registers_linux_amd64.go
+4
-4
proctl/threads_linux.go
proctl/threads_linux.go
+21
-10
未找到文件。
proctl/proctl.go
浏览文件 @
450e5c48
...
@@ -52,6 +52,7 @@ func Attach(pid int) (*DebuggedProcess, error) {
...
@@ -52,6 +52,7 @@ func Attach(pid int) (*DebuggedProcess, error) {
return
nil
,
err
return
nil
,
err
}
}
// Attach to all currently active threads.
// Attach to all currently active threads.
// TODO(dp) doing this in newDebugProcess already for mach
if
err
:=
dbp
.
updateThreadList
();
err
!=
nil
{
if
err
:=
dbp
.
updateThreadList
();
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
@@ -289,6 +290,44 @@ func (dbp *DebuggedProcess) DwarfReader() *reader.Reader {
...
@@ -289,6 +290,44 @@ func (dbp *DebuggedProcess) DwarfReader() *reader.Reader {
return
reader
.
New
(
dbp
.
Dwarf
)
return
reader
.
New
(
dbp
.
Dwarf
)
}
}
// Returns a new DebuggedProcess struct.
func
newDebugProcess
(
pid
int
,
attach
bool
)
(
*
DebuggedProcess
,
error
)
{
dbp
:=
DebuggedProcess
{
Pid
:
pid
,
Threads
:
make
(
map
[
int
]
*
ThreadContext
),
BreakPoints
:
make
(
map
[
uint64
]
*
BreakPoint
),
os
:
new
(
OSProcessDetails
),
}
if
attach
{
err
:=
sys
.
PtraceAttach
(
pid
)
if
err
!=
nil
{
return
nil
,
err
}
_
,
_
,
err
=
wait
(
pid
,
0
)
if
err
!=
nil
{
return
nil
,
err
}
}
proc
,
err
:=
os
.
FindProcess
(
pid
)
if
err
!=
nil
{
return
nil
,
err
}
dbp
.
Process
=
proc
err
=
dbp
.
LoadInformation
()
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
dbp
.
updateThreadList
();
err
!=
nil
{
return
nil
,
err
}
return
&
dbp
,
nil
}
func
(
dbp
*
DebuggedProcess
)
run
(
fn
func
()
error
)
error
{
func
(
dbp
*
DebuggedProcess
)
run
(
fn
func
()
error
)
error
{
dbp
.
running
=
true
dbp
.
running
=
true
dbp
.
halt
=
false
dbp
.
halt
=
false
...
...
proctl/proctl_darwin.go
浏览文件 @
450e5c48
...
@@ -62,33 +62,6 @@ func (dbp *DebuggedProcess) LoadInformation() error {
...
@@ -62,33 +62,6 @@ func (dbp *DebuggedProcess) LoadInformation() error {
return
nil
return
nil
}
}
// Returns a new DebuggedProcess struct.
func
newDebugProcess
(
pid
int
,
attach
bool
)
(
*
DebuggedProcess
,
error
)
{
dbp
:=
DebuggedProcess
{
Pid
:
pid
,
Threads
:
make
(
map
[
int
]
*
ThreadContext
),
BreakPoints
:
make
(
map
[
uint64
]
*
BreakPoint
),
os
:
new
(
OSProcessDetails
),
}
proc
,
err
:=
os
.
FindProcess
(
pid
)
if
err
!=
nil
{
return
nil
,
err
}
dbp
.
Process
=
proc
err
=
dbp
.
LoadInformation
()
if
err
!=
nil
{
return
nil
,
err
}
if
err
:=
dbp
.
updateThreadList
();
err
!=
nil
{
return
nil
,
err
}
return
&
dbp
,
nil
}
func
(
dbp
*
DebuggedProcess
)
updateThreadList
()
error
{
func
(
dbp
*
DebuggedProcess
)
updateThreadList
()
error
{
var
(
var
(
err
error
err
error
...
...
proctl/proctl_linux.go
浏览文件 @
450e5c48
...
@@ -33,44 +33,6 @@ func (dbp *DebuggedProcess) Halt() (err error) {
...
@@ -33,44 +33,6 @@ func (dbp *DebuggedProcess) Halt() (err error) {
return
nil
return
nil
}
}
// Steps through process.
func
(
dbp
*
DebuggedProcess
)
Step
()
(
err
error
)
{
var
(
th
*
ThreadContext
ok
bool
)
allm
,
err
:=
dbp
.
CurrentThread
.
AllM
()
if
err
!=
nil
{
return
err
}
fn
:=
func
()
error
{
for
_
,
m
:=
range
allm
{
th
,
ok
=
dbp
.
Threads
[
m
.
procid
]
fmt
.
Println
(
ok
,
m
.
procid
)
if
!
ok
{
if
m
.
procid
==
0
{
// TODO(dp) might not work for linux
th
=
dbp
.
Threads
[
dbp
.
CurrentThread
.
Id
]
}
return
fmt
.
Errorf
(
"m->procid is invalid port"
)
}
if
m
.
blocked
==
0
{
err
:=
th
.
Step
()
if
err
!=
nil
{
return
err
}
}
}
return
nil
}
return
dbp
.
run
(
fn
)
}
// Finds the executable from /proc/<pid>/exe and then
// Finds the executable from /proc/<pid>/exe and then
// uses that to parse the following information:
// uses that to parse the following information:
// * Dwarf .debug_frame section
// * Dwarf .debug_frame section
...
@@ -144,19 +106,21 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err
...
@@ -144,19 +106,21 @@ func (dbp *DebuggedProcess) addThread(tid int, attach bool) (*ThreadContext, err
return
dbp
.
Threads
[
tid
],
nil
return
dbp
.
Threads
[
tid
],
nil
}
}
func
(
dbp
*
DebuggedProcess
)
refresh
ThreadList
()
error
{
func
(
dbp
*
DebuggedProcess
)
update
ThreadList
()
error
{
allm
,
err
:=
dbp
.
CurrentThread
.
AllM
()
allm
,
err
:=
dbp
.
CurrentThread
.
AllM
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
// TODO(dp) user /proc/<pid>/task to remove reliance on allm
for
_
,
m
:=
range
allm
{
for
_
,
m
:=
range
allm
{
if
t
id
==
0
{
if
m
.
proc
id
==
0
{
continue
continue
}
}
if
_
,
err
:=
dbp
.
addThread
(
m
.
procid
,
false
);
err
!=
nil
{
if
_
,
err
:=
dbp
.
addThread
(
m
.
procid
,
false
);
err
!=
nil
{
return
err
return
err
}
}
}
}
return
nil
}
}
func
(
dbp
*
DebuggedProcess
)
findExecutable
()
(
*
elf
.
File
,
error
)
{
func
(
dbp
*
DebuggedProcess
)
findExecutable
()
(
*
elf
.
File
,
error
)
{
...
@@ -232,46 +196,11 @@ func (dbp *DebuggedProcess) obtainGoSymbols(exe *elf.File, wg *sync.WaitGroup) {
...
@@ -232,46 +196,11 @@ func (dbp *DebuggedProcess) obtainGoSymbols(exe *elf.File, wg *sync.WaitGroup) {
dbp
.
GoSymTable
=
tab
dbp
.
GoSymTable
=
tab
}
}
func
newDebugProcess
(
pid
int
,
attach
bool
)
(
*
DebuggedProcess
,
error
)
{
// TODO(dp) seems like it could be unneccessary
dbp
:=
DebuggedProcess
{
Pid
:
pid
,
Threads
:
make
(
map
[
int
]
*
ThreadContext
),
BreakPoints
:
make
(
map
[
uint64
]
*
BreakPoint
),
os
:
new
(
OSProcessDetails
),
}
if
attach
{
thread
,
err
:=
dbp
.
AttachThread
(
pid
)
if
err
!=
nil
{
return
nil
,
err
}
dbp
.
CurrentThread
=
thread
}
else
{
thread
,
err
:=
dbp
.
addThread
(
pid
)
if
err
!=
nil
{
return
nil
,
err
}
dbp
.
CurrentThread
=
thread
}
proc
,
err
:=
os
.
FindProcess
(
pid
)
if
err
!=
nil
{
return
nil
,
err
}
dbp
.
Process
=
proc
err
=
dbp
.
LoadInformation
()
if
err
!=
nil
{
return
nil
,
err
}
return
&
dbp
,
nil
}
func
addNewThread
(
dbp
*
DebuggedProcess
,
cloner
,
cloned
int
)
error
{
func
addNewThread
(
dbp
*
DebuggedProcess
,
cloner
,
cloned
int
)
error
{
fmt
.
Println
(
"new thread spawned"
,
cloned
)
fmt
.
Println
(
"new thread spawned"
,
cloned
)
th
,
err
:=
dbp
.
addThread
(
cloned
)
th
,
err
:=
dbp
.
addThread
(
cloned
,
false
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
proctl/registers_linux_amd64.go
浏览文件 @
450e5c48
...
@@ -14,14 +14,14 @@ func (r *Regs) SP() uint64 {
...
@@ -14,14 +14,14 @@ func (r *Regs) SP() uint64 {
return
r
.
regs
.
Rsp
return
r
.
regs
.
Rsp
}
}
func
(
r
*
Regs
)
SetPC
(
t
id
in
t
,
pc
uint64
)
error
{
func
(
r
*
Regs
)
SetPC
(
t
hread
*
ThreadContex
t
,
pc
uint64
)
error
{
r
.
regs
.
SetPC
(
pc
)
r
.
regs
.
SetPC
(
pc
)
return
sys
.
PtraceSetRegs
(
t
i
d
,
r
.
regs
)
return
sys
.
PtraceSetRegs
(
t
hread
.
I
d
,
r
.
regs
)
}
}
func
registers
(
t
id
in
t
)
(
Registers
,
error
)
{
func
registers
(
t
hread
*
ThreadContex
t
)
(
Registers
,
error
)
{
var
regs
sys
.
PtraceRegs
var
regs
sys
.
PtraceRegs
err
:=
sys
.
PtraceGetRegs
(
t
i
d
,
&
regs
)
err
:=
sys
.
PtraceGetRegs
(
t
hread
.
I
d
,
&
regs
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
...
...
proctl/threads_linux.go
浏览文件 @
450e5c48
...
@@ -16,32 +16,43 @@ func (t *ThreadContext) Halt() error {
...
@@ -16,32 +16,43 @@ func (t *ThreadContext) Halt() error {
}
}
err
:=
sys
.
Tgkill
(
t
.
Process
.
Pid
,
t
.
Id
,
sys
.
SIGSTOP
)
err
:=
sys
.
Tgkill
(
t
.
Process
.
Pid
,
t
.
Id
,
sys
.
SIGSTOP
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Halt err %s %d"
,
err
,
pi
d
)
return
fmt
.
Errorf
(
"Halt err %s %d"
,
err
,
t
.
I
d
)
}
}
pid
,
_
,
err
:=
wait
(
th
.
Id
,
sys
.
WNOHANG
)
_
,
_
,
err
=
wait
(
t
.
Id
,
sys
.
WNOHANG
)
if
err
!=
nil
{
if
err
!=
nil
{
return
fmt
.
Errorf
(
"wait err %s %d"
,
err
,
pi
d
)
return
fmt
.
Errorf
(
"wait err %s %d"
,
err
,
t
.
I
d
)
}
}
return
nil
return
nil
}
}
func
(
t
*
ThreadContext
)
cont
()
error
{
func
(
t
*
ThreadContext
)
cont
()
error
{
return
PtraceCont
(
t
hread
.
Id
,
0
)
return
PtraceCont
(
t
.
Id
,
0
)
}
}
func
(
t
*
ThreadContext
)
singleStep
()
error
{
func
(
t
*
ThreadContext
)
singleStep
()
error
{
err
:=
sys
.
PtraceSingleStep
(
t
.
Id
)
err
:=
sys
.
PtraceSingleStep
(
t
.
Id
)
if
err
!=
nil
l
{
if
err
!=
nil
{
return
err
return
err
}
}
_
,
_
,
err
=
wait
(
t
hread
.
Id
,
0
)
_
,
_
,
err
=
wait
(
t
.
Id
,
0
)
return
err
return
err
}
}
func
writeMemory
(
tid
int
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
func
(
t
*
ThreadContext
)
blocked
()
bool
{
return
sys
.
PtracePokeData
(
tid
,
addr
,
data
)
// TODO(dp) cache the func pc to remove this lookup
// TODO(dp) check err
pc
,
_
:=
t
.
CurrentPC
()
fn
:=
t
.
Process
.
GoSymTable
.
PCToFunc
(
pc
)
if
fn
!=
nil
&&
((
fn
.
Name
==
"runtime.futex"
)
||
(
fn
.
Name
==
"runtime.usleep"
))
{
return
true
}
return
false
}
func
writeMemory
(
thread
*
ThreadContext
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
return
sys
.
PtracePokeData
(
thread
.
Id
,
addr
,
data
)
}
}
func
readMemory
(
t
id
in
t
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
func
readMemory
(
t
hread
*
ThreadContex
t
,
addr
uintptr
,
data
[]
byte
)
(
int
,
error
)
{
return
sys
.
PtracePeekData
(
t
i
d
,
addr
,
data
)
return
sys
.
PtracePeekData
(
t
hread
.
I
d
,
addr
,
data
)
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录