??xml version="1.0" encoding="utf-8" standalone="yes"?>精品99久久aaa一级毛片,久久噜噜久久久精品66,久久久久人妻一区二区三区http://www.shnenglu.com/woaidongmao/category/16864.html文章均收录自他h博客Q但不喜标题前加-[转脓]Q因其丑陋,见谅Q~zh-cnTue, 10 May 2011 05:33:16 GMTTue, 10 May 2011 05:33:16 GMT60VC6 Release下,产生 MiniDump的编译设|?/title><link>http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146100.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Tue, 10 May 2011 05:05:00 GMT</pubDate><guid>http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146100.html</guid><wfw:comment>http://www.shnenglu.com/woaidongmao/comments/146100.html</wfw:comment><comments>http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146100.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/woaidongmao/comments/commentRss/146100.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/woaidongmao/services/trackbacks/146100.html</trackback:ping><description><![CDATA[<p>1、Generate debug必须选上Q否则没有调试信?/p> <p><a href="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VC6_B498/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VC6_B498/image_thumb.png" width="681" height="457"></a> </p> <p> </p> <p>2、把优化disableQ否则容易生代码地址偏移Q?/p> <p>3、用program database产生PDB文gQ?/p> <p><a href="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VC6_B498/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VC6_B498/image_thumb_1.png" width="681" height="457"></a> </p> <p> </p> <p>4、将dll, exe, pdbQ加上版本号Q防止下ơ开发编译时把老的PDB冲掉?/p> <p>5、发布的版本Q输出到一个固定目录,防止Zؓ删除DebugQ?RelaseD丢失</p> <p><a href="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VC6_B498/image_6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/VC6_B498/image_thumb_2.png" width="681" height="457"></a> </p> <p>6、对于已l稳定的版本dll, exeQ编译时Q可优化开启。(虽然偶然有代码地址偏移Q但是还可以接受Q?/p> <p>7、生成MiniDumpӞ用MiniDumpWithDataSegs方式Q这P全局变量的g可查?/p><img src ="http://www.shnenglu.com/woaidongmao/aggbug/146100.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/woaidongmao/" target="_blank">肥仔</a> 2011-05-10 13:05 <a href="http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146100.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>调试Release发布版程序的Crash错误http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146092.html肥仔肥仔Tue, 10 May 2011 03:58:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2011/05/10/146092.htmlhttp://www.shnenglu.com/woaidongmao/comments/146092.htmlhttp://www.shnenglu.com/woaidongmao/archive/2011/05/10/146092.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/146092.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/146092.htmlSetUnhandledExceptionFilter + StackWalker
 
    q个Ҏ需要自己动手往工程里添加代码了。要实现上面的想法,需要做两g事情Q?span lang="EN-US">1、需要在crash时有Z对程序堆栈进行处理;2、对堆栈信息q行攉?span lang="EN-US">
 
    1?span lang="EN-US">SetUnhandleExceptionFilter函数
 
    Windowsq_下的C++E序异常通常可分ZU:l构化异常(Structured ExceptionQ可以理解ؓ与操作系l相关的异常Q和C++异常。对于结构化异常处理Q?span lang="EN-US">SEHQ,可以扑ֈ很多资料Q在此不l说。对?span lang="EN-US">crash错误Q一般由未被正常捕获的异常引PWindows操作pȝ提供了一?span lang="EN-US">API函数可以在程?span lang="EN-US">crash之前有机会处理这些异常,是SetUnhandleExceptionFilter函数。(C++也有一个类似函?span lang="EN-US">set_terminate可以处理未被捕获?span lang="EN-US">C++异常。)
 
    SetUnhandleExceptionFilter函数声明如下Q?span lang="EN-US">
 
    LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
      __in          LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
    );
 
    其中 LPTOP_LEVEL_EXCEPTION_FILTER 定义如下Q?span lang="EN-US">
 
    typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)(
        __in struct _EXCEPTION_POINTERS *ExceptionInfo
    );
    typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
 
    单来_SetUnhandleExceptionFilter允许我们讄一个自q函数作ؓ全局SEHqo函数Q当E序crash前会调用我们的函数进行处理。我们可以利用的?_EXCEPTION_POINTERS l构cd的变?span lang="EN-US">ExceptionInfoQ它包含了对异常的描qC及发生异常的U程状态,qo函数可以通过q回不同的值来让系ll运行或退出应用程序?span lang="EN-US">
 
    关于 SetUnhandleExceptionFilter 函数的具体用法和CZ请参?span lang="EN-US">MSDN?span lang="EN-US">
 
 
 
    2?span lang="EN-US">StackWalker
    现在我们已经有机会可以在crash之前对程序状态信息进行处理了Q只需要生成ƈ保存堆栈信息大功告成了?span lang="EN-US">Windows?span lang="EN-US">dbghelp.dll库提供了一个函数可以得到当前堆栈信息:StackWalk64Q在Win2K以前版本中ؓStackWalkQ。该函数声明如下Q?span lang="EN-US">
 
    BOOL WINAPI StackWalk64(
      __in          DWORD MachineType,
      __in          HANDLE hProcess,
      __in          HANDLE hThread,
      __in_out      LPSTACKFRAME64 StackFrame,
      __in_out      PVOID ContextRecord,
      __in          PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
      __in          PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
      __in          PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
      __in          PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
    );
    该函数的具体用法可以参?span lang="EN-US">MSDN。在q里推荐一个牛人写好的StackWalkerQ可以直接拿来用Q开源的?span lang="EN-US">StackWalker提供了一个基c,l出了几个简单的接口Q可以方便地生成堆栈信息Qƈ且支持一pdVC版本Q非常好用。我们可以自己写一个子c,q载虚函数OnOutputQ就可以堆栈信息输Zؓ特定格式了?span lang="EN-US">StackWalker的地址为:http://www.codeproject.com/KB/threads/StackWalker.aspx?/span>
 
    不过对于Release版本来说Q?span lang="EN-US">StackWalk64函数获得的堆栈信息有可能不完整。如果异常是?span lang="EN-US">MFC的模块抛出,那么获得的堆栈可能缺前面调用模块信息。另外,StackWalk64需要最新的dbghelp.dll文g支持才能工作Q要正确输出crash的函数名和行P需要要pdb文g支持。以上不x可能影响输出信息的完整性和效果Q而对于发布在外的E序Q要带上pdb文g几乎不可能,因此q个Ҏq是有缺憄Q比较适用于本地的release版本调试?span lang="EN-US">
 
