Skip to content

Commit fe1d15e

Browse files
committedAug 20, 2024
crash: add crash reporter
1 parent 5040f37 commit fe1d15e

23 files changed

+1146
-343
lines changed
 

Diff for: ‎.github/ISSUE_TEMPLATE/config.yml

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
blank_issues_enabled: true

Diff for: ‎.github/ISSUE_TEMPLATE/crash.yml

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: Crash Report
2+
description: Quickshell has crashed
3+
labels: ["bug", "crash"]
4+
body:
5+
- type: textarea
6+
id: crashinfo
7+
attributes:
8+
label: General crash information
9+
description: |
10+
Paste the contents of the `info.txt` file in your crash folder here.
11+
value: "<details> <summary>General information</summary>
12+
13+
14+
```
15+
16+
<Paste the contents of the file here inside of the triple backticks>
17+
18+
```
19+
20+
21+
</details>"
22+
validations:
23+
required: true
24+
- type: textarea
25+
id: userinfo
26+
attributes:
27+
label: What caused the crash
28+
description: |
29+
Any information likely to help debug the crash. What were you doing when the crash occurred,
30+
what changes did you make, can you get it to happen again?
31+
- type: textarea
32+
id: dump
33+
attributes:
34+
label: Minidump
35+
description: |
36+
Attach `minidump.dmp` here. If it is too big to upload, compress it.
37+
38+
You may skip this step if quickshell crashed while processing a password
39+
or other sensitive information. If you skipped it write why instead.
40+
validations:
41+
required: true
42+
- type: textarea
43+
id: logs
44+
attributes:
45+
label: Log file
46+
description: |
47+
Attach `log.qslog` here. If it is too big to upload, compress it.
48+
49+
You can preview the log if you'd like using `quickshell read-log <path-to-log>`.
50+
validations:
51+
required: true
52+
- type: textarea
53+
id: config
54+
attributes:
55+
label: Configuration
56+
description: |
57+
Attach your configuration here, preferrably in full (not just one file).
58+
Compress it into a zip, tar, etc.
59+
60+
This will help us reproduce the crash ourselves.
61+
- type: textarea
62+
id: bt
63+
attributes:
64+
label: Backtrace
65+
description: |
66+
If you have gdb installed and use systemd, or otherwise know how to get a backtrace,
67+
we would appreciate one. (You may have gdb installed without knowing it)
68+
69+
1. Run `coredumpctl debug <pid>` where `pid` is the number shown after "Crashed process ID"
70+
in the crash reporter.
71+
2. Once it loads, type `bt -full` (then enter)
72+
3. Copy the output and attach it as a file or in a spoiler.

Diff for: ‎CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ option(BUILD_TESTING "Build tests" OFF)
99
option(ASAN "Enable ASAN" OFF) # note: better output with gcc than clang
1010
option(FRAME_POINTERS "Always keep frame pointers" ${ASAN})
1111

12+
option(CRASH_REPORTER "Enable the crash reporter" ON)
1213
option(USE_JEMALLOC "Use jemalloc over the system malloc implementation" ON)
1314
option(SOCKETS "Enable unix socket support" ON)
1415
option(WAYLAND "Enable wayland support" ON)
@@ -29,6 +30,7 @@ option(SERVICE_UPOWER "UPower service" ON)
2930
option(SERVICE_NOTIFICATIONS "Notification server" ON)
3031

3132
message(STATUS "Quickshell configuration")
33+
message(STATUS " Crash reporter: ${CRASH_REPORTER}")
3234
message(STATUS " Jemalloc: ${USE_JEMALLOC}")
3335
message(STATUS " Build tests: ${BUILD_TESTING}")
3436
message(STATUS " Sockets: ${SOCKETS}")

Diff for: ‎default.nix

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
ninja,
1010
qt6,
1111
cli11,
12+
breakpad,
1213
jemalloc,
1314
wayland,
1415
wayland-protocols,
@@ -28,6 +29,7 @@
2829
else "unknown"),
2930

3031
debug ? false,
32+
withCrashReporter ? true,
3133
withJemalloc ? true, # masks heap fragmentation
3234
withQtSvg ? true,
3335
withWayland ? true,
@@ -55,6 +57,7 @@
5557
qt6.qtdeclarative
5658
cli11
5759
]
60+
++ (lib.optional withCrashReporter breakpad)
5861
++ (lib.optional withJemalloc jemalloc)
5962
++ (lib.optional withQtSvg qt6.qtsvg)
6063
++ (lib.optionals withWayland [ qt6.qtwayland wayland ])
@@ -67,6 +70,7 @@
6770
cmakeBuildType = if debug then "Debug" else "RelWithDebInfo";
6871

6972
cmakeFlags = [ "-DGIT_REVISION=${gitRev}" ]
73+
++ lib.optional (!withCrashReporter) "-DCRASH_REPORTER=OFF"
7074
++ lib.optional (!withJemalloc) "-DUSE_JEMALLOC=OFF"
7175
++ lib.optional (!withWayland) "-DWAYLAND=OFF"
7276
++ lib.optional (!withPipewire) "-DSERVICE_PIPEWIRE=OFF"

