Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MegEngine 天元
MegEngine
提交
c3d63f14
MegEngine
项目概览
MegEngine 天元
/
MegEngine
1 年多 前同步成功
通知
403
Star
4705
Fork
582
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
MegEngine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
c3d63f14
编写于
1月 14, 2022
作者:
M
Megvii Engine Team
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat(dispatch): add gdb debug utils
GitOrigin-RevId: 393b0c9c76c29aacfcf917fd6e5479f5a9917a6b
上级
2e42bc08
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
246 addition
and
3 deletion
+246
-3
.gdbinit
.gdbinit
+1
-0
scripts/gdb/commands.py
scripts/gdb/commands.py
+210
-0
scripts/gdb/pretty_printers.py
scripts/gdb/pretty_printers.py
+35
-3
未找到文件。
.gdbinit
浏览文件 @
c3d63f14
source ./scripts/gdb/commands.py
source ./scripts/gdb/pretty_printers.py
source ./scripts/gdb/pretty_printers.py
source ./scripts/gdb/xmethods.py
source ./scripts/gdb/xmethods.py
catch throw
catch throw
scripts/gdb/commands.py
0 → 100644
浏览文件 @
c3d63f14
import
gdb
import
re
import
subprocess
_demangle_cache
=
{}
def
demangle
(
name
):
if
name
not
in
_demangle_cache
:
_demangle_cache
[
name
]
=
subprocess
.
run
([
'c++filt'
,
"-t"
,
name
],
stdout
=
subprocess
.
PIPE
).
stdout
return
_demangle_cache
[
name
].
decode
(
'utf-8'
).
strip
()
def
dynamic_cast
(
val
):
assert
val
.
type
.
code
==
gdb
.
TYPE_CODE_REF
val
=
val
.
cast
(
val
.
dynamic_type
)
return
val
def
eval_on_val
(
val
,
eval_str
):
if
val
.
type
.
code
==
gdb
.
TYPE_CODE_REF
:
val
=
val
.
referenced_value
()
address
=
val
.
address
eval_str
=
"(*({}){}){}"
.
format
(
address
.
type
,
address
,
eval_str
)
return
gdb
.
parse_and_eval
(
eval_str
)
def
is_subclass_of
(
subclass
,
baseclass
):
for
field
in
subclass
.
fields
():
if
field
.
is_base_class
:
if
field
.
type
==
baseclass
:
return
True
elif
is_subclass_of
(
field
.
type
,
baseclass
):
return
True
def
vector_size
(
vector
):
impl
=
vector
[
"_M_impl"
]
return
int
(
impl
[
"_M_finish"
]
-
impl
[
"_M_start"
])
def
vector_item
(
vector
,
i
):
impl
=
vector
[
"_M_impl"
]
return
(
impl
[
"_M_start"
]
+
i
).
dereference
()
def
shared_ptr_deref
(
ptr
):
return
ptr
[
"_M_ptr"
].
dereference
()
def
get_type_name
(
type_index
):
return
gdb
.
lookup_global_symbol
(
"mgb::imperative::debug::get_type_name(std::type_index const&)"
).
value
()(
type_index
).
string
()
mge_apply_transform_pattern
=
re
.
compile
(
r
"^(.*)::apply_transform\(mgb::imperative::Operator const&, mgb::imperative::Span<mgb::imperative::ValueRef>\)$"
)
mge_op_fallback_pattern
=
re
.
compile
(
r
"^(.*)::fallback\(mgb::imperative::Span<mgb::imperative::ValueRef>\) const$"
)
def
is_mge_frame
(
frame
):
function
=
frame
.
function
()
if
not
(
function
and
function
.
name
):
return
False
matcher
=
mge_apply_transform_pattern
.
match
(
function
.
name
)
if
matcher
:
typename
=
matcher
.
group
(
1
)
return
is_subclass_of
(
gdb
.
lookup_type
(
typename
),
gdb
.
lookup_type
(
"mgb::imperative::Transform"
))
matcher
=
mge_op_fallback_pattern
.
match
(
function
.
name
)
if
matcher
:
typename
=
matcher
.
group
(
1
)
return
is_subclass_of
(
gdb
.
lookup_type
(
typename
),
gdb
.
lookup_type
(
"mgb::imperative::Operator"
))
return
False
def
count_frame_level
(
frame
):
level
=
-
1
while
frame
:
frame
=
frame
.
newer
()
level
+=
1
return
level
def
print_mge_frame
(
frame
):
function
=
frame
.
function
()
op
=
eval_on_val
(
dynamic_cast
(
frame
.
read_var
(
"op"
)),
".to_string().c_str()"
).
string
()
inputs
=
str
(
frame
.
read_var
(
"inputs"
))
matcher
=
mge_apply_transform_pattern
.
match
(
function
.
name
)
if
matcher
:
name
=
matcher
.
group
(
1
)
else
:
name
=
mge_op_fallback_pattern
.
match
(
function
.
name
).
group
(
1
)
#TODO: span
sal
=
frame
.
find_sal
()
filename
=
sal
.
symtab
.
filename
line
=
sal
.
line
print
(
"#{} {} apply {} on {}, file: {}:{}"
.
format
(
count_frame_level
(
frame
),
name
,
op
,
inputs
,
filename
,
line
))
class
MegengineBacktrace
(
gdb
.
Command
):
def
__init__
(
self
):
super
().
__init__
(
"mge-bt"
,
gdb
.
COMMAND_USER
)
def
invoke
(
self
,
arg
,
from_tty
):
frame
=
gdb
.
newest_frame
()
mge_stack
=
[]
while
frame
is
not
None
:
if
is_mge_frame
(
frame
):
mge_stack
.
append
(
frame
)
frame
=
frame
.
older
()
for
frame
in
reversed
(
mge_stack
):
print_mge_frame
(
frame
)
class
MegengineBreakApply
(
gdb
.
Command
):
def
__init__
(
self
):
super
().
__init__
(
"mge-brk-apply"
,
gdb
.
COMMAND_USER
)
def
invoke
(
self
,
arg
,
from_tty
):
gdb
.
Breakpoint
(
"mgb::imperative::apply(mgb::imperative::Operator const&, mgb::imperative::Span<mgb::imperative::ValueRef>)"
)
class
MegengineWatch
(
gdb
.
Command
):
def
__init__
(
self
):
super
().
__init__
(
"mge-watch"
,
gdb
.
COMMAND_USER
)
def
invoke
(
self
,
arg
,
from_tty
):
watch
=
gdb
.
lookup_global_symbol
(
"mgb::imperative::debug::watch_value(mgb::imperative::ValueRef)"
).
value
()
value
=
gdb
.
parse_and_eval
(
arg
)
watch
(
value
)
print
(
"watching {}"
.
format
(
str
(
value
)))
class
MegengineUp
(
gdb
.
Command
):
def
__init__
(
self
):
super
().
__init__
(
"mge-up"
,
gdb
.
COMMAND_USER
)
def
invoke
(
self
,
arg
,
from_tty
):
frame
=
gdb
.
selected_frame
()
if
frame
is
None
:
print
(
"Unable to find older dispatch frame"
)
return
frame
=
frame
.
older
()
while
frame
is
not
None
and
not
is_mge_frame
(
frame
):
frame
=
frame
.
older
()
if
frame
is
None
:
print
(
"Unable to find older dispatch frame"
)
return
frame
.
select
()
print_mge_frame
(
frame
)
class
MegengineDown
(
gdb
.
Command
):
def
__init__
(
self
):
super
().
__init__
(
"mge-down"
,
gdb
.
COMMAND_USER
)
def
invoke
(
self
,
arg
,
from_tty
):
frame
=
gdb
.
selected_frame
()
if
frame
is
None
:
print
(
"Unable to find newer dispatch frame"
)
return
frame
=
frame
.
newer
()
while
frame
is
not
None
and
not
is_mge_frame
(
frame
):
frame
=
frame
.
newer
()
if
frame
is
None
:
print
(
"Unable to find newer dispatch frame"
)
return
frame
.
select
()
print_mge_frame
(
frame
)
class
MegengineInfo
(
gdb
.
Command
):
def
__init__
(
self
):
super
().
__init__
(
"mge-info"
,
gdb
.
COMMAND_USER
)
def
invoke
(
self
,
arg
,
from_tty
):
if
arg
==
"opr"
:
registered_oprs
=
gdb
.
lookup_global_symbol
(
"mgb::imperative::Operator::registered_types()"
).
value
()()
size
=
vector_size
(
registered_oprs
)
for
i
in
range
(
size
):
registered_opr
=
vector_item
(
registered_oprs
,
i
)
# name = eval_on_val(registered_opr, ".name()").string()
name
=
get_type_name
(
registered_opr
)
print
(
"{}: {}"
.
format
(
i
,
demangle
(
name
)))
elif
arg
==
"trf"
:
dispatch_context
=
gdb
.
lookup_global_symbol
(
"mgb::imperative::Transform::get_context()"
).
value
()()
transformations
=
dispatch_context
[
"transformations"
]
size
=
vector_size
(
transformations
)
for
i
in
range
(
size
):
transformation
=
vector_item
(
transformations
,
i
)
# name = eval_on_val(transformation, ".get()->name().c_str()").string()
name
=
shared_ptr_deref
(
transformation
).
dynamic_type
.
name
# name = get_type_name(transformation)
print
(
"{}: {}"
.
format
(
i
,
demangle
(
name
)))
else
:
print
(
"Unsupported argument {}"
.
format
(
arg
))
def
complete
(
self
,
text
,
word
):
return
[
"opr"
,
"trf"
]
MegengineBacktrace
()
MegengineBreakApply
()
MegengineUp
()
MegengineDown
()
MegengineInfo
()
MegengineWatch
()
gdb
.
Breakpoint
(
"mgb::imperative::debug::notify_event(char const*)"
)
\ No newline at end of file
scripts/gdb/pretty_printers.py
浏览文件 @
c3d63f14
...
@@ -3,8 +3,17 @@ import gdb.printing
...
@@ -3,8 +3,17 @@ import gdb.printing
import
gdb.types
import
gdb.types
def
dynamic_cast
(
val
):
assert
val
.
type
.
code
==
gdb
.
TYPE_CODE_REF
val
=
val
.
cast
(
val
.
dynamic_type
)
return
val
def
eval_on_val
(
val
,
eval_str
):
def
eval_on_val
(
val
,
eval_str
):
eval_str
=
"(*({}*)({})).{}"
.
format
(
val
.
type
,
val
.
address
,
eval_str
)
if
val
.
type
.
code
==
gdb
.
TYPE_CODE_REF
:
val
=
val
.
referenced_value
()
address
=
val
.
address
eval_str
=
"(*({}){}){}"
.
format
(
address
.
type
,
int
(
address
),
eval_str
)
return
gdb
.
parse_and_eval
(
eval_str
)
return
gdb
.
parse_and_eval
(
eval_str
)
...
@@ -50,7 +59,7 @@ class ToStringPrinter:
...
@@ -50,7 +59,7 @@ class ToStringPrinter:
self
.
val
=
val
self
.
val
=
val
def
to_string
(
self
):
def
to_string
(
self
):
return
eval_on_val
(
self
.
val
,
"to_string().c_str()"
).
string
()
return
eval_on_val
(
self
.
val
,
"
.
to_string().c_str()"
).
string
()
class
ReprPrinter
:
class
ReprPrinter
:
...
@@ -58,7 +67,10 @@ class ReprPrinter:
...
@@ -58,7 +67,10 @@ class ReprPrinter:
self
.
val
=
val
self
.
val
=
val
def
to_string
(
self
):
def
to_string
(
self
):
return
eval_on_val
(
self
.
val
,
"repr().c_str()"
).
string
()
val
=
self
.
val
if
val
.
type
.
code
==
gdb
.
TYPE_CODE_REF
:
val
=
val
.
referenced_value
()
return
eval_on_val
(
val
,
".repr().c_str()"
).
string
()
class
HandlePrinter
:
class
HandlePrinter
:
...
@@ -141,6 +153,23 @@ class OpDefPrinter:
...
@@ -141,6 +153,23 @@ class OpDefPrinter:
yield
field
.
name
,
concrete_val
[
field
.
name
]
yield
field
.
name
,
concrete_val
[
field
.
name
]
class
SpanPrinter
:
def
__init__
(
self
,
val
):
self
.
begin
=
val
[
'm_begin'
]
self
.
end
=
val
[
'm_end'
]
self
.
size
=
self
.
end
-
self
.
begin
def
to_string
(
self
):
return
'Span of Size {}'
.
format
(
self
.
size
)
def
display_hint
(
self
):
return
'array'
def
children
(
self
):
for
i
in
range
(
self
.
size
):
yield
"[{}]"
.
format
(
i
),
(
self
.
begin
+
i
).
dereference
()
pp
=
gdb
.
printing
.
RegexpCollectionPrettyPrinter
(
"MegEngine"
)
pp
=
gdb
.
printing
.
RegexpCollectionPrettyPrinter
(
"MegEngine"
)
# megdnn
# megdnn
pp
.
add_printer
(
'megdnn::SmallVectorImpl'
,
'^megdnn::SmallVector(Impl)?<.*>$'
,
SmallVectorPrinter
)
pp
.
add_printer
(
'megdnn::SmallVectorImpl'
,
'^megdnn::SmallVector(Impl)?<.*>$'
,
SmallVectorPrinter
)
...
@@ -154,6 +183,9 @@ pp.add_printer('mgb::imperative::LogicalTensorDesc', '^mgb::imperative::LogicalT
...
@@ -154,6 +183,9 @@ pp.add_printer('mgb::imperative::LogicalTensorDesc', '^mgb::imperative::LogicalT
pp
.
add_printer
(
'mgb::imperative::OpDef'
,
'^mgb::imperative::OpDef$'
,
OpDefPrinter
)
pp
.
add_printer
(
'mgb::imperative::OpDef'
,
'^mgb::imperative::OpDef$'
,
OpDefPrinter
)
pp
.
add_printer
(
'mgb::imperative::Subgraph'
,
'^mgb::imperative::Subgraph$'
,
ReprPrinter
)
pp
.
add_printer
(
'mgb::imperative::Subgraph'
,
'^mgb::imperative::Subgraph$'
,
ReprPrinter
)
pp
.
add_printer
(
'mgb::imperative::EncodedSubgraph'
,
'^mgb::imperative::EncodedSubgraph$'
,
ReprPrinter
)
pp
.
add_printer
(
'mgb::imperative::EncodedSubgraph'
,
'^mgb::imperative::EncodedSubgraph$'
,
ReprPrinter
)
# imperative dispatch
pp
.
add_printer
(
'mgb::imperative::ValueRef'
,
'^mgb::imperative::ValueRef$'
,
ToStringPrinter
)
pp
.
add_printer
(
'mgb::imperative::Span'
,
'^mgb::imperative::Span<.*>$'
,
SpanPrinter
)
gdb
.
printing
.
register_pretty_printer
(
gdb
.
current_objfile
(),
pp
)
gdb
.
printing
.
register_pretty_printer
(
gdb
.
current_objfile
(),
pp
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录