当我们把自己?span lang="EN-US">release版本E序发布出去以后Q一般都是在用户的机器上q行。这U情况下Q对于第四种ҎQ因为需?span lang="EN-US">pdb文g才能够正生成堆栈调用的函数行号及代码行P因此Ҏ四只适用于本?span lang="EN-US">release版的调试Q否则只能生成不完整的堆栈信息。对于前三种ҎQ其实只需要用户告知崩溃地址Q然后在本地查找crash地址可以了Q但是定?span lang="EN-US">crash的过E非怸方便Q如?span lang="EN-US">crash的情冉|较多Q前三种Ҏ都不合适。而且Q前三种Ҏ均不能生成堆栈调用信息,对于debug的作用有限?span lang="EN-US">
 
    下面我们来看一个更加完善的解决Ҏ?span lang="EN-US">
 
 
 
    Ҏ五:SetUnhandledExceptionFilter + Minidump
 
    SetUnhandleExceptionFilter函数我们已经介绍q了Q本Ҏ的思\q是要利用我们自q异常处理函数Q来生成minidump文g?span lang="EN-US">
 
    1?span lang="EN-US">Minidump概念
 
    minidumpQ小存储器{储)可以理解Z?span lang="EN-US">dump文gQ里面记录了能够帮助调试crash的最有用信息。实际上Q如果你?pȝ属?span lang="EN-US"> -> 高 -> 启动和故障恢?span lang="EN-US"> -> 讄 -> 写入调试信息 中选择?/span>内存{?span lang="EN-US">(64 KB)?/span>的话Q当pȝ意外停止旉会在C:\Windows\Minidump\路径下生成一?span lang="EN-US">.dmp后缀的文Ӟq个文g是minidump文gQ只不过q个是内核态的minidump?span lang="EN-US">
 
   我们要生成的是用h的minidumpQ文件中包含了程序运行的模块信息、线E信息、堆栈调用信息等。而且ZW合?span lang="EN-US">mini的特性,dump文g是压~过的?span lang="EN-US">
 
    2、生?span lang="EN-US">minidump文g
 
    生成minidump文g?span lang="EN-US">API函数?span lang="EN-US">MiniDumpWriteDumpQ该函数需?span lang="EN-US">dbghelp.lib支持Q其原型如下:
 
    BOOL WINAPI MiniDumpWriteDump(
      __in          HANDLE hProcess,
      __in          DWORD ProcessId,
      __in          HANDLE hFile,
      __in          MINIDUMP_TYPE DumpType,
      __in          PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
      __in          PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
      __in          PMINIDUMP_CALLBACK_INFORMATION CallbackParam
    );
 
    在我们的异常处理函数中加入以下代码:
 
    HANDLE hFile = ::CreateFile( _T("E:\\dumpfile.dmp"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
     if( hFile != INVALID_HANDLE_VALUE)
     {
         MINIDUMP_EXCEPTION_INFORMATION einfo;
         einfo.ThreadId = ::GetCurrentThreadId();
         einfo.ExceptionPointers = pExInfo;
         einfo.ClientPointers = FALSE;
 
        ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal, &einfo, NULL, NULL);
        ::CloseHandle(hFile);
     }
 
    其中Q?span lang="EN-US">pExInfo变量为异常处理函?span lang="EN-US">PEXCEPTION_POINTERScd的参数。具体请参?span lang="EN-US">MSDN?span lang="EN-US">
 
    3、调?span lang="EN-US">minidump
 
    调试dump文g首先需?span lang="EN-US">pdb文gQ因此我?span lang="EN-US">buildE序旉要设|?span lang="EN-US"> Debug Infomation Format ?span lang="EN-US"> “Program DatabaseQ?span lang="EN-US">/ZiQ?span lang="EN-US">?/span>。其ơ,我们q要保所用的dump文g与源代码?span lang="EN-US">exe?span lang="EN-US">pdb文g版本是一致的Q这要求我们必须l护好程序版本信息?span lang="EN-US">
 
    调试minidump最方便的环境就?span lang="EN-US">VS了,我们只要?span lang="EN-US">.dmp?span lang="EN-US">.exe?span lang="EN-US">.pdb文g攑֜一个\径下Q保证源代码文g的\径与~译时的路径一致就可以了,剩下的就?span lang="EN-US">VS帮我们完成。双?span lang="EN-US">.dmp文g或者在文g打开工程中选择“dump files?/span>Q加?span lang="EN-US">dump文gQ然后按F5q行p直接恢复crash时的现场了,你可以定?span lang="EN-US">crash的代码,可以查看调用堆栈Q可以查看线E和模块信息...一切都跟你讄断点调试一P太强大了Q看个截囑֐?span lang="EN-US">
 
    需要注意的是,对于release版的E序来说Q很多代码是l过~译器优化过的,因此定位的时候可能会有所偏差Q大家可以考虑讄选项L代码优化?span lang="EN-US">
 
    其他可以调试minidump的工兯?span lang="EN-US">WinDbg{,大家可以查阅相关资料?span lang="EN-US">

 



肥仔 2011-05-10 11:58 发表评论
]]>
使用MiniDumpWriteDump API 来生成程序的Dumphttp://www.shnenglu.com/woaidongmao/archive/2011/05/10/146086.html肥仔肥仔Tue, 10 May 2011 03:08:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2011/05/10/146086.htmlhttp://www.shnenglu.com/woaidongmao/comments/146086.htmlhttp://www.shnenglu.com/woaidongmao/archive/2011/05/10/146086.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/146086.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/146086.htmlMiniDumpWriteDump?span lang="EN-US">MS DbgHelp.dll 中一?span lang="EN-US">API, 用于导出当前q行的程序的Dump. q个dllE序pȝ中就?span lang="EN-US">, 但是很多软g, 都在自己的安装目录下保存了这?span lang="EN-US">.dll的最新的版本.

Z试q个API, 参考网上一些资?span lang="EN-US">, 写了一个简单的C++ E序. 目的是当有异常发生的时?span lang="EN-US">, 自动生成Dump文g供之后的分析. 有了Dump文g, 我们可以?span lang="EN-US">WinDBG{调试器来分析异常发生时的情?span lang="EN-US">. 其实q个功能很多软g都有, 比如QQ, 兽世界, {等. 它们在出C异常的时候会弹出一个对话框, 让用戯入异常发生时的情?span lang="EN-US">, 然后把异常的dump文g?span lang="EN-US">email发回, 供开发者们分析修改bug.

不过有一?span lang="EN-US">, q里需要程序的调试W号文g(pdb文g). 对于Debug版来?span lang="EN-US">, 是生成的, 但是Release版来说默认是不生成的. 可以讄VC的编译器, 让它?span lang="EN-US">Release版的时候也生成调试信息. q带来一个新的问?span lang="EN-US">, 因ؓ.pdb里面是保存了源文件的信息?span lang="EN-US">, Z避免泄密, 可以采用VS中的CVPack工具, 从中去除敏感的信?span lang="EN-US">.

E序需要?b>Dbghelp.h ?Dbghelp.lib . 它们可以?span lang="EN-US">MSDN扑ֈ.

//最主要的函?span lang="EN-US">, 生成Dump
static void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo)
{
if (excpInfo == NULL)
//如果没有传入异常, 比如是在E序里面调用?span lang="EN-US">, 生成一个异?/span>
{
// Generate exception to get proper context in dump
__try
{
OutputDebugString(_T("raising exception\r\n"));
RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL);
}
__except(DumpMiniDump(hFile, GetExceptionInformation()),
EXCEPTION_CONTINUE_EXECUTION)
{
}
}
else
{
OutputDebugString(_T("writing minidump\r\n"));
MINIDUMP_EXCEPTION_INFORMATION eInfo;
eInfo.ThreadId = GetCurrentThreadId();
//把需要的信息添进?/span>
eInfo.ExceptionPointers = excpInfo;
eInfo.ClientPointers = FALSE;

    // 调用, 生成Dump. 98不支?span lang="EN-US">
// Dump
的类型是型?span lang="EN-US">, 节省I间. 可以参?span lang="EN-US">MSDN生成更详l的Dump.
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
excpInfo ? &eInfo : NULL,
NULL,
NULL);
}
}

下面的是E序部分:

