Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
HugeYuan
delve
提交
6b80a726
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,发现更多精彩内容 >>
提交
6b80a726
编写于
10月 15, 2014
作者:
D
Derek Parker
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove DWARF .debug_line parser / util funcs
上级
414db82e
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
1 addition
and
550 deletion
+1
-550
dwarf/line/line_parser.go
dwarf/line/line_parser.go
+0
-95
dwarf/line/line_parser_test.go
dwarf/line/line_parser_test.go
+0
-103
dwarf/line/state_machine.go
dwarf/line/state_machine.go
+0
-249
dwarf/line/state_machine_test.go
dwarf/line/state_machine_test.go
+0
-87
proctl/proctl_linux_amd64.go
proctl/proctl_linux_amd64.go
+1
-16
未找到文件。
dwarf/line/line_parser.go
已删除
100644 → 0
浏览文件 @
414db82e
package
line
import
(
"bytes"
"encoding/binary"
"github.com/derekparker/dbg/dwarf/util"
)
type
DebugLinePrologue
struct
{
Length
uint32
Version
uint16
PrologueLength
uint32
MinInstrLength
uint8
InitialIsStmt
uint8
LineBase
int8
LineRange
uint8
OpcodeBase
uint8
StdOpLengths
[]
uint8
}
type
DebugLineInfo
struct
{
Prologue
*
DebugLinePrologue
IncludeDirs
[]
string
FileNames
[]
*
FileEntry
Instructions
[]
byte
}
type
FileEntry
struct
{
Name
string
DirIdx
uint64
LastModTime
uint64
Length
uint64
}
func
Parse
(
data
[]
byte
)
*
DebugLineInfo
{
var
(
dbl
=
new
(
DebugLineInfo
)
buf
=
bytes
.
NewBuffer
(
data
)
)
parseDebugLinePrologue
(
dbl
,
buf
)
parseIncludeDirs
(
dbl
,
buf
)
parseFileEntries
(
dbl
,
buf
)
dbl
.
Instructions
=
buf
.
Bytes
()
return
dbl
}
func
parseDebugLinePrologue
(
dbl
*
DebugLineInfo
,
buf
*
bytes
.
Buffer
)
{
p
:=
new
(
DebugLinePrologue
)
p
.
Length
=
binary
.
LittleEndian
.
Uint32
(
buf
.
Next
(
4
))
p
.
Version
=
binary
.
LittleEndian
.
Uint16
(
buf
.
Next
(
2
))
p
.
PrologueLength
=
binary
.
LittleEndian
.
Uint32
(
buf
.
Next
(
4
))
p
.
MinInstrLength
=
uint8
(
buf
.
Next
(
1
)[
0
])
p
.
InitialIsStmt
=
uint8
(
buf
.
Next
(
1
)[
0
])
p
.
LineBase
=
int8
(
buf
.
Next
(
1
)[
0
])
p
.
LineRange
=
uint8
(
buf
.
Next
(
1
)[
0
])
p
.
OpcodeBase
=
uint8
(
buf
.
Next
(
1
)[
0
])
p
.
StdOpLengths
=
make
([]
uint8
,
p
.
OpcodeBase
-
1
)
binary
.
Read
(
buf
,
binary
.
LittleEndian
,
&
p
.
StdOpLengths
)
dbl
.
Prologue
=
p
}
func
parseIncludeDirs
(
info
*
DebugLineInfo
,
buf
*
bytes
.
Buffer
)
{
for
{
str
,
_
:=
util
.
ParseString
(
buf
)
if
str
==
""
{
break
}
info
.
IncludeDirs
=
append
(
info
.
IncludeDirs
,
str
)
}
}
func
parseFileEntries
(
info
*
DebugLineInfo
,
buf
*
bytes
.
Buffer
)
{
for
{
entry
:=
new
(
FileEntry
)
name
,
_
:=
util
.
ParseString
(
buf
)
if
name
==
""
{
break
}
entry
.
Name
=
name
entry
.
DirIdx
,
_
=
util
.
DecodeULEB128
(
buf
)
entry
.
LastModTime
,
_
=
util
.
DecodeULEB128
(
buf
)
entry
.
Length
,
_
=
util
.
DecodeULEB128
(
buf
)
info
.
FileNames
=
append
(
info
.
FileNames
,
entry
)
}
}
dwarf/line/line_parser_test.go
已删除
100644 → 0
浏览文件 @
414db82e
package
line
import
(
"debug/elf"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/davecheney/profile"
)
func
grabDebugLineSection
(
p
string
,
t
*
testing
.
T
)
[]
byte
{
f
,
err
:=
os
.
Open
(
p
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
defer
f
.
Close
()
ef
,
err
:=
elf
.
NewFile
(
f
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
data
,
err
:=
ef
.
Section
(
".debug_line"
)
.
Data
()
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
return
data
}
func
TestDebugLinePrologueParser
(
t
*
testing
.
T
)
{
// Test against known good values, from readelf --debug-dump=rawline _fixtures/testnextprog
p
,
err
:=
filepath
.
Abs
(
"../../_fixtures/testnextprog"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
exec
.
Command
(
"go"
,
"build"
,
"-gcflags=-N -l"
,
"-o"
,
p
,
p
+
".go"
)
.
Run
()
if
err
!=
nil
{
t
.
Fatal
(
"Could not compile test file"
,
p
,
err
)
}
defer
os
.
Remove
(
p
)
data
:=
grabDebugLineSection
(
p
,
t
)
dbl
:=
Parse
(
data
)
prologue
:=
dbl
.
Prologue
if
prologue
.
Version
!=
uint16
(
2
)
{
t
.
Fatal
(
"Version not parsed correctly"
,
prologue
.
Version
)
}
if
prologue
.
MinInstrLength
!=
uint8
(
1
)
{
t
.
Fatal
(
"Minimun Instruction Length not parsed correctly"
,
prologue
.
MinInstrLength
)
}
if
prologue
.
InitialIsStmt
!=
uint8
(
1
)
{
t
.
Fatal
(
"Initial value of 'is_stmt' not parsed correctly"
,
prologue
.
InitialIsStmt
)
}
if
prologue
.
LineBase
!=
int8
(
-
1
)
{
t
.
Fatal
(
"Line base not parsed correctly"
,
prologue
.
LineBase
)
}
if
prologue
.
LineRange
!=
uint8
(
4
)
{
t
.
Fatal
(
"Line Range not parsed correctly"
,
prologue
.
LineRange
)
}
if
prologue
.
OpcodeBase
!=
uint8
(
10
)
{
t
.
Fatal
(
"Opcode Base not parsed correctly"
,
prologue
.
OpcodeBase
)
}
lengths
:=
[]
uint8
{
0
,
1
,
1
,
1
,
1
,
0
,
0
,
0
,
1
}
for
i
,
l
:=
range
prologue
.
StdOpLengths
{
if
l
!=
lengths
[
i
]
{
t
.
Fatal
(
"Length not parsed correctly"
,
l
)
}
}
if
len
(
dbl
.
IncludeDirs
)
!=
0
{
t
.
Fatal
(
"Include dirs not parsed correctly"
)
}
if
!
strings
.
Contains
(
dbl
.
FileNames
[
0
]
.
Name
,
"/dbg/_fixtures/testnextprog.go"
)
{
t
.
Fatal
(
"First entry not parsed correctly"
)
}
}
func
BenchmarkLineParser
(
b
*
testing
.
B
)
{
defer
profile
.
Start
(
profile
.
MemProfile
)
.
Stop
()
p
,
err
:=
filepath
.
Abs
(
"../../_fixtures/testnextprog"
)
if
err
!=
nil
{
b
.
Fatal
(
err
)
}
data
:=
grabDebugLineSection
(
p
,
nil
)
b
.
ResetTimer
()
for
i
:=
0
;
i
<
b
.
N
;
i
++
{
_
=
Parse
(
data
)
}
}
dwarf/line/state_machine.go
已删除
100644 → 0
浏览文件 @
414db82e
package
line
import
(
"bytes"
"encoding/binary"
"fmt"
"github.com/derekparker/dbg/dwarf/util"
)
type
Location
struct
{
File
string
Line
int
Address
uint64
Delta
int
}
type
StateMachine
struct
{
Dbl
*
DebugLineInfo
File
string
Line
int
Address
uint64
Column
uint
IsStmt
bool
BasicBlock
bool
EndSeq
bool
LastWasStandard
bool
LastDelta
int
}
type
opcodefn
func
(
*
StateMachine
,
*
bytes
.
Buffer
)
// Special opcodes
const
(
DW_LNS_copy
=
1
DW_LNS_advance_pc
=
2
DW_LNS_advance_line
=
3
DW_LNS_set_file
=
4
DW_LNS_set_column
=
5
DW_LNS_negate_stmt
=
6
DW_LNS_set_basic_block
=
7
DW_LNS_const_add_pc
=
8
DW_LNS_fixed_advance_pc
=
9
)
// Extended opcodes
const
(
DW_LINE_end_sequence
=
1
DW_LINE_set_address
=
2
DW_LINE_define_file
=
3
)
var
standardopcodes
=
map
[
byte
]
opcodefn
{
DW_LNS_copy
:
copyfn
,
DW_LNS_advance_pc
:
advancepc
,
DW_LNS_advance_line
:
advanceline
,
DW_LNS_set_file
:
setfile
,
DW_LNS_set_column
:
setcolumn
,
DW_LNS_negate_stmt
:
negatestmt
,
DW_LNS_set_basic_block
:
setbasicblock
,
DW_LNS_const_add_pc
:
constaddpc
,
DW_LNS_fixed_advance_pc
:
fixedadvancepc
,
}
var
extendedopcodes
=
map
[
byte
]
opcodefn
{
DW_LINE_end_sequence
:
endsequence
,
DW_LINE_set_address
:
setaddress
,
DW_LINE_define_file
:
definefile
,
}
func
newStateMachine
(
dbl
*
DebugLineInfo
)
*
StateMachine
{
return
&
StateMachine
{
Dbl
:
dbl
,
File
:
dbl
.
FileNames
[
0
]
.
Name
,
Line
:
1
}
}
// Returns the filename, line number and PC for the next executable line in
// the traced program.
func
(
dbl
*
DebugLineInfo
)
NextLocation
(
pc
uint64
,
file
string
,
line
int
)
*
Location
{
var
(
sm
=
newStateMachine
(
dbl
)
buf
=
bytes
.
NewBuffer
(
dbl
.
Instructions
)
)
for
b
,
err
:=
buf
.
ReadByte
();
err
==
nil
;
b
,
err
=
buf
.
ReadByte
()
{
findAndExecOpcode
(
sm
,
buf
,
b
)
if
sm
.
File
==
file
&&
sm
.
Line
>
line
{
break
}
}
return
&
Location
{
sm
.
File
,
sm
.
Line
,
sm
.
Address
,
sm
.
LastDelta
}
}
func
(
dbl
*
DebugLineInfo
)
LocationInfoForPC
(
pc
uint64
)
*
Location
{
var
(
sm
=
newStateMachine
(
dbl
)
buf
=
bytes
.
NewBuffer
(
dbl
.
Instructions
)
)
executeUntilPC
(
sm
,
buf
,
pc
)
return
&
Location
{
sm
.
File
,
sm
.
Line
,
sm
.
Address
,
sm
.
LastDelta
}
}
func
executeUntilFileAndLine
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
,
file
string
,
line
int
)
{
for
b
,
err
:=
buf
.
ReadByte
();
err
==
nil
;
b
,
err
=
buf
.
ReadByte
()
{
findAndExecOpcode
(
sm
,
buf
,
b
)
if
sm
.
Line
==
line
&&
sm
.
File
==
file
{
break
}
}
}
func
executeUntilPC
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
,
pc
uint64
)
{
var
line
int
for
b
,
err
:=
buf
.
ReadByte
();
err
==
nil
;
b
,
err
=
buf
.
ReadByte
()
{
findAndExecOpcode
(
sm
,
buf
,
b
)
if
line
!=
0
&&
sm
.
Line
!=
line
{
break
}
if
sm
.
Address
==
pc
{
if
!
sm
.
LastWasStandard
{
break
}
line
=
sm
.
Line
}
}
}
func
findAndExecOpcode
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
,
b
byte
)
{
switch
{
case
b
==
0
:
execExtendedOpcode
(
sm
,
b
,
buf
)
case
b
<
sm
.
Dbl
.
Prologue
.
OpcodeBase
:
execStandardOpcode
(
sm
,
b
,
buf
)
default
:
execSpecialOpcode
(
sm
,
b
)
}
}
func
execSpecialOpcode
(
sm
*
StateMachine
,
instr
byte
)
{
var
(
opcode
=
uint8
(
instr
)
decoded
=
opcode
-
sm
.
Dbl
.
Prologue
.
OpcodeBase
)
if
sm
.
Dbl
.
Prologue
.
InitialIsStmt
==
uint8
(
1
)
{
sm
.
IsStmt
=
true
}
sm
.
LastDelta
=
int
(
sm
.
Dbl
.
Prologue
.
LineBase
+
int8
(
decoded
%
sm
.
Dbl
.
Prologue
.
LineRange
))
sm
.
Line
+=
sm
.
LastDelta
sm
.
Address
+=
uint64
(
decoded
/
sm
.
Dbl
.
Prologue
.
LineRange
)
sm
.
BasicBlock
=
false
sm
.
LastWasStandard
=
false
}
func
execExtendedOpcode
(
sm
*
StateMachine
,
instr
byte
,
buf
*
bytes
.
Buffer
)
{
_
,
_
=
util
.
DecodeULEB128
(
buf
)
b
,
_
:=
buf
.
ReadByte
()
fn
,
ok
:=
extendedopcodes
[
b
]
if
!
ok
{
panic
(
fmt
.
Sprintf
(
"Encountered unknown extended opcode %#v
\n
"
,
b
))
}
sm
.
LastWasStandard
=
false
fn
(
sm
,
buf
)
}
func
execStandardOpcode
(
sm
*
StateMachine
,
instr
byte
,
buf
*
bytes
.
Buffer
)
{
fn
,
ok
:=
standardopcodes
[
instr
]
if
!
ok
{
panic
(
fmt
.
Sprintf
(
"Encountered unknown standard opcode %#v
\n
"
,
instr
))
}
sm
.
LastWasStandard
=
true
fn
(
sm
,
buf
)
}
func
copyfn
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
sm
.
BasicBlock
=
false
}
func
advancepc
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
addr
,
_
:=
util
.
DecodeULEB128
(
buf
)
sm
.
Address
+=
addr
*
uint64
(
sm
.
Dbl
.
Prologue
.
MinInstrLength
)
}
func
advanceline
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
line
,
_
:=
util
.
DecodeSLEB128
(
buf
)
sm
.
Line
+=
int
(
line
)
sm
.
LastDelta
=
int
(
line
)
}
func
setfile
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
i
,
_
:=
util
.
DecodeULEB128
(
buf
)
sm
.
File
=
sm
.
Dbl
.
FileNames
[
i
-
1
]
.
Name
}
func
setcolumn
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
c
,
_
:=
util
.
DecodeULEB128
(
buf
)
sm
.
Column
=
uint
(
c
)
}
func
negatestmt
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
sm
.
IsStmt
=
!
sm
.
IsStmt
}
func
setbasicblock
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
sm
.
BasicBlock
=
true
}
func
constaddpc
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
sm
.
Address
+=
(
255
/
uint64
(
sm
.
Dbl
.
Prologue
.
LineRange
))
}
func
fixedadvancepc
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
var
operand
uint16
binary
.
Read
(
buf
,
binary
.
LittleEndian
,
&
operand
)
sm
.
Address
+=
uint64
(
operand
)
}
func
endsequence
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
sm
.
EndSeq
=
true
}
func
setaddress
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
var
addr
uint64
binary
.
Read
(
buf
,
binary
.
LittleEndian
,
&
addr
)
sm
.
Address
=
addr
}
func
definefile
(
sm
*
StateMachine
,
buf
*
bytes
.
Buffer
)
{
var
(
_
,
_
=
util
.
ParseString
(
buf
)
_
,
_
=
util
.
DecodeULEB128
(
buf
)
_
,
_
=
util
.
DecodeULEB128
(
buf
)
_
,
_
=
util
.
DecodeULEB128
(
buf
)
)
// Don't do anything here yet.
}
dwarf/line/state_machine_test.go
已删除
100644 → 0
浏览文件 @
414db82e
package
line
import
(
"debug/elf"
"debug/gosym"
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"
)
func
parseGoSymTab
(
exe
*
elf
.
File
,
t
*
testing
.
T
)
*
gosym
.
Table
{
var
(
symdat
[]
byte
pclndat
[]
byte
err
error
)
if
sec
:=
exe
.
Section
(
".gosymtab"
);
sec
!=
nil
{
symdat
,
err
=
sec
.
Data
()
if
err
!=
nil
{
fmt
.
Println
(
"could not get .gosymtab section"
,
err
)
os
.
Exit
(
1
)
}
}
if
sec
:=
exe
.
Section
(
".gopclntab"
);
sec
!=
nil
{
pclndat
,
err
=
sec
.
Data
()
if
err
!=
nil
{
fmt
.
Println
(
"could not get .gopclntab section"
,
err
)
os
.
Exit
(
1
)
}
}
pcln
:=
gosym
.
NewLineTable
(
pclndat
,
exe
.
Section
(
".text"
)
.
Addr
)
tab
,
err
:=
gosym
.
NewTable
(
symdat
,
pcln
)
if
err
!=
nil
{
fmt
.
Println
(
"could not get initialize line table"
,
err
)
os
.
Exit
(
1
)
}
return
tab
}
func
TestNextLocAfterPC
(
t
*
testing
.
T
)
{
testfile
,
_
:=
filepath
.
Abs
(
"../../_fixtures/testnextprog"
)
p
,
err
:=
filepath
.
Abs
(
"../../_fixtures/testnextprog"
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
exec
.
Command
(
"go"
,
"build"
,
"-gcflags=-N -l"
,
"-o"
,
p
,
p
+
".go"
)
.
Run
()
if
err
!=
nil
{
t
.
Fatal
(
"Could not compile test file"
,
p
,
err
)
}
defer
os
.
Remove
(
p
)
var
(
data
=
grabDebugLineSection
(
p
,
t
)
dbl
=
Parse
(
data
)
)
f
,
err
:=
os
.
Open
(
p
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
e
,
err
:=
elf
.
NewFile
(
f
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
symtab
:=
parseGoSymTab
(
e
,
t
)
pc
,
_
,
err
:=
symtab
.
LineToPC
(
testfile
+
".go"
,
23
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
loc
:=
dbl
.
NextLocation
(
pc
,
testfile
+
".go"
,
23
)
if
loc
.
File
!=
testfile
+
".go"
{
t
.
Fatal
(
"File not returned correctly"
,
loc
.
File
)
}
if
loc
.
Line
!=
24
{
t
.
Fatal
(
"Line not returned correctly"
,
loc
.
Line
)
}
}
proctl/proctl_linux_amd64.go
浏览文件 @
6b80a726
...
...
@@ -15,7 +15,6 @@ import (
"unsafe"
"github.com/derekparker/dbg/dwarf/frame"
"github.com/derekparker/dbg/dwarf/line"
"github.com/derekparker/dbg/dwarf/op"
"github.com/derekparker/dbg/vendor/dwarf"
"github.com/derekparker/dbg/vendor/elf"
...
...
@@ -32,7 +31,6 @@ type DebuggedProcess struct {
Symbols
[]
elf
.
Symbol
GoSymTable
*
gosym
.
Table
FrameEntries
*
frame
.
FrameDescriptionEntries
DebugLine
*
line
.
DebugLineInfo
BreakPoints
map
[
uint64
]
*
BreakPoint
}
...
...
@@ -112,9 +110,8 @@ func (dbp *DebuggedProcess) LoadInformation() error {
return
err
}
wg
.
Add
(
3
)
wg
.
Add
(
2
)
go
dbp
.
parseDebugFrame
(
&
wg
)
go
dbp
.
parseDebugLine
(
&
wg
)
go
dbp
.
obtainGoSymbols
(
&
wg
)
wg
.
Wait
()
...
...
@@ -641,18 +638,6 @@ func (dbp *DebuggedProcess) findExecutable() error {
return
nil
}
func
(
dbp
*
DebuggedProcess
)
parseDebugLine
(
wg
*
sync
.
WaitGroup
)
{
defer
wg
.
Done
()
debugLine
,
err
:=
dbp
.
Executable
.
Section
(
".debug_line"
)
.
Data
()
if
err
!=
nil
{
fmt
.
Println
(
"could not get .debug_line section"
,
err
)
os
.
Exit
(
1
)
}
dbp
.
DebugLine
=
line
.
Parse
(
debugLine
)
}
func
(
dbp
*
DebuggedProcess
)
parseDebugFrame
(
wg
*
sync
.
WaitGroup
)
{
defer
wg
.
Done
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录