如何避免将 DbgCommand 命令写入日志文件 [英] How to avoid the DbgCommand command being written to the logfile
问题描述
我在使用 Pykd.pyd
时遇到了一个烦人的问题:我在脚本中使用它,启动几个 DbgCommand
函数,例如:
I'm having an annoying issue with Pykd.pyd
: I'm using it in a script, launching several DbgCommand
functions, like:
DbgCommand("dt 0x000000eab8748430 CMap<int,int,CUIntArray *,CUIntArray *> m_nCount")
这用于获取CMap
对象的大小.由于这是在脚本中完成的,使用了大量对象,我在 Windbg
中使用日志文件(菜单 edit
,Open/Close Log File
>),这是一个问题:
在 Windbg
窗口中查看时,我只看到 DbgCommand
调用的结果,但在日志文件中我也看到了命令本身:
This for getting the size of the CMap
object. As this is done in a script, using lots and lots of objects, I am using logfiles in Windbg
(menu edit
, Open/Close Log File
), and here's the catch:
When looking at this in Windbg
window, I only see the results of the DbgCommand
calls, but in the logfile I see the command itself too:
Windbg
窗口:
000000eab87488f0 CMap<int,int,CUIntArray *,CUIntArray *> Size:[0] // formatted DbgCommand result
000000eab8748930 CMap<int,int,CUIntArray *,CUIntArray *> Size:[0] // formatted DbgCommand result
日志文件:
dt 0x000000eab87488f0 CMap<int,int,CUIntArray *,CUIntArray *> m_nCount // DbgCommand command
000000eab87488f0 CMap<int,int,CUIntArray *,CUIntArray *> Size:[0] // formatted DbgCommand result
dt 0x000000eab8748930 CMap<int,int,CUIntArray *,CUIntArray *> m_nCount // DbgCommand command
000000eab8748930 CMap<int,int,CUIntArray *,CUIntArray *> Size:[0] // formatted DbgCommand result
如何避免将 DbgCommand
命令写入日志文件?
How can I avoid DbgCommand
commands being written to the logfile?
同时我发现存在一个参数suppressoutput
,它可以用于不在屏幕上显示命令的结果,但这不是我的意思,正如你在以下摘录:
Meanwhile I've found out that a parameter suppressoutput
exists, which can be used for not showing the result of the command on screen, but this is not what I mean, as you can see in following excerpts:
测试脚本摘录:
dprintln("1 : x /2 <application_name>!CStringList::CStringList, true")
dbgCommand("x /2 <application_name>!CStringList::CStringList", True)
dprintln("2 : x /2 <application_name>!CStringList::CStringList, false")
dbgCommand("x /2 <application_name>!CStringList::CStringList", False)
dprintln("3")
屏幕上的结果:
1 : x /2 <application_name>!CStringList::CStringList, true
2 : x /2 <application_name>!CStringList::CStringList, false
004b6d3e <application_name>!CStringList::CStringList
3
结果在日志文件中:
1 : x /2 <Application>!CStringList::CStringList, true
x /2 <Application>!CStringList::CStringList
004b6d3e <Application>!CStringList::CStringList
2 : x /2 <Application>!CStringList::CStringList, false
x /2 <Application>!CStringList::CStringList
004b6d3e <Application>!CStringList::CStringList
3
似乎 suppressoutput
是为了不在屏幕上显示 DbgCommand
结果,而我感兴趣的是不在屏幕上显示 DbgCommand
输入日志.
It seems that suppressoutput
is meant for not showing DbgCommand
result on screen, while I'm interested in not showing DbgCommand
input in the logs.
让我解释一下 typedvar
解决方案有什么问题:
Let me explain what's wrong with the typedvar
solution:
由于一些奇怪的原因,CMap
和 CArray
对象不能以简单的方式使用(标准的 windbg
命令),因为你可以在这里看到:
For some strange reason, CMap
and CArray
objects can't be used in a simple way (standard windbg
command), as you can see here:
0000000000335e90 <application_name>!CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const * __ptr64,int,int>
如您所见,dt
对此不起作用:
As you can see, dt
does not work on this:
dt 0x0000000000335e90 <application_name>!CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const * __ptr64,int,int>
Symbol <application_name>!CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const * __ptr64,int,int> not found
这可以通过删除
和 __ptr64
(不要忘记空格)来处理:
This can be handled by removing the <application_name>
and __ptr64
(don't forget the space):
0:000> dt 0x0000000000335e90 CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const *,int,int>
<application_name>!CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const *,int,int>
+0x000 __VFN_table : 0x00000001`3fc77ac8
+0x008 m_pHashTable : (null)
+0x010 m_nHashTableSize : 0x11
+0x018 m_nCount : 0n0
+0x020 m_pFreeList : (null)
+0x028 m_pBlocks : (null)
+0x030 m_nBlockSize : 0n10
这似乎与以下 x/2 *!*
结果一致:
This seems to correspond with following x /2 *!*
result:
00000001`3fc77ac8 <application_name>!CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const * __ptr64,int,int>::`vftable'
但是,如果我尝试使用 typedVar
它似乎不起作用:
However if I try to use typedVar
it seems not to work:
if type_name.find("CMap<") != -1:
dprintln("original type name : [%s]" % type_name)
dprintln(("pointer : [0x" + pointer_format + "]") % ptr)
var = typedVar(type_name, ptr) # before translation of __ptr64
nieuwe_grootte1 = var.m_nCount
type_name = type_name.replace(application_name + "!","") # Normally type_name starts with "<application_name>!CMap<...", it must become "CMap<..."
type_name = type_name.replace(" __ptr64","") # apparently, when the CMap definition contains __ptr64, it doesn't work
# dt 0x000000eab8748430 CMap<int,int,CUIntArray *,CUIntArray *> m_nCount seems to work
dprintln("after replacements type name : [%s]" % type_name)
var = typedVar(type_name, ptr) # after translation of __ptr64
nieuwe_grootte2 = var.m_nCount
grootte_result = dbgCommand(("dt 0x" + pointer_format + " %s m_nCount") % (ptr,type_name)).split(' : ')
grootte = grootte_result[-1].split('\n')[0] # list[-1] is Python for "take the last entry of a list"
grootte = grootte.replace("0n","")
dprintln((pointer_format + "\t%s\t Size:[%s, %d, %d]") % (ptr, type_name, grootte, nieuwe_grootte1, nieuwe_grootte2))
这给出了以下结果:
original type name : [<application_name>!CMap<unsigned int,unsigned int,enum CService::PARAMETER_TYPE,enum CService::PARAMETER_TYPE>]
pointer : [0x00000000003355e0]
after replacements type name : [CMap<unsigned int,unsigned int,enum CService::PARAMETER_TYPE,enum CService::PARAMETER_TYPE>]
00000000003355e0 CMap<unsigned int,unsigned int,enum CService::PARAMETER_TYPE,enum CService::PARAMETER_TYPE> Size:[105, 105, 105]
original type name : [<application_name>!CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const * __ptr64,int,int>]
pointer : [0x0000000000335640]
Traceback (most recent call last):
File "C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\heap_stat_extra.py", line 215, in <module>
var = typedVar(type_name, ptr) # before translation of __ptr64
TypeException: <application_name>!CMap<ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >,wchar_t const * __ptr64,int,int> : invalid type name
我已经尝试删除
和/或 __ptr64
但似乎没有解决问题.此外,dt
和 "x/2 !" 的结果(格式不正确)清楚地表明存在上述类型.typedVar
似乎在处理 __ptr64
标签时存在实际问题.有解决方法吗?
I have already tried removing <application_name>
and/or __ptr64
but it seems not to solve the issue. Moreover, the result of dt
and "x /2 !" (this does not format correctly) clearly indicate that the mentioned type is present. It seems that typedVar
has real problems dealing with the __ptr64
tag. Is there a workaround for this?
编辑
我刚刚尝试过,使用来自 pykd_team 的 Python 命令,但它似乎仍然不起作用(这次是在 CArray
对象上),如您所见:
Edit
I've just tried, using the Python commands from pykd_team, but still it seems not to be working (this time on CArray
objects), as you can see:
启动我的脚本给出以下结果:
Launching my script gives following result:
File "C:\Temp_Folder\blabla\heap_stat_logs_backup.py", line 232, in <module>
collection_Size = typedVar(type_name, ptr).m_nCount
TypeException: CArray<CSyncRules::VersionRestriction *,CSyncRules::VersionRestriction * const &> : invalid type name
试图调查什么是正确的类名:
Trying to investigate what's the correct classname:
0:000> !py
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> app = pykd.module("<Application>")
>>> for tp in app.enumTypes("*CArray*"):
... print tp
...
CArray<CSyncRules::VersionRestriction *,CSyncRules::VersionRestriction * const &>
...
如您所见,类名是完全匹配的,但仍有 TypeException
.你知道现在该怎么做吗?(顺便说一下,我正在使用 Visual Studio Professional 2017)
As you can see, the classname is an exact match, but yet there's a TypeException
. Do you have any idea what to do now? (By the way, I'm working with Visual Studio Professional 2017)
新编辑
问题很可能是由 PYKD 引起的,无法处理类型定义中的星号 (*
).我可以使用任何转义字符来避免上述问题吗?
Most probably the issue is caused by PYKD, not being able to handle the asterisk signs (*
) in the type definitions. Is there any escape character I can use in order to avoid the mentioned problems?
推荐答案
使用 pykd.typedVar 类.专为此类情况设计
Use pykd.typedVar class. It is specialy designed for such cases
这篇关于如何避免将 DbgCommand 命令写入日志文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!