int _tmain(int argc, _TCHAR* argv[])
{
// 创徏一?span lang="EN-US">Dump文g
HANDLE hFile = CreateFile( _T("MiniDump.dmp"), GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
int code;
__try
{  
// 把自己实现的main函数包装一?span lang="EN-US">, 攑֜try .. except 块中. q样出现了异常可以自动生?span lang="EN-US">dump
main_wrapper(argc, argv);
}
__except( code=GetExceptionCode(), DumpMiniDump(hFile, GetExceptionInformation() ),       EXCEPTION_EXECUTE_HANDLER )
//出现了异?span lang="EN-US">, 记录异常?span lang="EN-US">code, 生成dump!!
{
printf("%x\n", code);
wchar_t msg[512];
wsprintf(msg, L"Exception happened. Exception code is %x", code);
MessageBox(NULL, msg, L"Exception", MB_OK);
//昄消息l用?/span>
}
CloseHandle( hFile );
//关闭Dump文g
getchar();
return 0;
}

最下面是两个测试的函数, main_wrapper函数调?span lang="EN-US">test1, test1会生成一个异?span lang="EN-US">(非法内存?span lang="EN-US">)

void test1() {
int *p;
p = (int*)0x100;
*p = 0;
//?span lang="EN-US">0x100地址, q个是非法的
}

void main_wrapper(int argc, _TCHAR* argv[]) {
test1();
}

q行, 异常被捕获了:

clip_image001

同时, dump文g也生成了:

clip_image002

?span lang="EN-US">WinDBG打开Dump文g, 可以清楚的看出异常出现的情况:

clip_image003


从中可以比较清楚的看到异常发生的情况(Exception code), 异常出现的地址(test1函数, 偏移0x28). 因ؓq次试的是Debug?span lang="EN-US">, 有保存了源代码的.pdb文g, 所?span lang="EN-US">WinDbg把源代码也列出来?span lang="EN-US">. q样可以非常Ҏ的发现问?span lang="EN-US">.

============================================

参?span lang="EN-US">:
DbgHelp
中的DumpAPI例子: http://www.debuginfo.com/examples/src/effminidumps/MiniDump.cpp
CrashReport:
E序出现异常的时候显C发送错误的对话?span lang="EN-US">, q把Dump文g发送到指定的地址. http://code.google.com/p/crashrpt/
XCrashReport:
与上面的cM的一个开源项?span lang="EN-US">. http://www.codeproject.com/KB/debug/XCrashReportPt1.aspx



肥仔 2011-05-10 11:08 发表评论
]]>
W号文g&mdash;&mdash;Windows 应用E序调试必备http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146084.html肥仔肥仔Tue, 10 May 2011 03:02:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2011/05/10/146084.htmlhttp://www.shnenglu.com/woaidongmao/comments/146084.htmlhttp://www.shnenglu.com/woaidongmao/archive/2011/05/10/146084.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/146084.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/146084.html一、何谓符hӞ

  W号文gQ?span lang="EN-US">Symbol FilesQ是一个数据信息文Ӟ它包含了应用E序二进制文Ӟ比如Q?span lang="EN-US">EXE?span lang="EN-US">DLL{)调试信息Q专门用来作调试之用Q最l生成的可执行文件在q行时ƈ不需要这个符hӞ但你的程序中所有的变量信息都记录在q个文g中。所以调试应用程序时Q这个文件是非常重要的。用 Visual C++ ?span lang="EN-US"> WinDbg 调试E序旉要用到这个文件?span lang="EN-US">
  ?span lang="EN-US"> Windows pȝ中,W号文g?span lang="EN-US"> .pdb 为扩展名Q比如:每个 Windows 操作pȝ下有一?span lang="EN-US"> GDI32.dll 文gQ编译器在编译该 DLL 的时候会产生一?span lang="EN-US"> GDI32.pdb 文gQ一旦你拥有了这?span lang="EN-US"> PDB 文gQ那么便可以用它来调试ƈ跟踪?span lang="EN-US"> GDI32.dll 内部。该文g和二q制文g的编译版本密切相养I比如修改?span lang="EN-US"> DLL 的输出函敎ͼ再编译该 DLLQ那么原先的 PDB 文gp时了Q不能再用老的 PDB 文g来做调试工作,而必M用最新的 PDB 文g版本?span lang="EN-US">
  Visual C++ ~译代码后会?span lang="EN-US"> Debug 或?span lang="EN-US"> Release 目录下生成一?span lang="EN-US"> PDB 文g。一般情况下Q符h件包括以下的数据信息Q?span lang="EN-US">

  1. 全局变量Q?span lang="EN-US">Global variablesQ;
  2. 局部变量(Local variablesQ;
  3. 函数名和它们的入口地址Q?span lang="EN-US">Function names and the addresses of their entry pointsQ;
  4. FPO 数据Q?span lang="EN-US">Frame Pointer Omission)Q?span lang="EN-US">Frame Pointer 是一U用来在调用堆栈Q?span lang="EN-US">Call stackQ中扑ֈ下一个将要被调用的函数的数据l构源代码的行序PSource-line numbersQ;

