开发环境:MacOS: 10.13.6 Qt: Qt5.9.7 for Mac
要在MacOS平台下分析QT5的崩溃文件,必须依赖* .dSYM符号文件,而在MacOS平台下生成dSYM文件,之前一直在网上查找都没有找到,不得不说QT for Mac的资料比较其他资料少很多,可能是用的人少吧。
OK, 言归正传,首先第一步生成.dSYM符号文件,使用以下命令
dsymutil ./dSYMDemo.app/Contents/MacOS/dSYMDemo -o dSYMDemo.app.dSYM
macdeployqt dSYMDemo.app -verbose=1
在项目构建中设置。
设置成功后,编译生成dSYMDemo.app
代码如下
1.工程文件
#-------------------------------------------------
#
# Project created by QtCreator 2018-12-23T22:35:36
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = dSYMDemo
TEMPLATE = app
QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
#QMAKE_OBJECTIVE_CFLAGS_RELEASE = $$QMAKE_OBJECTIVE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
这三句必须加上,否则生成的dSYM文件没有用。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void InitView();
void InitConnect();
public slots:
void SlotCreateCrashFile();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPushButton>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
InitView();
InitConnect();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::InitView()
{
}
void MainWindow::InitConnect()
{
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(SlotCreateCrashFile()));
}
void MainWindow::SlotCreateCrashFile()
{
QPushButton *button = new QPushButton(this);
delete button;
qDebug() << "SlotCreateCrashFile=====================";
button->setText("Hello World");
}
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
第二步,运行 dSYMDemo.app,点击按钮,产生崩溃文件,内容如下(省略其它信息):
Process: dSYMDemo [1809]
Path: /Users/USER/*/dSYMDemo.app/Contents/MacOS/dSYMDemo
Identifier: yijun.dSYMDemo
Version: 0
Code Type: X86-64 (Native)
Parent Process: Qt Creator [694]
Responsible: dSYMDemo [1809]
User ID: 501
Date/Time: 2018-12-23 23:24:38.361 +0800
OS Version: Mac OS X 10.13.6 (17G65)
Report Version: 12
Anonymous UUID: 11AC0249-B983-6718-D60C-153EF7C39E46
Sleep/Wake UUID: 08CAAC92-0E1F-496E-A3E9-C2122F8721F3
Time Awake Since Boot: 5700 seconds
System Integrity Protection: enabled
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 org.qt-project.QtCore 0x000000010c40d070 operator==(QString const&, QString const&) + 0
1 org.qt-project.QtWidgets 0x000000010b9c7f99 QAbstractButton::setText(QString const&) + 41
2 yijun.dSYMDemo 0x000000010b8b2621 MainWindow::SlotCreateCrashFile() + 161 (mainwindow.cpp:35)
3 org.qt-project.QtCore 0x000000010c586e7a QMetaObject::activate(QObject*, int, int, void**) + 2954
4 org.qt-project.QtWidgets 0x000000010b9c795f QAbstractButtonPrivate::emitClicked() + 111
5 org.qt-project.QtWidgets 0x000000010b9c77f2 QAbstractButtonPrivate::click() + 226
6 org.qt-project.QtWidgets 0x000000010b9c8a5f QAbstractButton::mouseReleaseEvent(QMouseEvent*) + 271
7 org.qt-project.QtWidgets 0x000000010b907fd0 QWidget::event(QEvent*) + 496
8 org.qt-project.QtWidgets 0x000000010b9c85c1 QAbstractButton::event(QEvent*) + 145
9 org.qt-project.QtWidgets 0x000000010b8cdeb2 QApplicationPrivate::notify_helper(QObject*, QEvent*) + 306
10 org.qt-project.QtWidgets 0x000000010b8d0c4d QApplication::notify(QObject*, QEvent*) + 7165
11 org.qt-project.QtCore 0x000000010c55624f QCoreApplication::notifyInternal2(QObject*, QEvent*) + 159
。。。。。。。。。。。。。。。。。。。
Logical CPU: 0
Error Code: 0x00000000
Trap Number: 13
Binary Images:
0x10b8af000 - 0x10b8b2fff +yijun.dSYMDemo (0) <2827EE1D-4B6D-3BC1-A19F-528C0414F407> /Users/USER/*/dSYMDemo.app/Contents/MacOS/dSYMDemo
0x10b8bc000 - 0x10bd0cff7 +org.qt-project.QtWidgets (5.9 - 5.9.7) <912EDEB2-1A36-3E12-B127-D4509B85BD49> /Users/USER/*/QtWidgets.framework/Versions/5/QtWidgets
0x10be69000 - 0x10c270feb +org.qt-project.QtGui (5.9 - 5.9.7) <6106A820-329B-32BE-8F91-D398C4EEFEE3>
。。。。。。。。。。。。。。
第三步:使用 atos命令进行分析,格式如下:
xcrun atos -o appName.app.dSYM/Contents/Resources/DWARF/appName -l 加载地址 崩溃地址 -arch CPU架构
0x10b8af000 是程序的加载地址 0x000000010b8b2621是程序的崩溃地址 X86-64是CPU架构
bogon:build-dSYMDemo-Desktop_Qt_5_9_7_clang_64bit-Release chenyijun$ xcrun atos -o dSYMDemo.app.dSYM/Contents/Resources/DWARF/dSYMDemo -l 0x10b8af000 0x000000010b8b2621 -arch x86_64
输出结果:
MainWindow::SlotCreateCrashFile() (in dSYMDemo) (mainwindow.cpp:35)
分析显示在mainwindow.cpp的第35行崩溃了,回到源代码验证
button->setText("Hello World");
这句崩溃了,说明分析OK