记一次QT程序Debug的过程(WinDbg的使用)

环境

WinDbg preview,Debugger client version: 1.2210.3001.0,Debugger engine version: 10.0.25200.1003

下载路径:https://learn.microsoft.com/zh-cn/windows-hardware/drivers/debugger/debugger-download-tools

QtCreator 7.0.2,Qt 6.2.3,MSVC 2019 64位

现象

程序异常退出,没有提示原因

找原因

1. debug方式qt打包exe

步骤见:https://blog.woyou.cool/post/4225

2. 使用WinDbg打开exe

3. 设置debug环境

pdb文件干啥的?

如果用debug模式打的包会在exe同级目录下生成一个pdb文件,该文件保存了一些debug需要的符号信息,如果没有该文件的话报错提示就会很隐晦

为啥需要设置源文件?

为了报错后能定位到报错位置,你本身已经打包成exe了,不包含源码了

也可以使用命令设置它们

# 设置源码位置
.srcpath [your source code location]

4. 启动程序

5. 程序崩溃时就会有堆栈信息

6. 查看详细异常信息

输入命令

!analyze -v

然后就能看到如下信息

由上述信息就可知出现空指针的位置

问题

源码显示不对应

见下图,一开始我很奇怪为什么我源码都注释掉了它还是提示这个地方有问题,更奇怪的是它竟然还有注释掉的局部变量信息

这其实就是上面第3步中源码和pdb文件位置设置的不对导致的,或者你在开始debug后修改了源码(这里显示的源码是和文件中的修改实时同步)

debug release版本

在 pro 文件中加入以下两行代码

# 生成pdb文件
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO

没有 QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO 无法生成 pdb 文件

没有 QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO

qt中异步通信

qt中可以使用信号槽的方式进行异步通信,也可以使用 invokeMethod 方式

// 子线程下写
QMetaObject::invokeMethod(qApp, [&]() {
        // 这个lambda表达式的代码将在主线程下执行
        ...
});

//捕获模式可以是(关于这里面的问题,详见下面参考中的 “c++的lambda使用注意事项”):
// [&]    捕获全部引用
// [=]    捕获全部值
// [a,&b]    捕获部分值和部分引用
// [x=x]    广义lambda捕获

参考

WinDbg 入门(用户模式)

!analyze命令简介

Qt5多线程/线程池技术集锦(2)如何在子线程更新ui窗口

c++的lambda使用注意事项,可能导致的崩溃问题分析

c++ lambda

后记

当然,上述的那个空指针问题是我自己模拟的。我自己遇到了一个多线程下的野指针问题,有些麻烦,它会在运行过程中随机时间崩溃,我整了老久老久。后面发现可能是子线程将引用传入到主线程后销毁内存导致的

开始没用windbg的时候我很绝望,为啥程序崩溃了却没有任何信息打印处理(见开头,只提示软件crashed),我自己不熟悉这个肯定也是一个原因,但这种提示真不友好,至少对一个java程序员不友好

再一个就是查看源码的问题了,很多时候我想看看某个方法的源码,直接使用ide跳转功能只会直接跳转到方法声明的地方,比如对c++就只跳到头文件位置,python如果没有源码就可能跳到pyi文件的位置,这种跳转方式总是能让我有种崩溃的感觉

java大法好

Leave a Comment