二、如何得到和安装W号文g?

  1. 先确定你的操作系l(OSQ版本;
  2. 到微软网站下载相应的W号文gQ?
  3. 安装W号文gQ对于符h件的安装位置没有特贝要求Q可以安装在M目录中;
  4. 讄环境变量Q得调试工P比如Q?span lang="EN-US">Visual C++?span lang="EN-US">WinDbg?span lang="EN-US">Ntsd?span lang="EN-US">DrWatson {)能找到符hӞ

安装W号文g的注意事:

  如果是手动安装符hӞ有一点很重要Q那是宿主机(Hostt ComputerQ上的符h件必M目标机器Q?span lang="EN-US">Target Computer
Q上?span lang="EN-US"> Windows 版本相匹配?span lang="EN-US">
  q里所谓的宿主机指的是q行调试会话的机器,在典型的双系l调试会话环境中Q宿L可以是连接到目标机器的Q何机器。目标机器指的是发生软glg、系l服务、应用程序或操作pȝq行p|的机器。也x需要被调试的机器,它是调试会话x的焦炏V目标机器可以近在咫,也可以位于完全不同的地方。有时我们也目标机器称之ؓ—?/span>被调试者(debuggeeQ,那么与之对应Q宿L则可以称试者(debuggerQ?span lang="EN-US">

三、在 Visual C++ 使用W号文g的方?/span>

?span lang="EN-US"> Visual C++ 6.0 中的使用ҎQ?span lang="EN-US">

  1. 打开 Visual C++ 6.0 ?span lang="EN-US"> Workspace 文gQ?span lang="EN-US">*.dswQ;
  2. q入 Tools 菜单Q选择 Options 菜单?span lang="EN-US"> (Tools->Options)Q?
  3. 单击 Directoties 标签Q?
  4. ?span lang="EN-US"> “Show directories for?/span>下拉列表中选择 “Executable files?/span>Q?
  5. 符h件的路径d?span lang="EN-US"> “Directories?路径列表中;
  6. 单击  OK 完成Q?

?span lang="EN-US"> Visual C++ .NET 2003 中的使用ҎQ?span lang="EN-US">

  1. 打开 Visual C++ .NET 的项目文Ӟ*.vcprojQ;
  2. 在解x案管理器中选中要用符h件的目Q?
  3. 单击右键q入目属性对话框Q?
  4. 选择?/span>配置属?span lang="EN-US">?/span>中的?/span>调试?/span>Q?
  5. 在与?/span>调试?/span>对应?span lang="EN-US">?/span>操作?/span>选项中有一?span lang="EN-US">?/span>W号路径?/span>Q在此添加符h件的路径卛_Q?
  6. 单击  ?/span>定?完成Q?

四、如何?span lang="EN-US"> Release 版本二进制文件对应的 PDB 文g?

?span lang="EN-US"> Visual C++ 6.0 中的ҎQ?span lang="EN-US">

  1. 打开 Visual C++ 6.0 ?span lang="EN-US"> Workspace 文gQ?span lang="EN-US">*.dswQ;
  2. q入 Project 菜单Q选择 Settings 菜单?span lang="EN-US"> (Project->Settings)Q打开目讄对话框;
  3. ?span lang="EN-US"> “Settings for?/span>列表中选择目?span lang="EN-US"> Release 配置Q?
  4. 单击“C/C++?/span>标签Q?
  5. ?span lang="EN-US">“Category?/span>下拉列表框中选择“General?/span>选项Q?
  6. ?span lang="EN-US">“Debug info?/span>下拉列表框中选择调试信息格式Q具体选项参见图一Q,在此不必用M优化选项Q?
  7. 单击“Link?/span>标签Q?
  8. ?span lang="EN-US">“Category?/span>下拉列表框中选择“Debug?/span>选项Q?
  9. 选中“Debug info?/span>复选框Q然后选择需要的链接调试cdQ具体选项参见图一Q;
  10. 不要选择“Separate types?/span>复选框Q?
  11. ?span lang="EN-US">“Project options?/span>~辑框的最后添加如下指令:/opt:ref,icfQ?
  12. 重新生成Q?span lang="EN-US">RebuildQ项目;

?span lang="EN-US"> Visual C++ .NET 2003 中的ҎQ?span lang="EN-US">

  1. 打开 Visual C++ .NET 的项目文Ӟ*.vcprojQ;
  2. q入 Project 菜单Q选择 Settings 菜单?span lang="EN-US"> (Project->Settings)Q打开目讄对话框;
  3. ?span lang="EN-US"> ?/span>配置?/span>下拉列表中选择目?span lang="EN-US"> ?/span>Q活动)Release?配置Q?
  4. 选择?/span>配置属?span lang="EN-US">?/span>树型节点中的“C/C++?==?span lang="EN-US">?/span>常规?/span>Q?
  5. 讄双?span lang="EN-US">?/span>调试信息格式?/span>选项Q具体选项参见图一Q;
  6. 选择?/span>配置属?span lang="EN-US">?/span>树型节点中的?/span>链接?span lang="EN-US">?=?span lang="EN-US">?/span>调试?/span>Q?
  7. 讄双?span lang="EN-US">?/span>生成E序数据库文?span lang="EN-US">?/span>Q具体选项参见图一Q;
  8. 选择?/span>配置属?span lang="EN-US">?/span>树型节点中的?/span>链接?span lang="EN-US">?=?span lang="EN-US">?/span>命o?span lang="EN-US">?/span>Q?
  9. ?span lang="EN-US">?/span>附加选项(D)?/span>~辑框中d如下指oQ?span lang="EN-US">/opt:ref,icfQ?
  10. ?span lang="EN-US">?/span>定?/span>退出;
  11. 重新生成Q?span lang="EN-US">RebuildQ项目;

clip_image001

图一

五、关?span lang="EN-US"> Free BuildQ也U?span lang="EN-US"> Retail BuildQ和 Checked BuildQ也U?span lang="EN-US"> Debug BuildQ?/span>

每个Z NT 操作pȝ有两U不同的E序生成模式Q即Q?span lang="EN-US">

  • Free Build (?span lang="EN-US"> Retail Build)
  • Checked Build (?span lang="EN-US"> Debug Build)

  Free Build 生成的是最l用L本,针对生成的二q制文gq行了彻底的优化Q禁用了调试断言Qƈ剥离了调试信息。这样一来可执行程序文件更,加蝲更快Q用的内存也更?span lang="EN-US">
  Checked Build 生成的是试和调试版本。它包含额外?span lang="EN-US"> Free Build 所没有的错误检查,参数验证和调试信息,Checked Build 有助于隔d跟踪可能D不可预见的行为的问题Q比如内存溢出,不正的讑֤配置。虽?span lang="EN-US"> Checked Build 提供了额外的保护Q但?span lang="EN-US"> Free Build 比较Q它需要更多的内存开销和磁盘空间。由于可执行E序包含W号调试信息Q调试时要执行附加的代码、参数检查和输出调试诊断信息Q从而导致性能下降?span lang="EN-US">

六、系l符h件的更新Ҏ

  pȝW号文g?span lang="EN-US"> Windows 操作pȝ依赖的那几个重要?span lang="EN-US"> DLL/SYS 和可执行文g对应的符hӞ常见的比如:gdi32.dll?span lang="EN-US">Kernel32.dll?span lang="EN-US">Kerberos.dll?span lang="EN-US">psapi.dll?span lang="EN-US">user32.dll{,使用 WinDbg 调试Ӟ你就会发现系l符h?span lang="EN-US">(PDB)有多重要Q这些文仉与本地的 OS 密切相关Q比如,Windows 2000 打了SP补丁的话Q那么必L新系l符h件才能进行相兌试,原来的符h件与打补丁后的系l就会不匚wQ怎么办呢? 可以通过|络来更斎ͼ象下面这样在 WinDbg ?span lang="EN-US"> Symbols Path 里面输入路径Q?span lang="EN-US">

SRV*D:\Symbols\websymbols*http://msdl.microsoft.com/download/symbols

Q斜体部分是你在本地保存W号文g的\径)

  如果你不是通过代理上网Q那么在你用 WinDbg 打开一个被调试E序后,输入 symchk 回RQ?span lang="EN-US">WinDbg
׃自动的连到微软的|站Ҏ你的机器的情冉|新的 PDB 文gQƈ它保存在上面斜体部分指定的本地路径里,q样你就可以保你的W号文g版本和你机器上的文g版本一致?span lang="EN-US">

如果你是通过代理上网那么你需要配|?span lang="EN-US"> IE 的连接设|。具体方法恕不赘a

 



肥仔 2011-05-10 11:02 发表评论
]]>
功能强大的vc6调试?/title><link>http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146082.html</link><dc:creator>肥仔</dc:creator><author>肥仔</author><pubDate>Tue, 10 May 2011 03:01:00 GMT</pubDate><guid>http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146082.html</guid><wfw:comment>http://www.shnenglu.com/woaidongmao/comments/146082.html</wfw:comment><comments>http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/woaidongmao/comments/commentRss/146082.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/woaidongmao/services/trackbacks/146082.html</trackback:ping><description><![CDATA[<p style="text-align: left; line-height: 150%; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto; mso-pagination: widow-orphan" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt">要成Z位优U的Y件工E师Q调试能力必不可~。本文将较详l介l?span lang="EN-US">VC6</span>调试器的主要用法?span lang="EN-US"> <br>  windows</span>q_的调试器主要分ؓ两大c:<span lang="EN-US"> <br>  1 </span>用户模式<span lang="EN-US">(user-mode)</span>调试器:它们都基?span lang="EN-US">win32 Debugging API</span>Q有使用方便的界面,主要用于调试用户模式下的应用E序。这c调试器包括<span lang="EN-US">Visual C++</span>调试器?span lang="EN-US">WinDBG</span>?span lang="EN-US">BoundChecker</span>?span lang="EN-US">Borland C++ Builder</span>调试器?span lang="EN-US">NTSD</span>{?span lang="EN-US"> <br>  2 </span>内核模式<span lang="EN-US">(kernel-mode)</span>调试器:内核调试器位?span lang="EN-US">CPU</span>和操作系l之_一旦启动,操作pȝ也会中止q行Q主要用于调试驱动程序或用户模式调试器不易调试的E序。这c调试器包括<span lang="EN-US">WDEB386</span>?span lang="EN-US">WinDBG</span>?span lang="EN-US">softice</span>{。其?span lang="EN-US">WinDBG</span>?span lang="EN-US">softice</span>也可以调试用h式代码?span lang="EN-US"> <br>  </span>国外一位调试高手曾_?span lang="EN-US">70</span>Q调试时间是在用<span lang="EN-US">VC++</span>Q其余时间是使用<span lang="EN-US">WinDBG</span>?span lang="EN-US">softice</span>。毕竟,调试用户模式代码Q?span lang="EN-US">VC6</span>调试器的效率是非帔R的。因此,我将首先在本介l?span lang="EN-US">VC6</span>调试器的主要用法Q其他调试器的用法及一些调试技能在后箋文章中阐q?span lang="EN-US"> <br><br></span><b>一 位置断点Q?span lang="EN-US">Location Breakpoint</span>Q?/b><span lang="EN-US"> <br>  </span>大家最常用的断Ҏ普通的位置断点Q在源程序的某一行按<span lang="EN-US">F9</span>p|了一个位|断炏V但对于很多问题Q这U朴素的断点作用有限。譬如下面这D代码: <span lang="EN-US"><?xml:namespace prefix = o /><o:p></o:p></span></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">void CForDebugDlg::OnOK() <span style="mso-tab-count: 1"></span><o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">{<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>for (int i = 0; i < 1000; i++)<span style="mso-tab-count: 1">    </span>//A<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>{<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 2">              </span>int k = i * 10 - 2;<span style="mso-tab-count: 1"> </span>//B<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 2">              </span>SendTo(k);<span style="mso-tab-count: 2">          </span>//C<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 2">              </span>int tmp = DoSome(i);<span style="mso-tab-count: 1"> </span>//D<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 2">              </span>int j = i / tmp;<span style="mso-tab-count: 1">    </span>//E<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>}<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">}<span style="mso-spacerun: yes">      </span><o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-spacerun: yes">      </span><o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt" lang="EN-US">  </span><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt">执行此函敎ͼE序崩溃?span lang="EN-US">E</span>行,发现此时<span lang="EN-US">tmp</span>?span lang="EN-US">0</span>Q假?span lang="EN-US">tmp</span>本不应该?span lang="EN-US">0</span>Q怎么q个时候ؓ<span lang="EN-US">0</span>呢?所以最好能够跟t此ơ@环时<span lang="EN-US">DoSome</span>函数是如何运行的Q但׃是在循环体内Q如果在<span lang="EN-US">E</span>行设|断点,可能需要按<span lang="EN-US">F5</span>Q?span lang="EN-US">GO</span>Q许多次。这h要不停的按,很痛苦。?span lang="EN-US">VC6</span>断点修饰条g可以轻易解x问题。步骤如下?span lang="EN-US"> <br>  1 Ctrl+B</span>打开断点讄框,如下图:<span lang="EN-US"> <br><a href="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/vc6_9B2B/clip_image001_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image001" border="0" alt="clip_image001" src="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/vc6_9B2B/clip_image001_thumb.jpg" width="573" height="376" v:shapes="_x0000_i1025"></a><br><b><span style="color: blue">Figure 1</span></b></span><span style="color: blue">讄高位置断点</span><span lang="EN-US"> <br>  2 </span>然后选择<span lang="EN-US">D</span>行所在的断点Q然后点?span lang="EN-US">condition</span>按钮Q在弹出对话框的最下面一个编辑框中输入一个很大数目,具体视应用而定Q这?span lang="EN-US">1000</span>够了?span lang="EN-US"> <br>  3 </span>?span lang="EN-US">F5</span>重新q行E序Q程序中断?span lang="EN-US">Ctrl+B</span>打开断点框,发现此断点后跟随一串说明:<span lang="EN-US">...487 times remaining</span>。意思是q剩?span lang="EN-US">487</span>ơ没有执行,那就是说执行?span lang="EN-US">513</span>Q?span lang="EN-US">1000</span>Q?span lang="EN-US">487</span>Q次时候出错的。因此,我们按步?span lang="EN-US">2</span>所Ԍ更改此断点的<span lang="EN-US">skip</span>ơ数<span lang="EN-US">,</span>?span lang="EN-US">1000</span>改ؓ<span lang="EN-US">513</span>?span lang="EN-US"> <br>  4 </span>再次重新q行E序Q程序执行了<span lang="EN-US">513</span>ơ@环,然后自动停在断点处。这Ӟ我们可以仔l查?span lang="EN-US">DoSome</span>是如何返?span lang="EN-US">0</span>的。这P你就避免了手指的痛苦Q节省了旉?span lang="EN-US"> <br>  </span>再看位置断点其他修饰条g。如<b><span lang="EN-US">Figure 1</span></b>所C,?span lang="EN-US">“Enter the expression to be evaluated:?/span>下面Q可以输入一些条Ӟ当这些条件满xQ断Ҏ启动。譬如,刚才的程序,我们需?span lang="EN-US">i</span>?span lang="EN-US">100</span>时程序停下来Q我们就可以输入在编辑框中输?span lang="EN-US">“i==<?xml:namespace prefix = st1 /><st1:chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="100" unitname="”">100?/st1:chmetcnv></span>?span lang="EN-US"> <br>  </span>另外Q如果在此编辑框中如果只输入变量名称Q则变量发生改变Ӟ断点才会启动。这Ҏ一个变量何时被修改很方便,特别对一些大E序?span lang="EN-US"> <br>  </span>用好位置断点的修饰条Ӟ可以大大方便解决某些问题?span lang="EN-US"> <br><br></span><b>?数据断点Q?span lang="EN-US">Data Breakpoint</span>Q?/b><span lang="EN-US"> <br>  </span>软g调试q程中,有时会发C些数据会莫名其妙的被修改掉(如一些数l的界写导致覆盖了另外的变量)Q找Z处代码导致这块内存被更改是一件棘手的事情Q如果没有调试器的帮助)。恰当运用数据断点可以快速帮你定位何时何处这个数据被修改。譬如下面一D늨序: <span lang="EN-US"><o:p></o:p></span></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">#include "stdafx.h"<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">#include <o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><o:p> </o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">int main(int argc, char* argv[])<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">{<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>char szName1[10];<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>char szName2[4];<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>strcpy(szName1,"shenzhen");<span style="mso-tab-count: 2">              </span><o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>printf("%s\n", szName1);<span style="mso-tab-count: 2">          </span>//A<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><o:p> </o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>strcpy(szName2, "vckbase");<span style="mso-tab-count: 2">              </span>//B<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>printf("%s\n", szName1);<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>printf("%s\n", szName2);<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><o:p> </o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>return 0;<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US">}<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-spacerun: yes">      </span><o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt" lang="EN-US">  </span><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt">q段E序的输出是 <span lang="EN-US"><o:p></o:p></span></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-spacerun: yes">      </span><span style="mso-tab-count: 1">       </span>szName1: shenzhen<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>szName1: ase<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-tab-count: 1">       </span>szName2: vckbase<o:p></o:p></span></p> <p style="text-align: left; line-height: 150%; mso-pagination: widow-orphan; tab-stops: 45.8pt 91.6pt 137.4pt 183.2pt 229.0pt 274.8pt 320.6pt 366.4pt 412.2pt 458.0pt 503.8pt 549.6pt 595.4pt 641.2pt 687.0pt 732.8pt" class="MsoNormal" align="left"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: 宋体; mso-font-kerning: 0pt" lang="EN-US"><span style="mso-spacerun: yes">     </span><o:p></o:p></span></p> <p style="line-height: 150%" class="MsoNormal"><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt" lang="EN-US">szName1</span><span style="line-height: 150%; font-family: 宋体; letter-spacing: 0.75pt; font-size: 12pt; mso-bidi-font-family: tahoma; mso-font-kerning: 0pt">何时被修改呢Q因为没有明昄修改<span lang="EN-US">szName1</span>代码。我们可以首先在<span lang="EN-US">A</span>行设|普通断点,<span lang="EN-US">F5</span>q行E序Q程序停?span lang="EN-US">A</span>行。然后我们再讄一个数据断炏V如下图Q?span lang="EN-US"> <br><a href="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/vc6_9B2B/clip_image002_2.jpg"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://www.shnenglu.com/images/cppblog_com/woaidongmao/WindowsLiveWriter/vc6_9B2B/clip_image002_thumb.jpg" width="656" height="381" v:shapes="_x0000_i1026"></a><br><b><span style="color: blue">Figure 2</span></b><span style="color: blue"> </span></span><span style="color: blue">数据断点</span><span lang="EN-US"> <br>  F5</span>l箋q行Q程序停?span lang="EN-US">B</span>行,说明<span lang="EN-US">B</span>处代码修改了<span lang="EN-US">szName1</span>?span lang="EN-US">B</span>处明明没有修?span lang="EN-US">szName1</span>呀Q但调试器指明是q一行,一般不会错Q所以还是静下心来看看程序,哦,你发CQ?span lang="EN-US">szName2</span>只有<span lang="EN-US">4</span>个字节,?span lang="EN-US">strcpy</span>?span lang="EN-US">7</span>个字节,所以覆写了<span lang="EN-US">szName1</span>?span lang="EN-US"> <br>  </span>数据断点不只是对变量改变有效Q还可以讄变量是否{于某个倹{譬如,你可以将<span lang="EN-US">Figure 2</span>中红圈处改ؓ条g<span lang="EN-US">”szName2[0]==''''y''''?</span>那么?span lang="EN-US">szName2</span>W一个字Wؓ<span lang="EN-US">y</span>时断点就会启动?span lang="EN-US"> <br>  </span>可以看出Q数据断点相对位|断点一个很大的区别是不用明指明在哪一行代码设|断炏V?span lang="EN-US"> <br><br></span><b>?其他</b><span lang="EN-US"> <br>  1 </span>?span lang="EN-US">call stack</span>H口中设|断点,选择某个函数Q按<span lang="EN-US">F9</span>讄一个断炏V这样可以从深层ơ的函数调用中迅速返回到需要的函数?span lang="EN-US"> <br>  2 Set Next StateMent</span>命oQ?span lang="EN-US">debug</span>q程中,右键菜单中的命oQ?span lang="EN-US"> <br>  </span>此命令的作用是将E序的指令指针(<span lang="EN-US">EIP</span>Q指向不同的代码行。譬如,你正在调试上面那D代码,q行?span lang="EN-US">A</span>行,但你不愿意运?span lang="EN-US">B</span>行和<span lang="EN-US">C</span>行代码,q时Q你可以在<span lang="EN-US">D</span>行,右键Q然?span lang="EN-US">“Set Next StateMent?/span>。调试器׃会执?span lang="EN-US">B</span>?span lang="EN-US">C</span>行。只要在同一函数内,此指令就可以随意跛_或蟩后执行。灵zM用此功能可以大量节省调试旉?span lang="EN-US"> <br>  3 watch</span>H口<span lang="EN-US"> <br>  watch</span>H口支持丰富的数据格式化功能。如输入<span lang="EN-US">0x65,u</span>Q则在右栏显C?span lang="EN-US">101</span>?span lang="EN-US"> <br>  </span>实时昄<span lang="EN-US">windows API</span>调用的错误:在左栏输?span lang="EN-US">@err,hr</span>?span lang="EN-US"> <br>  </span>?span lang="EN-US">watch</span>H口中调用函数。提醒一下,调用完函数后马上?span lang="EN-US">watch</span>H口中清除它Q否则,单步调试时每一步调试器都会调用此函数?span lang="EN-US"> <br>  4 messages</span>断点不怎么实用。基本上可以用前面讲q的断点代替?span lang="EN-US"> <br></span><b>ȝ</b><span lang="EN-US"> <br>  </span>调试最重要的还是你要思考,要猜你的程序可能出错的地方Q然后运用你的调试器来证实你的猜。而熟l用上面这些技巧无疑会加快q个q程。最后,大家如果有关于调试方面的问题Q我乐意参与探讨</span><span style="line-height: 150%; font-family: 宋体; font-size: 12pt; mso-bidi-font-family: arial" lang="EN-US"><o:p></o:p></span></p><img src ="http://www.shnenglu.com/woaidongmao/aggbug/146082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/woaidongmao/" target="_blank">肥仔</a> 2011-05-10 11:01 <a href="http://www.shnenglu.com/woaidongmao/archive/2011/05/10/146082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>默认的调试器http://www.shnenglu.com/woaidongmao/archive/2010/01/25/106377.html肥仔肥仔Mon, 25 Jan 2010 04:13:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2010/01/25/106377.htmlhttp://www.shnenglu.com/woaidongmao/comments/106377.htmlhttp://www.shnenglu.com/woaidongmao/archive/2010/01/25/106377.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/106377.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/106377.html如果一个线E的异常没有被处理,?span lang=EN-US>Windows的未处理异常qo器将会被调用。这个函数根据注册表

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug

键中的内ҎҎ处理的异帔R取一U统一的行为和Ҏ?span lang=EN-US>

该键中的

Auto: 军_是自动运行调试器Q还是让用户军_

Debugger: 是指向调试器可执行文件的路径的字W串

-------------------------------------------------------------------------------------------

据观察,在我装了vs2005之后

"Auto"="1"
"Debugger"="\"C:\\WINDOWS\\system32\\vsjitdebugger.exe\" -p %ld -e %ld"

表示自动运行调试器

-------------------------------------------------------------------------------------------

?span lang=EN-US>Windows默认的调试器?span lang=EN-US>Dr.Watson

它捕获应用程序应用程序崩溃状态,q记录日志文ӞDrwtsn32.logQ和q程崩溃转储文gQ?span lang=EN-US>User.dmpQ?span lang=EN-US>

要想查看q|?span lang=EN-US>Dr.WatsonQ可以在q行中输?span lang=EN-US>Drwtsn32.exe?span lang=EN-US>

要想恢复pȝ初始状态则可以q行 Drwtsn32 -i

q样注册表的那两个g变成

"Auto"="1"
"Debugger"="drwtsn32 -p %ld -e %ld -g"

-------------------------------------------------------------------------------------------

 



肥仔 2010-01-25 12:13 发表评论
]]>
Chrome的Crash Report服务http://www.shnenglu.com/woaidongmao/archive/2009/10/22/99211.html肥仔肥仔Thu, 22 Oct 2009 11:33:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99211.htmlhttp://www.shnenglu.com/woaidongmao/comments/99211.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99211.html#Feedback1http://www.shnenglu.com/woaidongmao/comments/commentRss/99211.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99211.html阅读全文

