我正在使用WinDBG调试应用程序,并且PDB文件仅包含公共符号,因此“k”命令仅显示调用堆栈中的函数名称。我怎样才能显示参数?
我已经发现我可以通过启用“.symopt- 2”来显示装饰名称, 所以我可以使用Visual Studio附带的“undname.exe”从装饰名称中获取参数。从本质上讲,我希望WinDBG做同样的事情。那可能吗?是否有插件?
非常感谢提前!
(PS:Visual Studio显示参数,因此默认情况下可能会这样做)
答案 0 :(得分:4)
windbg软件包中的 dbh.exe 工具有 undec命令和-d command line option
,您可以通过在sepearte cmd中加载exe来利用它与windbg相同的基地址的行窗口和下面的检查涉及到装饰名称的手动复制粘贴
一个例子
dbh -d classmagic.exe
classmagic [1000000]: b 1350000 <-- base as loaded in windbg
classmagic [1350000]: a 1351000
?somecrap@@YAHHMND@Z
name : ?somecrap@@YAHHMND@Z
addr : 1351000
size : 0
flags : 400000
type : 0
modbase : 1350000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagPublicSymbol (a)
index : 1
classmagic [1350000]: undec ?somecrap@@YAHHMND@Z
?somecrap@@YAHHMND@Z =
int __cdecl somecrap(int,float,double,char)
classmagic [1350000]:
如果您需要自动化并且可以接受或改进正则表达式作为适当的
1)你应该在路径中有unix / linux sed.exe 的gnuwin32端口(从k1输出中剥离modname)
2)您应该在路径中使用 vc++filt 而不是undname.exe
3)你应该能够运行windbg .shell 命令
4)用 .symopt- symopt_undname
重新设计功能名称
5)运行这个衬里 .shell -ci“k1”sed s /.*!// g | VC ++ FILT 强>
k1 仅使用一帧(top of stack
)
.shell -ci 接受windbg命令和passes the commands output to an external application
sed剥离模块名称和爆炸字符 xxxxx!并将其传递给 vc ++ filt
vc ++ filt去除符号名称并返回正式名称
函数名称为windbg屏幕
以下示例
0:000> k1
ChildEBP RetAddr
001cf904 013513b5 classmagic!?somecrap@@YAHHMND@Z
0:000> .shell -ci "k1" sed s/.*!//g | vc++filt
ChildEBP RetAddr
int __cdecl somecrap(int,float,double,char)
答案 1 :(得分:1)
这取决于可用符号的类型。
公共符号,不包含有关形式参数的信息。这是explained to great length here(注意:此页面也可以在windbg帮助文件中找到,搜索&#34;公共和私人符号&#34;)。
另一方面,函数包含在私有符号中 数据和公共符号表,但同时是私有符号数据 包括函数名称,地址,FPO记录,输入参数 名称和类型以及输出类型,公共符号表包括 只是函数名称,地址和FPO记录。
x
,ln
(或其他一些命令,例如.fnent
)应该会为您提供此类信息。
记事本示例:
0:004> x notepad!RestoreFmt
00007ff7`471251a8 notepad!RestoreFmt (<no parameter info>)
0:004> ln notepad!RestoreFmt
Browse module
Set bu breakpoint
(00007ff7`471251a8) notepad!RestoreFmt | (00007ff7`471251f8) notepad!SaveFile
Exact matches:
notepad!RestoreFmt (<no parameter info>)
请注意<no parameter info>
明确指出符号不包含所需信息。
同样适用于具有私人符号信息的另一个程序:
C ++代码:
bool DiskReaderWriter::ReadDisk(off_t offset, size_t size_to_read, std::vector<BYTE>& buffer)
Windbg:
0:001> x drive_rw!DiskReaderWriter::ReadDisk
00000000`00d202c0 drive_rw!DiskReaderWriter::ReadDisk (long, unsigned int, class std::vector<unsigned char,std::allocator<unsigned char> > *)
0:001> ln drive_rw!DiskReaderWriter::ReadDisk
Browse module
Set bu breakpoint
g:\app\cpp\drive_rw\diskreaderwriter.cpp(72)
(00000000`00d202c0) drive_rw!DiskReaderWriter::ReadDisk | (00000000`00d20410) drive_rw!std::_Iterator_base12::_Adopt
Exact matches:
drive_rw!DiskReaderWriter::ReadDisk (long, unsigned int, class std::vector<unsigned char,std::allocator<unsigned char> > *)