1. 前言
在写程序的过程中,不可避免出现各种Bug,如何快速的定位到Bug的位置,是程序员必备的技能之一。
2. 几种方法
2.1. 逻辑分析
根据程序所出的问题,分析问题可能所在的几个位置,通过逻辑分析找出Bug,并解决Bug。很多Bug都是粗心所致,一般都能通过逻辑分析找出。
2.2. VS调试
我属于毕业后一直用Qt进行开发,所以比较习惯用Qt Creator进行编写代码,但是它调试确实不好用,很多时候在Qt Creator环境下崩了根本找不到位置,根本没有有用的提示,这时候我就会配置一下VS的环境,在VS上进行调试,一般死在那个位置,或者缺少哪个库都能看到,VS调试真实yyds。
2.3. WinDbg(dump文件)
还有一种情况:程序不在自己手中,比如在测试或者用户手中,突然出问题了,除了根据问题逻辑分析外,还可以在开发时,程序上加上保存dump文件的代码,出问题时可用工具WinDbg打开查看Bug位置。
以下介绍用法:
2.3.1 下载 WinDbg Preview
WinDbg Preview是 WinDbg 的新版本,具有更现代的视觉效果、更快的窗口和成熟的脚本体验,下面是下载地址,傻瓜式安装就可以了。
Download Debugging Tools for Windows - WinDbg - Windows drivers | Microsoft Learn
2.3.2. 添加保存Dump文件的代码
先在pro文件里包含
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE += $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
LIBS += -lDbgHelp
然后在main.cpp文件中添加
long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp)
{
QString appName = QCoreApplication::applicationDirPath();
appName.append("/dmpDir");
QDir dir(appName);
if(!dir.exists()){
dir.mkpath(appName);
}
appName.append("/")
.append(QCoreApplication::applicationName())
.append(".")
.append(QString::number(QDateTime::currentMSecsSinceEpoch()))
.append("_CRASH_DUMP.DMP");
//create Dump file
HANDLE hDumpFile = ::CreateFile(
(LPCWSTR)appName.utf16(),
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hDumpFile != INVALID_HANDLE_VALUE)
{
//Dump info
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ExceptionPointers = pexcp;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ClientPointers = TRUE;
//write Dump
::MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hDumpFile,
MiniDumpNormal,
&dumpInfo,
NULL,
NULL
);
}
return 0;
}
int main(int argc, char *argv[])
{
::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback);
QApplication a(argc, argv);
...
return a.exec();
}
2.3.3. 出错分析
出错后就会在对应目录下生成dump文件
(1)若是安装了WinDbg Preview,双击dump文件,WinDbg Preview就会打开。
(2)配置路径:可在工具栏点击设置(Settings)或者在点击文件下的设置(Settings)
(图1),然后如图2所示配置路径。
(3)点击 !analyze -v 进行分析,如图3。
(4)分析结束后即可看到结果,如图4。
图1
图2
图3
图4
3. 结束语
目前我掌握的就这几种方式,根据不同的场合运用不同的方式定位Bug!