肥仔 2009-10-22 19:33 发表评论
]]>
也谈Release版本排错http://www.shnenglu.com/woaidongmao/archive/2009/10/22/99210.html肥仔肥仔Thu, 22 Oct 2009 11:28:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99210.htmlhttp://www.shnenglu.com/woaidongmao/comments/99210.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99210.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99210.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99210.html阅读全文

肥仔 2009-10-22 19:28 发表评论
]]>
MiniDump结http://www.shnenglu.com/woaidongmao/archive/2009/10/22/99201.html肥仔肥仔Thu, 22 Oct 2009 09:27:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99201.htmlhttp://www.shnenglu.com/woaidongmao/comments/99201.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99201.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99201.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99201.html1、挂异常链?span lang=EN-US>SetUnhandledExceptionFilter
2、在调试状态下无效

3、发生异常的时候ؓ了保留现场堆栈需要冻l进E内其他U程Q所使用的操作越越好?span lang=EN-US>

4、开启另外一个进E对异常q程q行MiniDump?span lang=EN-US>

5、如果要分析崩溃地址是否在某个模块,最好在分析q程里做。或者在模块加蝲时计模块区域以便在异常时快速定位。判断崩溃是否和某个模块相关Q只能通过分析堆栈里的模块来识别,使用StackWalk函数?span lang=EN-US>StackWalk函数里所使用?span lang=EN-US>context参数要用异常参数里?span lang=EN-US>ContextRecordQ这栯分析在崩溃的时候的堆栈Q而不会受后面操作的媄响?span lang=EN-US>