Diff for: ‎src/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ install(TARGETS quickshell RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
55
add_subdirectory(core)
66
add_subdirectory(io)
77

8+
if (CRASH_REPORTER)
9+
add_subdirectory(crash)
10+
endif()
11+
812
if (DBUS)
913
add_subdirectory(dbus)
1014
endif()

Diff for: ‎src/core/CMakeLists.txt

+11-1
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,19 @@ qt_add_library(quickshell-core STATIC
4141
clock.cpp
4242
logging.cpp
4343
paths.cpp
44+
crashinfo.cpp
45+
common.cpp
4446
)
4547

46-
set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}")
48+
if (CRASH_REPORTER)
49+
set(CRASH_REPORTER_DEF 1)
50+
endif()
51+
52+
add_library(quickshell-build INTERFACE)
53+
configure_file(build.hpp.in build.hpp)
54+
target_include_directories(quickshell-build INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
55+
target_link_libraries(quickshell-core PRIVATE quickshell-build)
56+
4757
qt_add_qml_module(quickshell-core URI Quickshell VERSION 0.1)
4858

4959
target_link_libraries(quickshell-core PRIVATE ${QT_DEPS} Qt6::QuickPrivate CLI11::CLI11)

Diff for: ‎src/core/build.hpp.in

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#pragma once
2+
3+
// NOLINTBEGIN
4+
#define GIT_REVISION "@GIT_REVISION@"
5+
#define CRASH_REPORTER @CRASH_REPORTER_DEF@
6+
// NOLINTEND

Diff for: ‎src/core/common.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "common.hpp"
2+
3+
#include <qdatetime.h>
4+
5+
namespace qs {
6+
7+
const QDateTime Common::LAUNCH_TIME = QDateTime::currentDateTime();
8+
9+
}

Diff for: ‎src/core/common.hpp

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
#include <qdatetime.h>
4+
5+
namespace qs {
6+
7+
struct Common {
8+
static const QDateTime LAUNCH_TIME;
9+
};
10+
11+
} // namespace qs

Diff for: ‎src/core/crashinfo.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include "crashinfo.hpp"
2+
3+
#include <qdatastream.h>
4+
5+
QDataStream& operator<<(QDataStream& stream, const InstanceInfo& info) {
6+
stream << info.configPath << info.shellId << info.launchTime << info.noColor;
7+
return stream;
8+
}
9+
10+
QDataStream& operator>>(QDataStream& stream, InstanceInfo& info) {
11+
stream >> info.configPath >> info.shellId >> info.launchTime >> info.noColor;
12+
return stream;
13+
}
14+
15+
namespace qs::crash {
16+
17+
CrashInfo CrashInfo::INSTANCE = {}; // NOLINT
18+
19+
}

Diff for: ‎src/core/crashinfo.hpp

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <qdatetime.h>
4+
#include <qstring.h>
5+
6+
struct InstanceInfo {
7+
QString configPath;
8+
QString shellId;
9+
QString initialWorkdir;
10+
QDateTime launchTime;
11+
bool noColor = false;
12+
bool sparseLogsOnly = false;
13+
};
14+
15+
QDataStream& operator<<(QDataStream& stream, const InstanceInfo& info);
16+
QDataStream& operator>>(QDataStream& stream, InstanceInfo& info);
17+
18+
namespace qs::crash {
19+
20+
struct CrashInfo {
21+
int logFd = -1;
22+
23+
static CrashInfo INSTANCE; // NOLINT
24+
};
25+
26+
} // namespace qs::crash

Diff for: ‎src/core/logging.cpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <sys/mman.h>
2525
#include <sys/sendfile.h>
2626

27+
#include "crashinfo.hpp"
2728
#include "logging_p.hpp"
2829
#include "logging_qtprivate.cpp" // NOLINT
2930
#include "paths.hpp"
@@ -198,14 +199,16 @@ void ThreadLogging::init() {
198199

199200
if (logMfd != -1) {
200201
this->file = new QFile();
201-
this->file->open(logMfd, QFile::WriteOnly, QFile::AutoCloseHandle);
202+
this->file->open(logMfd, QFile::ReadWrite, QFile::AutoCloseHandle);
202203
this->fileStream.setDevice(this->file);
203204
}
204205

205206
if (dlogMfd != -1) {
207+
crash::CrashInfo::INSTANCE.logFd = dlogMfd;
208+
206209
this->detailedFile = new QFile();
207210
// buffered by WriteBuffer
208-
this->detailedFile->open(dlogMfd, QFile::WriteOnly | QFile::Unbuffered, QFile::AutoCloseHandle);
211+
this->detailedFile->open(dlogMfd, QFile::ReadWrite | QFile::Unbuffered, QFile::AutoCloseHandle);
209212
this->detailedWriter.setDevice(this->detailedFile);
210213

211214
if (!this->detailedWriter.writeHeader()) {
@@ -245,7 +248,7 @@ void ThreadLogging::initFs() {
245248
auto* file = new QFile(path);
246249
auto* detailedFile = new QFile(detailedPath);
247250

248-
if (!file->open(QFile::WriteOnly | QFile::Truncate)) {
251+
if (!file->open(QFile::ReadWrite | QFile::Truncate)) {
249252
qCCritical(logLogging
250253
) << "Could not start filesystem logger as the log file could not be created:"
251254
<< path;
@@ -256,7 +259,7 @@ void ThreadLogging::initFs() {
256259
}
257260

258261
// buffered by WriteBuffer
259-
if (!detailedFile->open(QFile::WriteOnly | QFile::Truncate | QFile::Unbuffered)) {
262+
if (!detailedFile->open(QFile::ReadWrite | QFile::Truncate | QFile::Unbuffered)) {
260263
qCCritical(logLogging
261264
) << "Could not start detailed filesystem logger as the log file could not be created:"
262265
<< detailedPath;
@@ -287,6 +290,8 @@ void ThreadLogging::initFs() {
287290
sendfile(detailedFile->handle(), oldFile->handle(), nullptr, oldFile->size());
288291
}
289292

293+
crash::CrashInfo::INSTANCE.logFd = detailedFile->handle();
294+
290295
this->detailedFile = detailedFile;
291296
this->detailedWriter.setDevice(detailedFile);
292297

0 commit comments

Comments
 (0)
Please sign in to comment.