Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
HugeYuan
delve
提交
93db6249
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,发现更多精彩内容 >>
提交
93db6249
编写于
8月 23, 2014
作者:
D
Derek Parker
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Launch prog from cli, also exit cleanly
上级
44dba87c
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
183 addition
and
27 deletion
+183
-27
_fixtures/integrationprog
_fixtures/integrationprog
+0
-0
_fixtures/integrationprog.go
_fixtures/integrationprog.go
+18
-0
command/command.go
command/command.go
+0
-13
main.go
main.go
+76
-14
main_test.go
main_test.go
+89
-0
未找到文件。
_fixtures/integrationprog
0 → 100755
浏览文件 @
93db6249
文件已添加
_fixtures/integrationprog.go
0 → 100644
浏览文件 @
93db6249
package
main
import
(
"fmt"
"time"
)
func
sayhi
()
{
fmt
.
Println
(
"hi"
)
}
func
main
()
{
time
.
Sleep
(
1
*
time
.
Second
)
for
i
:=
0
;
i
<
3
;
i
++
{
sayhi
()
time
.
Sleep
(
1
*
time
.
Second
)
}
}
command/command.go
浏览文件 @
93db6249
...
...
@@ -5,11 +5,9 @@ package command
import
(
"debug/gosym"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"syscall"
"github.com/derekparker/dbg/proctl"
)
...
...
@@ -23,7 +21,6 @@ type Commands struct {
// Returns a Commands struct with default commands defined.
func
DebugCommands
()
*
Commands
{
cmds
:=
map
[
string
]
cmdfunc
{
"exit"
:
exitFunc
,
"continue"
:
cont
,
"next"
:
next
,
"break"
:
breakpoint
,
...
...
@@ -66,16 +63,6 @@ func noCmdAvailable(p *proctl.DebuggedProcess, ars ...string) error {
return
fmt
.
Errorf
(
"command not available"
)
}
func
exitFunc
(
p
*
proctl
.
DebuggedProcess
,
ars
...
string
)
error
{
err
:=
syscall
.
PtraceDetach
(
p
.
Pid
)
if
err
!=
nil
{
return
err
}
os
.
Exit
(
0
)
return
nil
}
func
nullCommand
(
p
*
proctl
.
DebuggedProcess
,
ars
...
string
)
error
{
return
nil
}
...
...
main.go
浏览文件 @
93db6249
...
...
@@ -2,11 +2,13 @@ package main
import
(
"bufio"
"flag"
"fmt"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
"syscall"
"github.com/derekparker/dbg/command"
"github.com/derekparker/dbg/proctl"
...
...
@@ -23,32 +25,35 @@ func main() {
runtime
.
LockOSThread
()
var
(
pid
int
proc
string
t
=
newTerm
()
cmds
=
command
.
DebugCommands
()
)
if
len
(
os
.
Args
)
==
1
{
die
(
"You must provide a pid
\n
"
)
}
flag
.
IntVar
(
&
pid
,
"pid"
,
0
,
"Pid of running process to attach to."
)
flag
.
StringVar
(
&
proc
,
"proc"
,
""
,
"Path to process to run and debug.
"
)
flag
.
Parse
()
pid
,
err
:=
strconv
.
Atoi
(
os
.
Args
[
1
])
if
err
!=
nil
{
die
(
err
)
if
flag
.
NFlag
()
==
0
{
flag
.
Usage
()
os
.
Exit
(
0
)
}
dbgproc
,
err
:=
proctl
.
NewDebugProcess
(
pid
)
if
err
!=
nil
{
die
(
"Could not start debugging process:"
,
err
)
}
dbgproc
:=
beginTrace
(
pid
,
proc
)
for
{
cmdstr
,
err
:=
t
.
promptForInput
()
if
err
!=
nil
{
die
(
"Prompt for input failed.
\n
"
)
die
(
1
,
"Prompt for input failed.
\n
"
)
}
cmdstr
,
args
:=
parseCommand
(
cmdstr
)
if
cmdstr
==
"exit"
{
handleExit
(
t
,
dbgproc
,
0
)
}
cmd
:=
cmds
.
Find
(
cmdstr
)
err
=
cmd
(
dbgproc
,
args
...
)
if
err
!=
nil
{
...
...
@@ -57,9 +62,66 @@ func main() {
}
}
func
die
(
args
...
interface
{})
{
func
beginTrace
(
pid
int
,
proc
string
)
*
proctl
.
DebuggedProcess
{
var
(
err
error
dbgproc
*
proctl
.
DebuggedProcess
)
if
pid
!=
0
{
dbgproc
,
err
=
proctl
.
NewDebugProcess
(
pid
)
if
err
!=
nil
{
die
(
1
,
"Could not start debugging process:"
,
err
)
}
}
if
proc
!=
""
{
proc
:=
exec
.
Command
(
proc
)
proc
.
Stdout
=
os
.
Stdout
err
=
proc
.
Start
()
if
err
!=
nil
{
die
(
1
,
"Could not start process:"
,
err
)
}
dbgproc
,
err
=
proctl
.
NewDebugProcess
(
proc
.
Process
.
Pid
)
if
err
!=
nil
{
die
(
1
,
"Could not start debugging process:"
,
err
)
}
}
return
dbgproc
}
func
handleExit
(
t
*
term
,
dbp
*
proctl
.
DebuggedProcess
,
status
int
)
{
fmt
.
Println
(
"Would you like to kill the process? [y/n]"
)
answer
,
err
:=
t
.
stdin
.
ReadString
(
'\n'
)
if
err
!=
nil
{
die
(
2
,
err
.
Error
())
}
fmt
.
Println
(
"Detaching from process..."
)
err
=
syscall
.
PtraceDetach
(
dbp
.
Process
.
Pid
)
if
err
!=
nil
{
die
(
2
,
"Could not detach"
,
err
)
}
if
answer
==
"y
\n
"
{
fmt
.
Println
(
"Killing process"
,
dbp
.
Process
.
Pid
)
err
:=
dbp
.
Process
.
Kill
()
if
err
!=
nil
{
fmt
.
Println
(
"Could not kill process"
,
err
)
}
}
die
(
status
,
"Hope I was of service hunting your bug!"
)
}
func
die
(
status
int
,
args
...
interface
{})
{
fmt
.
Fprint
(
os
.
Stderr
,
args
)
os
.
Exit
(
1
)
fmt
.
Fprint
(
os
.
Stderr
,
"
\n
"
)
os
.
Exit
(
status
)
}
func
newTerm
()
*
term
{
...
...
main_test.go
0 → 100644
浏览文件 @
93db6249
package
main
import
(
"bytes"
"os"
"os/exec"
"strconv"
"strings"
"testing"
"time"
)
func
buildBinary
(
t
*
testing
.
T
)
{
cmd
:=
exec
.
Command
(
"go"
,
"build"
,
"-o"
,
"dbg-test"
)
err
:=
cmd
.
Run
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}
func
startDebugger
(
t
*
testing
.
T
,
pid
int
)
*
os
.
Process
{
cmd
:=
exec
.
Command
(
"sudo"
,
"./dbg-test"
,
"-pid"
,
strconv
.
Itoa
(
pid
))
cmd
.
Stdin
=
bytes
.
NewBufferString
(
"exit
\n
y
\n
"
)
err
:=
cmd
.
Start
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
return
cmd
.
Process
}
func
startTestProg
(
t
*
testing
.
T
,
proc
string
)
*
os
.
Process
{
cmd
:=
exec
.
Command
(
proc
)
err
:=
cmd
.
Start
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
return
cmd
.
Process
}
func
TestCleanExit
(
t
*
testing
.
T
)
{
buildBinary
(
t
)
var
(
waitchan
=
make
(
chan
*
os
.
ProcessState
)
testprog
=
startTestProg
(
t
,
"_fixtures/livetestprog"
)
)
go
func
()
{
ps
,
err
:=
testprog
.
Wait
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
waitchan
<-
ps
}()
proc
:=
startDebugger
(
t
,
testprog
.
Pid
)
defer
func
()
{
testprog
.
Kill
()
proc
.
Kill
()
err
:=
os
.
Remove
(
"dbg-test"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
}()
timer
:=
time
.
NewTimer
(
5
*
time
.
Second
)
select
{
case
ps
:=
<-
waitchan
:
// Admittedly, this is weird.
// There is/was a bug in Go that marked
// a process as done whenever `Wait()` was
// called on it, I fixed that, but it seems
// there may be another connected bug somewhere
// where the process is not marked as exited.
if
strings
.
Contains
(
ps
.
String
(),
"exited"
)
{
t
.
Fatal
(
"Process has not exited"
)
}
case
<-
timer
.
C
:
t
.
Fatal
(
"timeout"
)
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录