6、如果希望自己是W一个被调用Q可以在挂链之后?span lang=EN-US>APIHook讄SetUnhandledExceptionFilterq回I?span lang=EN-US>

7、在ȝU程的时候,不要?span lang=EN-US>MessageBoxQ会D当前U程因ؓ其他U程挂v而阻歅R?span lang=EN-US>

8、异帔R?span lang=EN-US>SetUnHandledExceptionFliter之外Q还?span lang=EN-US>AddVectoredExceptionHandlerQ相对于前者,后者的优点是能够让异常按照铑ּ触发Q不会被中间节点断开。但?span lang=EN-US>AddVectoredExceptionHandler无法?span lang=EN-US>2K下用。。?span lang=EN-US>

 



肥仔 2009-10-22 17:27 发表评论
]]>
异常处理与MiniDump详解(1,2,3,4)http://www.shnenglu.com/woaidongmao/archive/2009/10/22/99200.html肥仔肥仔Thu, 22 Oct 2009 09:15:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99200.htmlhttp://www.shnenglu.com/woaidongmao/comments/99200.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/22/99200.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99200.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99200.htmlhttp://blog.csdn.net/vagrxie/archive/2009/07/02/4317423.aspx



肥仔 2009-10-22 17:15 发表评论
]]>
利用VS2005q行dump文g调试http://www.shnenglu.com/woaidongmao/archive/2009/10/21/99135.html肥仔肥仔Wed, 21 Oct 2009 10:58:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99135.htmlhttp://www.shnenglu.com/woaidongmao/comments/99135.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99135.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99135.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99135.html前言Q利?/span>drwtsn32?/span>NTSDq行E序崩溃处理Q都可以生成可用于调试的dmp格式文g。?/span>VS2005打开生成?/span>DMP文gQ能很方便的扑ևBUG所在位|。本文将讨论以下内容Q?/span>

1?/span>  E序~译选项

2?/span>  利用VS2005 分析dump文g

3?/span>  常见问题讨论

一?/span>       E序~译选项

PDB files contains all debug information like type definition and function prototype. When application crashes, we need the PDB files to analyze the root cause, so make sure these PDB files will be created when building it. You must do the following setting:

C/C++\General\Debug Information Format=Program Database (/Zi).

clip_image001

?/span>1.1 调试信息格式

Linker\Debugging\Generate Program Database File=”Name and location of your PDB files”

clip_image002

?/span>1.2 PDB文g输出路径

PDB文g路径最好设|在同一个文件夹中,q样方便dmp文g调试时调用?/span>

调试Ӟ所有的PDB文g和源文g必须严格匚wQ?/span>the PDB files should be the one generated by build the source codeQ,q存储在一个安全的位置。当客户报告了一个错误时Q你需要这些文件来帮忙以便定位错误于源代码中ƈ解决问题?/span>

二?/span>       VS2005 分析dump文g

In this simple application, there is an unhandled Access Violation Reading exception, because GetNameFromDatabase returns a NULL pointer, and this pointer is passed into IsPrefix and then it’s used directly without NULL pointer checking.

clip_image003

?/span>1.3 演示代码

 

利用Release模式~译该测试程序,在客h上运行该E序Q将ҎNTSD讄生成相对应的DMP格式文g?/span>

可以使用Visual Studio.Net?/span>NTSD或是其他的调试工具对DMP格式文gq行分析?/span>

 

l         Start Visual Studio.Net

Click File\Open Solution and make sure the files of type is *.dmp then click Open.

clip_image004

?/span>1.3 Open Dump File (GUI)

 

l         Set Symbol Path

Click Tools\Options, Debugging\SymbolsQ增?/span>PDB文g路径。若调试的程序需要微软基库的PDB信息Q可以增加一个\径ؓQ?/span>

http://msdl.microsoft.com/download/symbols

在界面下?/span>Cache Symbol From symbol…选择本地存储q些Symbols的\径?/span>

clip_image005

?/span>1.4 Symbol Path

如果DMP文g没有攑օ本nPDB文g所在目录,也可以在此处增加一个本地目录。点OK后,VS2005从|络中下载所需要的SymbolsQ需要等待一D|间。如果是多次调试同一个程序错误所生成?/span>DMP文gQ可以在对话框中选择“Search the above locations only when symbols are loaded manually”。从而可以节省网l带宽?/span>

 

l         Set Source code path

Open Solution Property Pages and set the source code path.

clip_image006

?/span>1.5 属性菜?/span>

clip_image007

?/span>1.6 Debug Source Files

 

l         Start to Debug the Dump File

Click the Debug menu, it will ask you to save as a solution, save it. Then it will go to the line which caused the crash of your application.

clip_image008

?/span>1.7 调试H口Q定位到源代?/span>

 

三?/span>       常见问题讨论

1?/span>  Dump文g攑֜哪里Q?/span>

Dump文g不用非要攑֜你编译出来的位置Q你完全可以建立一个新的文件夹来放它。但若不是存攑֜~译出来的位|,需要将~译生成?/span>PDB文g拯?/span>Dump文g目录Q或是利?/span>VS2005打开Dump文g后,讄PDB文g路径。参照图1.4?/span>

 

2?/span>  如何恢复当时的现场?

可能你要问,怎么可能Q这?span lang=EN-US>dump文g可是用户发给我的Q我不可能去用户安调试吧?q个恢复现场可不是指的非要到那台机器上去Q而是要把产生dump文g对应的二q制文g拿到?span lang=EN-US>

但是恢复现场需要所有的二进制文仉要对应,你一定要有导致用户崩溃的那些Exe?span lang=EN-US>DLL。既然是你发布的E序Q?span lang=EN-US>Exe文g当然你会有。所以这里只考虑DLLp了?span lang=EN-US>

Dump文g中记录了所?span lang=EN-US>DLL文g的版本号和时间戳Q所以你一定可以同q某U途径拿到它。如果你能从用户那里拿到最好,如果不方便,用户不可能用的是我们q_不常用的操作pȝQ所以找个有对应pȝ的机器一般都会有。但是记住不仅是文g名称要一_q要核对版本和时间戳Q如果不同一h有办法用?span lang=EN-US>

如果客户用了某个Ҏ的补丁怎么办?

其实q个问题也很好解冻I只要它不ȝ阅读堆栈Q就不用它Q调?span lang=EN-US>Dump和运行程序不一P~少一两个DLL没有M问题?span lang=EN-US>

 

3?/span>  如果真的需要怎么办?

W号文g现在主要是指PDB文g?span lang=EN-US>

如果没有W号文gQ那么调试的时候可能导致堆栈错误?span lang=EN-US>

如果你丢׃q个发布版本中你~译出来的那?/span>exe?/span>DLL?/span>PDBQ那么这个损失是严重的,重新~译出来的版本是不能使用的?/span>

我自qDLL都有了,可是~的是系l的DLL的对?/span>PDB文g怎么办??/span>1.4中已l介l了Ҏ。微软在它的W号数据库上为我们提供了所有的PDB文gQ还有部分非关键DLL。设|好后程序将自动下蝲需要的PDB?/span>DLL文g?/span>

 

4?/span>  拿到需要的文g了,q些文g应该攑֜哪里Q?/span>

W号数据库中的文件不用动Q把其它?/span>exe?/span>DLL?/span>PDB文g攑֜dump文g目录里就行了?/span>

 

5?/span>  我用的是VS2005Q明明有源代码,Z么显CZ了?

q个?/span>dump调试的最头痛问题Q代码可能已l改q了Q即使你?/span>SVN拿到当时的版本,旉戳也是错的,VS2005是不让你显CZ码。其实只要在

Tools\OptionsQ?/span>Debugging\General中去?/span>

Require source files to exactly match the original version的复选就行了?/span>

 



肥仔 2009-10-21 18:58 发表评论
]]>
NTSD(Command Line)调试DMP格式文ghttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99134.html肥仔肥仔Wed, 21 Oct 2009 10:56:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99134.htmlhttp://www.shnenglu.com/woaidongmao/comments/99134.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99134.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99134.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99134.html 

前言Q之前介l了利用VS2005q行Dump文g的调试,功能非常强大。但VS2005是一个大E序Q本文将讨论利用NTSD?span lang=EN-US>Command Line 实现Dump 文g的调试?span lang=EN-US>

1?/span>  载入DMP格式文g

利用CMD打开命o行窗口,切换?span lang=EN-US>NTSD所在目录。利用命令蝲?span lang=EN-US>DMP文gQ?span lang=EN-US>

ntsd –z dumpfileName –y symbolPath –srcpath sourcecodePath

dumpfileNameQ?span lang=EN-US>DMP格式文g路径

symbolPathQ?span lang=EN-US>PDB文g路径

sourcecodePathQ程序的源代码\?span lang=EN-US>

如图1.1Q若载入成功Q将弹出一?span lang=EN-US>NTSDH口Q如?span lang=EN-US>1.2?span lang=EN-US>

clip_image001

?span lang=EN-US>1.1 载入DMP格式文g

clip_image002

?span lang=EN-US>1.2 NTSD界面

U色的圈中显CZBUG的原因,函数IsPrefix 存在错误?/span>0x36是错误相对于函数的偏Ud{这个错误是一?span lang=EN-GB>Access Violation的异常,异常地址?span lang=EN-GB>00401036?/span>

NoteQ?/span>

l  若\径中存在I格Q需要用在\径前后加上引受?/span>

l  若提C错误,Ҏ提示查看是否׃dbghelp.dll不存在导_安装的调试工具包中存在该动态库?/span>

2?/span>  定位与源代码

利用如下命o可以定位错误到源代码中:

lsp  –a 500

lsa  .

W一行命令用于设|显C的源代码行敎ͼW二行命令将错误定位与错误行。如图:

clip_image003

?span lang=EN-US>1.3 Analysis Result: Line of Source Code Causing Crash

从图中可以看出,W?span lang=EN-US>13hDE序错误的位|。如果希望看到变量的|使用命oQ?span lang=EN-US>

x

若需要详l查看某个变量的|使用命oQ?span lang=EN-US>

??  variableName

clip_image004

?/span>1.4 Analysis Result: Value of Variable Causing Crash

 

Module Address of Your Application(昄E序模块地址)

Command:

x *!

clip_image005

?span lang=EN-GB>1.5 Application Module Information

It shows all the module address in your application.

 

Crash Stack TraceQ显C程序调用堆栈)

If you want to trace the stack of application, use this command:

Command:

kb

clip_image006

?span lang=EN-GB>1.6 Application Stack Trace

It shows that function main invokes function IsPrefix then application crashes.

For more commands of NTSD, refer to debugger.chm in Microsoft Debugger Tools package.

 



肥仔 2009-10-21 18:56 发表评论
]]>
WinDbg调试DMP格式文ghttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99133.html肥仔肥仔Wed, 21 Oct 2009 10:53:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99133.htmlhttp://www.shnenglu.com/woaidongmao/comments/99133.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99133.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99133.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99133.html前言Q?span lang=EN-US>WinDbg是微软开发的免费源代码的调试工兗?span lang=EN-US>WinDbg可以用于Kernel模式调试和用h式调试,q可以调?span lang=EN-US>Dump文g。本文的讨论是在安装?span lang=EN-US>Debugging Tools for Windows 的前提下q行的,下蝲地址可以参考我之前的文章?span lang=EN-US>WinDbg对于dump文g的调试可以通过菜单讄Symbol File Path?span lang=EN-US>Source File Path Qƈ可设|多个\径?span lang=EN-US>

1?/span>  打开Dump格式文g

打开WinDbgQ通过菜单[File] à [Open Crash dump] 选择dump文g打开Q也可通过CMD打开Dos命oH口Q切换到WinDbg所在目录,利用命oQ?span lang=EN-US>

WinDbg –z “D:\Lines2009-7-25-22-20-33-900.dmp”

-z表示路径

clip_image001

 

?span lang=EN-US>1.1 利用WinDbg打开dump文g

载入dump文g昄如图Q?span lang=EN-US>

clip_image002

 

?span lang=EN-US>1.2 WinDbg界面

2?/span>  分析dump文g

若生成的dump文g在本机,dump文g中将包含调试需要的PDB文g及源代码路径Q若不在本机Q可以通过WinDbg菜单[File] à [Symbol File path] ?[Source File Path] 分别讄PDB文g路径和源代码路径。如果程序涉及到DLLQ需要将EXE?span lang=EN-US>DLL所有涉及的PDB、源代码路径都包括。用命令:

!analyze –v

分?span lang=EN-US>dump文gQƈ昄E序崩溃处于的代码行Q?span lang=EN-US>

clip_image003

 

?span lang=EN-US>1.3 分析dump 文g

 



肥仔 2009-10-21 18:53 发表评论
]]>
E序自动生成Dump文ghttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99132.html肥仔肥仔Wed, 21 Oct 2009 10:52:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99132.htmlhttp://www.shnenglu.com/woaidongmao/comments/99132.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99132.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99132.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99132.html阅读全文

肥仔 2009-10-21 18:52 发表评论
]]>
自己创徏 minidumphttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99130.html肥仔肥仔Wed, 21 Oct 2009 10:50:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99130.htmlhttp://www.shnenglu.com/woaidongmao/comments/99130.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99130.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99130.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99130.html以前曑ֆq一?span lang=EN-US> bugslayer.dll 的介l?span lang=EN-US>. 在程序出错时调用栈写到文g. 觉得不错. 后来开始用 windbg. 知道?span lang=EN-US> userdump. 知道了如何调?span lang=EN-US> dump... 才知道程序崩溃的时候写 dump 文g其实可以获取比调用栈多得多的信息

如果你的E序什么都不干. 那么在程序出错的时?span lang=EN-US>. drwtsn32.exe 会写一?span lang=EN-US> userdump. ?span lang=EN-US> drwtsn32 有些~点. 比如只能写一?span lang=EN-US> dump 文g. 后面的崩溃写 dump 文g时会覆盖前面?span lang=EN-US>. win2000 下的 drwtsn32 只能写旧式的 dump 文g(往往寸比较?span lang=EN-US>). 有一文章论q的比较清楚:
 http://www.debuginfo.com/articles/ntsdwatson.html

使用 ntsd 代替 drwtsn32. ?span lang=EN-US> ntsd 的缺点就是需要安装最新的 windbg. q是一个硬?span lang=EN-US>. 在看?span lang=EN-US> debuginfo.com 的另一文?span lang=EN-US>:
 http://www.debuginfo.com/articles/effminidumps.html
 
之后, 我选择的是在程序出错的时候调?span lang=EN-US> api 自己?span lang=EN-US> minidump. 克服?span lang=EN-US> drwtsn32, ntsd 的缺?span lang=EN-US>.
封装好的函数放C一个头文g?span lang=EN-US>, 包含卛_. 使用的方法很?span lang=EN-US>:

#include <windows.h>
#include "minidump.h"
LONG __stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
CreateMiniDump(pExceptionInfo, "c:\\user.dmp");
return EXCEPTION_EXECUTE_HANDLER;
}

void main()
{
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
*(int*)0=0; // AV
}

q样好?span lang=EN-US>. 注意安装臛_ xp 以上?span lang=EN-US> sdk.
q里用到了一?span lang=EN-US> api SetUnhandledExceptionFilter(), 如果不明白可以搜一?span lang=EN-US> msdn.
q行例子E序出错退Z?span lang=EN-US>, 得C c:\\user.dmp. 可以?span lang=EN-US> windbg {调试器来分析了

代码从这里下?http://nicoster.googlepages.com/minidump.rar

 



肥仔 2009-10-21 18:50 发表评论
]]>
VS2005中SetUnhandledExceptionFilter函数应用http://www.shnenglu.com/woaidongmao/archive/2009/10/21/99129.html肥仔肥仔Wed, 21 Oct 2009 10:47:00 GMThttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99129.htmlhttp://www.shnenglu.com/woaidongmao/comments/99129.htmlhttp://www.shnenglu.com/woaidongmao/archive/2009/10/21/99129.html#Feedback0http://www.shnenglu.com/woaidongmao/comments/commentRss/99129.htmlhttp://www.shnenglu.com/woaidongmao/services/trackbacks/99129.html很多软g通过讄自己的异常捕获函敎ͼ捕获未处理的异常Q生成报告或者日志(例如生成mini-dump文gQ,辑ֈRelease版本下追t?span lang=EN-US>Bug的目的。但是,CVS2005Q即VC8Q,Microsoft?span lang=EN-US>CRTQ?span lang=EN-US>Cq行时库Q的一些与安全相关的代码做了些改动Q典型的Q例如增加了对缓冲溢出的查。新CRT版本在出现错误时强制把异常抛l默认的调试器(如果没有配置的话Q默认是Dr.WatsonQ,而不再通知应用E序讄的异常捕获函敎ͼq种行ؓ主要在以下三U情况出现?span lang=EN-US>

Q?span lang=EN-US>1Q?/span>       调用abort函数Qƈ且设|了_CALL_REPORTFAULT选项Q这个选项?span lang=EN-US>Release版本是默认设|的Q?span lang=EN-US>

Q?span lang=EN-US>2Q?/span>       启用了运行时安全查选项Qƈ且在软gq行时检查出安全性错误,例如出现~存溢出。(安全查选项 /GS 默认也是打开的)

Q?span lang=EN-US>3Q?/span>       遇到_invalid_parameter错误Q而应用程序又没有d调用

_set_invalid_parameter_handler讄错误捕获函数?span lang=EN-US>

所以结论是Q?span lang=EN-US>VS2005Q?span lang=EN-US>VC8Q编译的E序Q许多错误都不能?span lang=EN-US>SetUnhandledExceptionFilter捕获到。这?span lang=EN-US>CRT相对于前面版本的一个比较大的改变,但是很遗憾,Microsoft却没有在相应的文档明指出?span lang=EN-US>

解决Ҏ

       之所以应用程序捕获不到那些异常,原因是因为新版本?span lang=EN-US>CRT实现在异常处理中强制删除所有应用程序先前设|的捕获函数Q如下所C:

 /* Make sure any filter already in place is deleted. */

 SetUnhandledExceptionFilter(NULL);

 UnhandledExceptionFilter(&ExceptionPointers);

解决Ҏ是拦?span lang=EN-US>CRT调用SetUnhandledExceptionFilter函数Q之无效。在X86q_下,可以使用以下代码?span lang=EN-US>

#ifndef _M_IX86

       #error "The following code only works for x86!"

#endif

 

void DisableSetUnhandledExceptionFilter()

{

    void *addr = (void*)GetProcAddress(LoadLibrary(_T("kernel32.dll")),

                                                         "SetUnhandledExceptionFilter");

    if (addr)

    {

              unsigned char code[16];

              int size = 0;

              code[size++] = 0x33;

              code[size++] = 0xC0;

              code[size++] = 0xC2;

              code[size++] = 0x04;

              code[size++] = 0x00;

 

               DWORD dwOldFlag, dwTempFlag;

              VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);

              WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);

              VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);

       }

}

在设|自q异常处理函数后,调用DisableSetUnhandledExceptionFilterCRT讄卛_?span lang=EN-US>

其它讨论

       上面通过讄api hookQ解决了?span lang=EN-US>VS2005上的异常捕获问题Q这U虽然不是那?#8220;q净”的解x案,是目前唯一单有效的方式?span lang=EN-US>

       虽然也可以通过_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT), signal(SIGABRT, ...), ?span lang=EN-US>_set_invalid_parameter_handler(...) 解决Q?span lang=EN-US>1Q(3Q,但是对于Q?span lang=EN-US>2Q,讄api hook是唯一的方式?span lang=EN-US>

 



肥仔 2009-10-21 18:47 发表评论
]]>
޾Ʒھþ| þþƷһ| ŷѹۿþ| þһ| VVþþ| ٸƷþ| þùƷӰԺ| þþþAV| Ұ¾þһ| þó˹Ʒ| ͵ٸþþþþþþ| þۺĻ| þˬˬƬAV| þþƷ91þۺ鶹 | þһ99| ĻȾþþþþþ| þ99Ʒþþþþ벥| ŷۺϾþþ| Ʒþþþþ| þ99ֻƵƷ8| ˾Ʒþþþ7777| Ůþþþþjþ| þۺϾƷ| ٸþĻ| þþƷһ| ˾þĻ| ޹˾ƷŮ˾þþ| þþƷ91þ鶹| ھƷžžþþƷ| þһ| Ʒþþþþù| Ʒһþ㽶߿| þþƷAVӰ| Ʒ99þþþþլС˵| þĻƷһ| ˾Ʒþһav | ƷۺϾþ| þ99Ʒ| þŷƷ| ɫۺϾþþþۺһ | ɫվWWWþþž|