├── logo.png ├── src ├── bugzillaintegration │ └── libbugzilla │ │ ├── autotests │ │ ├── data │ │ │ ├── bugs.new.json │ │ │ ├── attachment.new.json │ │ │ ├── bugzilla.version.json │ │ │ ├── bugzilla.login.json │ │ │ ├── hi.http │ │ │ ├── put.http │ │ │ ├── error.nobug.invalid.json │ │ │ ├── bugs.update.json │ │ │ ├── error.http │ │ │ ├── field.rep_platform.json │ │ │ ├── comments.json │ │ │ └── bugs.unresolved.json │ │ ├── CMakeLists.txt │ │ └── jobdouble.h │ │ ├── models │ │ ├── logindetails.cpp │ │ ├── logindetails.h │ │ ├── comment.cpp │ │ ├── comment.h │ │ └── bugfield.cpp │ │ ├── clients │ │ ├── commands │ │ │ ├── bugupdate.cpp │ │ │ ├── jsoncommand.h │ │ │ ├── querycommand.h │ │ │ ├── newattachment.cpp │ │ │ ├── bugupdate.h │ │ │ ├── newbug.cpp │ │ │ ├── bugsearch.cpp │ │ │ ├── bugsearch.h │ │ │ ├── commandbase.h │ │ │ ├── newattachment.h │ │ │ ├── newbug.h │ │ │ ├── jsoncommand.cpp │ │ │ └── querycommand.cpp │ │ ├── clientbase.cpp │ │ ├── clientbase.h │ │ ├── commentclient.h │ │ ├── productclient.h │ │ ├── attachmentclient.h │ │ ├── bugfieldclient.h │ │ ├── bugclient.h │ │ ├── productclient.cpp │ │ ├── attachmentclient.cpp │ │ ├── bugfieldclient.cpp │ │ ├── commentclient.cpp │ │ └── bugclient.cpp │ │ ├── bugzilla.h │ │ ├── query.cpp │ │ ├── bugzilla.cpp │ │ ├── query.h │ │ └── CMakeLists.txt ├── tests │ ├── data │ │ ├── linux-procfs-maps.so.license │ │ ├── linux-procfs-maps-with-deleted-exe.license │ │ ├── linux-procfs-maps-with-missing-files.license │ │ ├── linux-procfs-maps-with-deleted-exe │ │ ├── linux-procfs-maps.so │ │ ├── linux-procfs-maps-with-missing-files │ │ └── os-release │ ├── sentrytest │ │ ├── data │ │ │ ├── sentry-event.json │ │ │ ├── sentryenvelope │ │ │ └── dsns.json │ │ ├── CMakeLists.txt │ │ ├── sentryfilereply.h │ │ └── sentryenvelopetest.cpp │ ├── python │ │ └── gdb │ │ │ ├── FrameDecorator.py │ │ │ └── __init__.py │ ├── crashtest │ │ └── CMakeLists.txt │ ├── lsb_release_double.c │ ├── bugzillalibtest │ │ └── CMakeLists.txt │ ├── integration │ │ ├── CMakeLists.txt │ │ └── data │ │ │ └── bugs │ └── backtraceparsertest │ │ ├── CMakeLists.txt │ │ ├── backtraceparsertest_data │ │ ├── test_bug192412_a │ │ ├── test_bug192412_b │ │ ├── test_h │ │ ├── data.ini │ │ ├── test_bug168000 │ │ ├── test_e │ │ ├── test_usefulfunctions4 │ │ ├── test_bug200993 │ │ ├── test_usefulfunctions │ │ └── test_c │ │ ├── fakebacktracegenerator.h │ │ ├── fakebacktracegenerator.cpp │ │ ├── backtraceparsertest.h │ │ └── README ├── qml │ ├── qmldir │ ├── MainPageButton.qml │ ├── FooterActionBar.qml │ ├── qml.qrc │ ├── Globals.qml │ ├── DownloadSymbolsCheckBox.qml │ ├── SentPage.qml │ ├── BacktracePage.qml │ ├── PreviewPage.qml │ └── WelcomePage.qml ├── data │ ├── gdb_preamble │ │ └── __init__.py │ └── CMakeLists.txt ├── coredump │ ├── polkit │ │ ├── org.kde.drkonqi.service.in │ │ ├── org.kde.drkonqi.conf │ │ ├── org.kde.drkonqi.policy │ │ └── CMakeLists.txt │ ├── socket.h │ ├── gui │ │ ├── qml │ │ │ ├── qml.qrc │ │ │ └── main.qml │ │ ├── CMakeLists.txt │ │ ├── DetailsLoader.h │ │ ├── DetailsLoader.cpp │ │ └── PatientModel.h │ ├── dumpexcavator │ │ ├── CMakeLists.txt │ │ ├── coredumpexcavator.h │ │ ├── automaticcoredumpexcavator.h │ │ └── coredumpexcavator.cpp │ ├── cleanup │ │ ├── autotests │ │ │ ├── CMakeLists.txt │ │ │ └── cleanuptest.cpp │ │ ├── drkonqi-coredump-cleanup.timer │ │ ├── drkonqi-coredump-cleanup.service.cmake │ │ ├── CMakeLists.txt │ │ └── main.cpp │ ├── launcher │ │ ├── GlobalNotifierTruck.h │ │ ├── DumpTruckInterface.h │ │ ├── drkonqi-coredump-launcher@.service.cmake │ │ ├── DevNotifierTruck.h │ │ ├── drkonqi-coredump-launcher.socket │ │ └── CMakeLists.txt │ ├── CMakeLists.txt │ ├── processor │ │ ├── drkonqi-coredump-pickup.service.cmake │ │ ├── CMakeLists.txt │ │ └── drkonqi-coredump-processor@.service.cmake │ ├── coredump.h │ ├── coredumpwatcher.h │ ├── memory.h │ └── coredump.cpp ├── ExtraDesktop.sh ├── config-drkonqi.h.cmake ├── sentry │ ├── CMakeLists.txt │ ├── data │ │ └── CMakeLists.txt │ ├── postman │ │ ├── main.cpp │ │ ├── drkonqi-sentry-postman.timer │ │ ├── drkonqi-sentry-postman.service.cmake │ │ ├── drkonqi-sentry-postman.path │ │ └── CMakeLists.txt │ └── lib │ │ ├── sentryscope.h │ │ ├── sentrypaths.h │ │ ├── CMakeLists.txt │ │ ├── sentrypostman.h │ │ ├── sentrypostbox.h │ │ ├── sentryenvelope.h │ │ ├── sentryconnection.cpp │ │ ├── sentrydsns.h │ │ ├── sentryscope.cpp │ │ ├── sentryconnection.h │ │ └── sentrypaths.cpp ├── settings.kcfgc ├── core │ ├── drkonqipaths.h │ ├── CMakeLists.txt │ ├── drkonqipaths.cpp │ └── metadata.h ├── qmlextensions │ ├── commentmodel.cpp │ ├── commentmodel.h │ ├── qobjectlistmodel.h │ ├── reproducibilitymodel.h │ ├── qobjectlistmodel.cpp │ ├── doctore.cpp │ ├── platformmodel.h │ ├── doctore.h │ └── credentialstore.h ├── drkonqidialog.h ├── systemd │ ├── org.freedesktop.systemd1.Manager.xml │ ├── org.freedesktop.systemd1.Unit.xml │ ├── CMakeLists.txt │ ├── memorypressure.h │ ├── org.freedesktop.DBus.Properties.xml │ └── memoryfence.h ├── drkonqi_globals.cpp ├── safe_strerror.h ├── detachedprocessmonitor.h ├── parser │ ├── backtraceparsernull.h │ ├── CMakeLists.txt │ ├── backtraceparserlldb.h │ ├── backtraceparser_p.h │ ├── backtraceparsergdb.h │ ├── backtraceparsernull.cpp │ └── backtraceparserlldb.cpp ├── settings.kcfg ├── Messages.sh ├── linuxprocmapsparser.h ├── bugreportaddress.h ├── statusnotifier.h ├── detachedprocessmonitor.cpp ├── debuggermanager.h ├── backtraceratingwidget.h ├── drkonqi_globals.h ├── drkonqiwidgetsdialog.h ├── org.kde.drkonqi.desktop.cmake ├── coredumpbackend.h ├── debugpackageinstaller.h ├── backtracewidget.h ├── drkonqibackends.h ├── statuswidget.h └── backtraceratingwidget.cpp ├── .kateconfig ├── logo.png.license ├── .git-blame-ignore-revs ├── .gitlab-ci.yml ├── cmake ├── Findeu-unstrip.cmake ├── Findcoredumpctl.cmake ├── Findflatpak-coredumpctl.cmake ├── SystemctlEnable.cmake ├── FindGDB.cmake ├── FindPythonModule.cmake.in ├── FindPythonModule.cmake └── FindSystemd.cmake ├── .reuse └── dep5 ├── .gitignore ├── LICENSES ├── LicenseRef-KDE-Accepted-GPL.txt ├── LicenseRef-KDE-Accepted-LGPL.txt ├── BSD-2-Clause.txt └── BSD-3-Clause.txt ├── .kde-ci.yml └── Testing.md /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KDE/drkonqi/HEAD/logo.png -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/bugs.new.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 12345 3 | } 4 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/attachment.new.json: -------------------------------------------------------------------------------- 1 | { 2 | "ids": [1234] 3 | } 4 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/bugzilla.version.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "5.0.0" 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/data/linux-procfs-maps.so.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: none 3 | -------------------------------------------------------------------------------- /.kateconfig: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: none 3 | kate: replace-tabs on; indent-width 4; 4 | -------------------------------------------------------------------------------- /src/qml/qmldir: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: none 3 | singleton Globals 1.0 Globals.qml 4 | -------------------------------------------------------------------------------- /src/tests/data/linux-procfs-maps-with-deleted-exe.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: none 3 | -------------------------------------------------------------------------------- /logo.png.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: LGPL-3.0-or-later 2 | SPDX-FileCopyrightText: 2016 Andreas Kainz 3 | -------------------------------------------------------------------------------- /src/tests/data/linux-procfs-maps-with-missing-files.license: -------------------------------------------------------------------------------- 1 | SPDX-License-Identifier: CC0-1.0 2 | SPDX-FileCopyrightText: none 3 | -------------------------------------------------------------------------------- /src/tests/sentrytest/data/sentry-event.json: -------------------------------------------------------------------------------- 1 | {"event_id": "9ec79c33ec9942ab8353589fcb2e04dc", "message":"hello world","level":"error"} 2 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/bugzilla.login.json: -------------------------------------------------------------------------------- 1 | { 2 | "id" : 52960, 3 | "token" : "52960-aaaaaaaaaa" 4 | } 5 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/hi.http: -------------------------------------------------------------------------------- 1 | HTTP/1.1 200 OK 2 | Date: Tue, 05 Mar 2019 13:42:49 GMT 3 | Server: Apache/2.4.29 (Ubuntu) 4 | 5 | Hello! 6 | -------------------------------------------------------------------------------- /src/data/gdb_preamble/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/put.http: -------------------------------------------------------------------------------- 1 | HTTP/1.1 201 Created 2 | Date: Thu, 07 Mar 2019 12:11:29 GMT 3 | Server: Apache/2.4.29 (Ubuntu) 4 | 5 | General Kenobi! 6 | -------------------------------------------------------------------------------- /src/coredump/polkit/org.kde.drkonqi.service.in: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | [D-BUS Service] 3 | Name=org.kde.drkonqi 4 | Exec=@KDE_INSTALL_FULL_LIBEXECDIR_KF@/drkonqi-polkit-helper 5 | User=root 6 | -------------------------------------------------------------------------------- /src/ExtraDesktop.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | #This file has output in separate line each file with a .desktop syntax 3 | #that needs to be translated but has a non .desktop extension 4 | find data -name "*rc" -print 5 | -------------------------------------------------------------------------------- /src/config-drkonqi.h.cmake: -------------------------------------------------------------------------------- 1 | #cmakedefine01 HAVE_STRSIGNAL 2 | #cmakedefine01 HAVE_UNAME 3 | 4 | #define DEBUG_PACKAGE_INSTALLER_NAME "@DEBUG_PACKAGE_INSTALLER_NAME@" 5 | 6 | #define PROJECT_VERSION "@PROJECT_VERSION@" 7 | -------------------------------------------------------------------------------- /src/sentry/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | add_subdirectory(lib) 5 | add_subdirectory(data) 6 | add_subdirectory(postman) 7 | -------------------------------------------------------------------------------- /src/tests/python/gdb/FrameDecorator.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | class FrameDecorator: 5 | pass 6 | -------------------------------------------------------------------------------- /src/tests/python/gdb/__init__.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | def selected_thread(): 5 | return None 6 | -------------------------------------------------------------------------------- /src/tests/data/linux-procfs-maps-with-deleted-exe: -------------------------------------------------------------------------------- 1 | 55655b57b000-55655b585000 r--p 00000000 00:1b 36066866 /usr/bin/kwrite (deleted) 2 | 55f469b92000-55f46ab0f000 rw-p 00000000 00:00 0 [heap] 3 | -------------------------------------------------------------------------------- /src/tests/crashtest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(crashtest crashtest.cpp) 2 | ecm_mark_as_test(crashtest) 3 | ecm_mark_nongui_executable(crashtest) 4 | target_link_libraries(crashtest KF6::Crash KF6::CoreAddons Qt::Gui Qt::Concurrent) 5 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/error.nobug.invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "code" : 101, 3 | "documentation" : "https://bugzilla.readthedocs.org/en/5.0/api/", 4 | "error" : null, 5 | "message" : "Bug #1 does not exist." 6 | } 7 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/bugs.update.json: -------------------------------------------------------------------------------- 1 | { 2 | "bugs": [ 3 | { 4 | "id": 54321, 5 | "changes": {}, 6 | "alias": [], 7 | "last_change_time": "2019-06-27T13:40:31Z" 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /src/tests/sentrytest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | remove_definitions(-DQT_NO_CAST_FROM_ASCII) 2 | 3 | ecm_add_tests(sentryenvelopetest.cpp 4 | sentrypostboxtest.cpp 5 | sentrydsnstest.cpp 6 | LINK_LIBRARIES Qt::Core Qt::Test DrKonqiSentryInternal) 7 | -------------------------------------------------------------------------------- /src/settings.kcfgc: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | File=settings.kcfg 4 | ClassName=Settings 5 | Mutators=true 6 | DefaultValueGetters=true 7 | Singleton=true 8 | GenerateProperties=true 9 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: none 3 | 4 | # clang-format 5 | 72aec3e0ecde2765d0145dc1934136c2613d8525 6 | f8d6b7da535448e3a9664db0f01415248f2dab4e 7 | # cmake format 8 | 23ce46eb05abf60705a37045b7af32d23ef88ee0 9 | -------------------------------------------------------------------------------- /src/coredump/socket.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #pragma once 7 | 8 | namespace Socket 9 | { 10 | constexpr int DatagramSize = 8192; 11 | } // namespace Socket 12 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/error.http: -------------------------------------------------------------------------------- 1 | HTTP/1.1 401 Unauthorized 2 | Date: Tue, 05 Mar 2019 13:42:49 GMT 3 | Server: Apache/2.4.29 (Ubuntu) 4 | 5 | {"error":true,"documentation":"https://bugzilla.readthedocs.org/en/5.0/api/","message":"You must enter a summary for this bug.","code":107} 6 | -------------------------------------------------------------------------------- /src/tests/data/linux-procfs-maps.so: -------------------------------------------------------------------------------- 1 | 55f467eab000-55f467eb5000 r--p 00000000 00:1b __INODE__ /__FILE_PATH__ 2 | 55f469b92000-55f46ab0f000 rw-p 00000000 00:00 0 [heap] 3 | 7feac05c6000-7feac07f9000 rw-s 00000000 00:01 244999 /memfd:xorg (deleted) 4 | 5 | -------------------------------------------------------------------------------- /src/core/drkonqipaths.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2019-2025 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | namespace Paths 9 | { 10 | [[nodiscard]] QString drkonqiExe(); 11 | } // namespace Paths 12 | -------------------------------------------------------------------------------- /src/tests/data/linux-procfs-maps-with-missing-files: -------------------------------------------------------------------------------- 1 | 55655b57b000-55655b585000 r--p 00000000 00:1b 36066866 /usr/lib/foo.so (deleted) 2 | 55f469b92000-55f46ab0f000 rw-p 00000000 00:00 0 [heap] 3 | 7feac05c6000-7feac07f9000 rw-s 00000000 00:01 244999 /memfd:xorg (deleted) 4 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/models/logindetails.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "logindetails.h" 8 | 9 | namespace Bugzilla 10 | { 11 | } // namespace Bugzilla 12 | -------------------------------------------------------------------------------- /src/tests/lsb_release_double.c: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include 8 | 9 | int main() 10 | { 11 | printf("KDE SUSE User Edition 5.16\n"); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /src/tests/sentrytest/data/sentryenvelope: -------------------------------------------------------------------------------- 1 | {"dsn":"https://foo.bar","event_id":"9ec79c33ec9942ab8353589fcb2e04dc"} 2 | {"length":88,"type":"event"} 3 | {"event_id":"9ec79c33ec9942ab8353589fcb2e04dc","message":"hello world","level":"error"} 4 | 5 | {"length":64,"type":"user_report"} 6 | {"email":"john@me.com","name":"John Me","comments":"It broke."} 7 | -------------------------------------------------------------------------------- /src/coredump/gui/qml/qml.qrc: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | main.qml 8 | ListPage.qml 9 | DetailsPage.qml 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/qmlextensions/commentmodel.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #include "commentmodel.h" 5 | 6 | int CommentsModel::rowCount(const QModelIndex &parent) const 7 | { 8 | Q_UNUSED(parent) 9 | return m_list.size(); 10 | } 11 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: None 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | include: 5 | - project: sysadmin/ci-utilities 6 | file: 7 | - /gitlab-templates/linux-qt6.yml 8 | - /gitlab-templates/xml-lint.yml 9 | - /gitlab-templates/yaml-lint.yml 10 | - /gitlab-templates/qml-lint.yml 11 | - /gitlab-templates/linux-qt6-next.yml 12 | -------------------------------------------------------------------------------- /cmake/Findeu-unstrip.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | find_program(eu-unstrip_EXE eu-unstrip) 5 | 6 | include(FindPackageHandleStandardArgs) 7 | find_package_handle_standard_args(eu-unstrip 8 | FOUND_VAR 9 | eu-unstrip_FOUND 10 | REQUIRED_VARS 11 | eu-unstrip_EXE 12 | ) 13 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/bugupdate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "bugupdate.h" 8 | 9 | namespace Bugzilla 10 | { 11 | } // namespace Bugzilla 12 | 13 | #include "moc_bugupdate.cpp" 14 | -------------------------------------------------------------------------------- /cmake/Findcoredumpctl.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | find_program(coredumpctl_EXE coredumpctl) 5 | 6 | include(FindPackageHandleStandardArgs) 7 | find_package_handle_standard_args(coredumpctl 8 | FOUND_VAR 9 | coredumpctl_FOUND 10 | REQUIRED_VARS 11 | coredumpctl_EXE 12 | ) 13 | -------------------------------------------------------------------------------- /src/coredump/dumpexcavator/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | 3 | add_library(drkonqi-coredumpexcavator OBJECT coredumpexcavator.cpp automaticcoredumpexcavator.cpp) 4 | target_link_libraries(drkonqi-coredumpexcavator Qt6::Core Qt6::DBus) 5 | target_include_directories(drkonqi-coredumpexcavator PUBLIC "$") 6 | -------------------------------------------------------------------------------- /src/sentry/data/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | add_executable(drkonqi-sentry-data main.cpp) 5 | target_link_libraries(drkonqi-sentry-data 6 | Qt::Core 7 | Qt::DBus 8 | KF6::CoreAddons 9 | ) 10 | install(TARGETS drkonqi-sentry-data DESTINATION ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) 11 | -------------------------------------------------------------------------------- /cmake/Findflatpak-coredumpctl.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | find_program(flatpak-coredumpctl_EXE flatpak-coredumpctl) 5 | 6 | include(FindPackageHandleStandardArgs) 7 | find_package_handle_standard_args(flatpak-coredumpctl 8 | FOUND_VAR 9 | flatpak-coredumpctl_FOUND 10 | REQUIRED_VARS 11 | flatpak-coredumpctl_EXE 12 | ) 13 | -------------------------------------------------------------------------------- /src/coredump/cleanup/autotests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | if(NOT BUILD_TESTING) 5 | return() 6 | endif() 7 | 8 | remove_definitions(-DQT_NO_CAST_FROM_ASCII) 9 | 10 | ecm_add_tests(cleanuptest.cpp LINK_LIBRARIES Qt::Core Qt::Test TARGET_NAMES_VAR cleanuptest_TARGET) 11 | add_dependencies(${cleanuptest_TARGET} drkonqi-coredump-cleanup) 12 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/clientbase.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "clientbase.h" 8 | 9 | namespace Bugzilla 10 | { 11 | ClientBase::ClientBase(const Connection &connection) 12 | : m_connection(connection) 13 | { 14 | } 15 | 16 | } // namespace Bugzilla 17 | -------------------------------------------------------------------------------- /src/sentry/postman/main.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #include 5 | 6 | #include 7 | 8 | int main(int argc, char **argv) 9 | { 10 | QCoreApplication app(argc, argv); 11 | 12 | SentryPostman postman; 13 | postman.run(); 14 | 15 | return app.exec(); 16 | } 17 | -------------------------------------------------------------------------------- /src/sentry/postman/drkonqi-sentry-postman.timer: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2021-2023 Harald Sitter 3 | 4 | [Unit] 5 | Description=Submitting pending crash events 6 | ConditionPathExistsGlob=%C/drkonqi/sentry-envelopes/* 7 | 8 | [Timer] 9 | OnCalendar=hourly 10 | Persistent=false 11 | 12 | [Install] 13 | WantedBy=timers.target plasma-core.target 14 | -------------------------------------------------------------------------------- /src/tests/sentrytest/data/dsns.json: -------------------------------------------------------------------------------- 1 | { 2 | "fallthrough": { 3 | "project": "fallthrough", 4 | "key": "asdf", 5 | "index": "12" 6 | }, 7 | "dolphin": { 8 | "project": "dolphin", 9 | "key": "c048b4a60fe742b1b17ed5bb95325e1e", 10 | "index": "4" 11 | }, 12 | "kwrite": { 13 | "project": "kwrite", 14 | "key": "ba18a003921d4ac281851019f69050b4", 15 | "index": "3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/drkonqidialog.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // SPDX-FileCopyrightText: 2009 Dario Andres Rodriguez 3 | // SPDX-FileCopyrightText: 2022 Harald Sitter 4 | 5 | #pragma once 6 | 7 | #include 8 | 9 | class DrKonqiDialog : public QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | using QObject::QObject; 14 | 15 | enum class GoTo { Main, Sentry }; 16 | void show(GoTo to); 17 | }; 18 | -------------------------------------------------------------------------------- /src/sentry/lib/sentryscope.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | class SentryScope 9 | { 10 | public: 11 | [[nodiscard]] static SentryScope *instance(); 12 | QHash environment(); 13 | 14 | QString traceId; 15 | QString spanId; 16 | QString release; 17 | }; 18 | -------------------------------------------------------------------------------- /src/tests/bugzillalibtest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(bugzillalibtest_SRCS bugzillalibtest.cpp) 2 | 3 | ecm_qt_declare_logging_category( 4 | bugzillalibtest_SRCS 5 | HEADER drkonqi_debug.h 6 | IDENTIFIER DRKONQI_LOG 7 | CATEGORY_NAME org.kde.drkonqi 8 | ) 9 | 10 | add_executable(bugzillalibtest ${bugzillalibtest_SRCS}) 11 | ecm_mark_as_test(bugzillalibtest) 12 | 13 | target_link_libraries(bugzillalibtest KF6::KIOWidgets KF6::I18n qbugzilla DrKonqiInternal) 14 | -------------------------------------------------------------------------------- /src/sentry/postman/drkonqi-sentry-postman.service.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2021-2023 Harald Sitter 3 | 4 | [Unit] 5 | Description=Submitting pending crash events 6 | PartOf=graphical-session.target 7 | After=plasma-core.target 8 | 9 | [Service] 10 | ExecStart=@KDE_INSTALL_FULL_LIBEXECDIR@/drkonqi-sentry-postman 11 | RuntimeMaxSec=30 minutes 12 | Restart=no 13 | -------------------------------------------------------------------------------- /.reuse/dep5: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: drkonqi 3 | Upstream-Contact: KDE 4 | Source: https://invent.kde.org/plasma/drkonqi 5 | 6 | Files: src/bugzillaintegration/libbugzilla/autotests/data/* 7 | src/tests/backtraceparsertest/backtraceparsertest_data/* 8 | src/tests/integration/data/* 9 | src/tests/data/* 10 | src/tests/*/data/* 11 | Copyright: none 12 | License: CC0-1.0 13 | -------------------------------------------------------------------------------- /src/coredump/dumpexcavator/coredumpexcavator.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | class QFile; 8 | 9 | class CoredumpExcavator : public QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | using QObject::QObject; 14 | void excavateFromTo(const QString &coreFile, const std::shared_ptr &coreFileTarget); 15 | 16 | Q_SIGNALS: 17 | void excavated(int exitCode); 18 | }; 19 | -------------------------------------------------------------------------------- /src/coredump/launcher/GlobalNotifierTruck.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include "DumpTruckInterface.h" 7 | 8 | #include 9 | 10 | class GlobalNotifierTruck : public QObject, public DumpTruckInterface 11 | { 12 | Q_OBJECT 13 | public: 14 | using QObject::QObject; 15 | [[nodiscard]] bool handle(const Coredump &dump) override; 16 | }; 17 | -------------------------------------------------------------------------------- /src/coredump/polkit/org.kde.drkonqi.conf: -------------------------------------------------------------------------------- 1 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/sentry/lib/sentrypaths.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022-2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | namespace SentryPaths 11 | { 12 | QString payloadsDir(); 13 | QString sentPayloadsDir(); 14 | QString payloadPath(const QString &eventId); 15 | QString sentPayloadPath(const QString &eventId); 16 | } // namespace SentryPaths 17 | -------------------------------------------------------------------------------- /src/sentry/postman/drkonqi-sentry-postman.path: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | [Unit] 5 | Description=Submitting pending crash events (file monitor) 6 | 7 | [Path] 8 | PathExistsGlob=%C/drkonqi/sentry-envelopes/* 9 | MakeDirectory=true 10 | TriggerLimitIntervalSec=30 minutes 11 | TriggerLimitBurst=4 12 | 13 | [Install] 14 | WantedBy=default.target plasma-core.target 15 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/models/logindetails.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef LOGINDETAILS_H 8 | #define LOGINDETAILS_H 9 | 10 | #include 11 | 12 | namespace Bugzilla 13 | { 14 | struct LoginDetails { 15 | int id; 16 | QString token; 17 | }; 18 | 19 | } // namespace Bugzilla 20 | 21 | #endif // LOGINDETAILS_H 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: none 3 | 4 | # Ignore the following files 5 | *~ 6 | *.[oa] 7 | *.diff 8 | *.kate-swp 9 | *.kdev4 10 | .kdev_include_paths 11 | *.kdevelop.pcs 12 | *.moc 13 | *.moc.cpp 14 | *.orig 15 | *.user 16 | .*.swp 17 | .swp.* 18 | Doxyfile 19 | Makefile 20 | avail 21 | random_seed 22 | /build*/ 23 | CMakeLists.txt.user* 24 | *.unc-backup* 25 | .cmake/ 26 | /.clang-format 27 | /compile_commands.json 28 | .clangd 29 | .idea 30 | /cmake-build* 31 | .cache 32 | -------------------------------------------------------------------------------- /src/tests/integration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_test( 2 | NAME drkonqi_integration_suite 3 | COMMAND 4 | ${RUBY_EXECTUABLE} ${CMAKE_CURRENT_SOURCE_DIR}/suite --drkonqi $ --at-spi-bus-launcher 5 | ${ATSPI_BUS_LAUNCHER_EXECUTABLE} --at-spi-registryd ${ATSPI_REGISTRYD_EXECUTABLE} 6 | ) 7 | set_tests_properties(drkonqi_integration_suite PROPERTIES TIMEOUT 150) 8 | 9 | # Hack to get rb files to show in qtc. 10 | file(GLOB RUBIES suite *.rb) 11 | add_custom_target(Rubies ALL echo SOURCES ${RUBIES}) 12 | -------------------------------------------------------------------------------- /src/coredump/launcher/DumpTruckInterface.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | class Coredump; 11 | 12 | class DumpTruckInterface 13 | { 14 | public: 15 | DumpTruckInterface() = default; 16 | virtual ~DumpTruckInterface() = default; 17 | Q_DISABLE_COPY_MOVE(DumpTruckInterface) 18 | [[nodiscard]] virtual bool handle(const Coredump &dump) = 0; 19 | }; 20 | -------------------------------------------------------------------------------- /src/systemd/org.freedesktop.systemd1.Manager.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/coredump/launcher/drkonqi-coredump-launcher@.service.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | [Unit] 5 | Description=Launch DrKonqi for a systemd-coredump crash 6 | PartOf=graphical-session.target 7 | ConditionUser=!@system 8 | 9 | [Service] 10 | # Don't need to be working anywhere specific, use tmp. 11 | WorkingDirectory=%T 12 | ExecStart=@KDE_INSTALL_FULL_LIBEXECDIR@/drkonqi-coredump-launcher 13 | Slice=app.slice 14 | Restart=no 15 | -------------------------------------------------------------------------------- /src/drkonqi_globals.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #include "drkonqi_globals.h" 7 | 8 | #include 9 | 10 | KGuiItem2 DrStandardGuiItem::appRestart() 11 | { 12 | return {i18nc("@action:button", "&Restart Application"), 13 | QIcon::fromTheme(QStringLiteral("system-reboot")), 14 | i18nc("@info:tooltip", "Use this button to restart the crashed application.")}; 15 | } 16 | -------------------------------------------------------------------------------- /src/core/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | # Core library ideally only depending on Qt::Core and KCoreAddons. 5 | # Place to put helper code that is used throughout the stack. Both our CoreApps and GUIApps. 6 | add_library(drkonqi-core STATIC metadata.cpp drkonqipaths.cpp) 7 | target_link_libraries(drkonqi-core PUBLIC Qt::Core) 8 | target_compile_options( 9 | drkonqi-core 10 | PRIVATE 11 | -DKDE_INSTALL_FULL_LIBEXECDIR=\"${KDE_INSTALL_FULL_LIBEXECDIR}\" 12 | ) 13 | -------------------------------------------------------------------------------- /src/coredump/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2021-2022 Harald Sitter 3 | 4 | add_library(drkonqi-coredump STATIC coredump.cpp coredumpwatcher.cpp) 5 | target_link_libraries(drkonqi-coredump PUBLIC Qt::Core Qt::Network Systemd::systemd) 6 | set_property(TARGET drkonqi-coredump PROPERTY POSITION_INDEPENDENT_CODE ON) 7 | 8 | add_subdirectory(cleanup) 9 | add_subdirectory(processor) 10 | add_subdirectory(launcher) 11 | add_subdirectory(gui) 12 | add_subdirectory(polkit) 13 | add_subdirectory(dumpexcavator) 14 | -------------------------------------------------------------------------------- /src/coredump/cleanup/drkonqi-coredump-cleanup.timer: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | [Unit] 5 | Description=Cleanup lingering KCrash metadata 6 | ConditionPathExistsGlob=%C/kcrash-metadata/*.ini 7 | 8 | [Timer] 9 | # Purely for users that always supend, they'd not get cruft cleaned up on login. 10 | # That's also why persistence is of no value or use. 11 | OnCalendar=weekly 12 | Persistent=false 13 | 14 | [Install] 15 | WantedBy=timers.target 16 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | ecm_add_test( 2 | fakebacktracegenerator.cpp 3 | backtraceparsertest.cpp 4 | TEST_NAME backtraceparsertest 5 | LINK_LIBRARIES Qt::Test Qt::Core KF6::KIOWidgets drkonqi_backtrace_parser 6 | ) 7 | add_executable(backtraceparsertest_manual fakebacktracegenerator.cpp backtraceparsertest_manual.cpp) 8 | target_link_libraries(backtraceparsertest_manual Qt::Core KF6::I18n KF6::KIOWidgets drkonqi_backtrace_parser) 9 | ecm_mark_as_test(backtraceparsertest_manual) 10 | ecm_mark_nongui_executable(backtraceparsertest_manual) 11 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_bug192412_a: -------------------------------------------------------------------------------- 1 | [Current thread is 0 (process 12545)] 2 | 3 | Thread 1 (Thread 0x7fddaac76740 (LWP 12545)): 4 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 5 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 6 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 7 | #3 8 | #6 0x0805a0eb in ?? () 9 | #7 0x08050ac4 in _start () 10 | -------------------------------------------------------------------------------- /src/qml/MainPageButton.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2021-2022 Harald Sitter 3 | 4 | import QtQuick 2.15 5 | import QtQuick.Controls 2.15 as QQC2 6 | import QtQuick.Layouts 1.15 7 | import QtQuick.Templates 2.15 as T 8 | import org.kde.kirigami 2.19 as Kirigami 9 | 10 | import org.kde.drkonqi 1.0 11 | 12 | QQC2.Button { 13 | Layout.alignment: Qt.AlignHCenter 14 | icon.width: Kirigami.Units.iconSizes.medium 15 | icon.height: icon.width 16 | visible: action.visible 17 | } 18 | -------------------------------------------------------------------------------- /src/qmlextensions/commentmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include "qobjectlistmodel.h" 7 | 8 | #include "bugzillaintegration/libbugzilla/models/comment.h" 9 | 10 | class CommentsModel : public QObjectListModel 11 | { 12 | public: 13 | using QObjectListModel::QObjectListModel; 14 | 15 | [[nodiscard]] int rowCount(const QModelIndex &parent) const override; 16 | 17 | private: 18 | QList m_list; 19 | }; 20 | -------------------------------------------------------------------------------- /src/safe_strerror.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | inline char *safe_strerror(int error) 10 | { 11 | constexpr auto maxBufferSize = 1024; 12 | thread_local std::array buffer; 13 | // The return value changes depending on CFLAGS, so we intentionally do not do anything with it! 14 | strerror_r(error, buffer.data(), buffer.size()); 15 | return buffer.data(); 16 | } 17 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/clientbase.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef CLIENTBASE_H 8 | #define CLIENTBASE_H 9 | 10 | #include "connection.h" 11 | 12 | namespace Bugzilla 13 | { 14 | class ClientBase 15 | { 16 | public: 17 | explicit ClientBase(const Connection &connection = Bugzilla::connection()); 18 | 19 | protected: 20 | const Connection &m_connection; 21 | }; 22 | 23 | } // namespace Bugzilla 24 | 25 | #endif // CLIENTBASE_H 26 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_bug192412_b: -------------------------------------------------------------------------------- 1 | [Current thread is 0 (process 12545)] 2 | 3 | Thread 1 (Thread 0x7fddaac76740 (LWP 12545)): 4 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 5 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 6 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 7 | #5 0x00007f6e4e3edc34 in Phonon::AbstractMediaStreamPrivate::writeData () from /usr/lib/libphonon.so.4 8 | #6 0x000000000045cdbc in _start () 9 | -------------------------------------------------------------------------------- /src/systemd/org.freedesktop.systemd1.Unit.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | remove_definitions(-DQT_NO_CAST_FROM_ASCII) 2 | 3 | include(ECMAddTests) 4 | include(GenerateExportHeader) 5 | 6 | # Include src so we have access to config-kcrash.h 7 | include_directories(${CMAKE_CURRENT_BINARY_DIR}/..) 8 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 9 | 10 | ecm_add_tests( 11 | attachmenttest.cpp 12 | bugtest.cpp 13 | bugfieldtest.cpp 14 | bugzillatest.cpp 15 | commenttest.cpp 16 | connectiontest.cpp 17 | producttest.cpp 18 | LINK_LIBRARIES Qt::Core Qt::Test Qt::Network qbugzilla 19 | ) 20 | 21 | ecm_mark_nongui_executable(bugzillatest) 22 | -------------------------------------------------------------------------------- /src/coredump/dumpexcavator/automaticcoredumpexcavator.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | class AutomaticCoredumpExcavator : public QObject 9 | { 10 | Q_OBJECT 11 | public: 12 | using QObject::QObject; 13 | void excavateFrom(const QString &coredumpFilename); 14 | 15 | Q_SIGNALS: 16 | void failed(); 17 | // WARNING: the corepath is only valid as long as the excavator exists! 18 | void excavated(const QString &corePath); 19 | 20 | private: 21 | std::unique_ptr m_coreDir; 22 | }; 23 | -------------------------------------------------------------------------------- /src/coredump/launcher/DevNotifierTruck.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include "DumpTruckInterface.h" 7 | 8 | #include 9 | 10 | // Issues KNotifications with the option of opening konsole with gdb. 11 | // It also sports no i18n because it must be opted into and is only intended 12 | // for developers. 13 | class DevNotifierTruck : public QObject, public DumpTruckInterface 14 | { 15 | Q_OBJECT 16 | public: 17 | using QObject::QObject; 18 | [[nodiscard]] bool handle(const Coredump &dump) override; 19 | }; 20 | -------------------------------------------------------------------------------- /src/data/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | install(FILES mappings DESTINATION ${KDE_INSTALL_DATADIR}/drkonqi) 2 | install(DIRECTORY gdb_preamble DESTINATION ${KDE_INSTALL_DATADIR}/drkonqi/gdb/python/) 3 | 4 | if(WITH_PYTHON_VENDORING) 5 | find_program(pip_EXE pip3) 6 | if(NOT pip_EXE) 7 | find_program(pip_EXE pip) 8 | endif() 9 | 10 | set(vendor_dir ${CMAKE_CURRENT_BINARY_DIR}/python) 11 | add_custom_target(python_vendor ALL 12 | BYPRODUCTS ${vendor_dir} 13 | COMMAND ${pip_EXE} install --target ${vendor_dir} pygdbmi psutil sentry-sdk) 14 | install(DIRECTORY ${vendor_dir} DESTINATION ${KDE_INSTALL_DATADIR}/drkonqi/gdb/) 15 | endif() 16 | -------------------------------------------------------------------------------- /src/coredump/processor/drkonqi-coredump-pickup.service.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | [Unit] 5 | Description=Consume pending crashes using DrKonqi 6 | PartOf=graphical-session.target 7 | Requires=drkonqi-coredump-launcher.socket 8 | After=plasma-core.target 9 | After=drkonqi-coredump-launcher.socket 10 | ConditionUser=!@system 11 | 12 | [Service] 13 | ExecStart=@KDE_INSTALL_FULL_LIBEXECDIR@/drkonqi-coredump-processor --settle-first --pickup --uid %U 14 | RuntimeMaxSec=30 minutes 15 | 16 | [Install] 17 | WantedBy=plasma-core.target 18 | -------------------------------------------------------------------------------- /src/detachedprocessmonitor.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #ifndef DETACHEDPROCESSMONITOR_H 7 | #define DETACHEDPROCESSMONITOR_H 8 | 9 | #include 10 | 11 | class DetachedProcessMonitor : public QObject 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit DetachedProcessMonitor(QObject *parent = nullptr); 16 | void startMonitoring(int pid); 17 | 18 | Q_SIGNALS: 19 | void processFinished(); 20 | 21 | protected: 22 | void timerEvent(QTimerEvent *) override; 23 | 24 | private: 25 | int m_pid; 26 | }; 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /cmake/SystemctlEnable.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | function(systemctl_enable unit wantedby dir) 5 | set(wantedby_directory $ENV{DESTDIR}/${dir}/${wantedby}.wants/) 6 | file(MAKE_DIRECTORY ${wantedby_directory}) 7 | execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ../${unit} ${wantedby_directory}/${unit} 8 | RESULT_VARIABLE enable_result 9 | ERROR_VARIABLE enable_fail 10 | COMMAND_ECHO STDOUT) 11 | if(NOT enable_result EQUAL "0") 12 | message(FATAL_ERROR "Systemctl failed: ${enable_fail} ${ARGN}") 13 | endif() 14 | endfunction() 15 | -------------------------------------------------------------------------------- /src/parser/backtraceparsernull.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009-2010 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #ifndef BACKTRACEPARSERNULL_H 7 | #define BACKTRACEPARSERNULL_H 8 | 9 | #include "backtraceparser.h" 10 | 11 | class BacktraceParserNull : public BacktraceParser 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit BacktraceParserNull(QObject *parent = nullptr); 16 | 17 | protected Q_SLOTS: 18 | void newLine(const QString &lineStr) override; 19 | 20 | protected: 21 | BacktraceParserPrivate *constructPrivate() const override; 22 | }; 23 | 24 | #endif // BACKTRACEPARSERNULL_H 25 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commentclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef COMMENTCLIENT_H 8 | #define COMMENTCLIENT_H 9 | 10 | #include "clientbase.h" 11 | #include "models/comment.h" 12 | 13 | namespace Bugzilla 14 | { 15 | class CommentClient : public ClientBase 16 | { 17 | public: 18 | using ClientBase::ClientBase; 19 | 20 | QList getFromBug(KJob *kjob) const; 21 | KJob *getFromBug(int bugId); 22 | }; 23 | 24 | } // namespace Bugzilla 25 | 26 | #endif // COMMENTCLIENT_H 27 | -------------------------------------------------------------------------------- /src/coredump/polkit/org.kde.drkonqi.policy: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 10 | Extracting crash data from $(coreName) 11 | Extraction of crash data 12 | 13 | no 14 | auth_admin 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/parser/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(BACKTRACEPARSER_SRCS 2 | backtraceparser.cpp 3 | backtraceparsergdb.cpp 4 | backtraceparsernull.cpp 5 | backtraceparserlldb.cpp 6 | backtraceparser.h 7 | backtraceparsergdb.h 8 | backtraceparsernull.h 9 | backtraceparserlldb.h 10 | ) 11 | 12 | ecm_qt_declare_logging_category( 13 | BACKTRACEPARSER_SRCS 14 | HEADER drkonqi_parser_debug.h 15 | IDENTIFIER DRKONQI_PARSER_LOG 16 | CATEGORY_NAME org.kde.drkonqi.parser 17 | DESCRIPTION "drkonqi parser" 18 | EXPORT DRKONQI 19 | ) 20 | 21 | add_library(drkonqi_backtrace_parser STATIC ${BACKTRACEPARSER_SRCS}) 22 | target_link_libraries(drkonqi_backtrace_parser PUBLIC Qt::Core) 23 | -------------------------------------------------------------------------------- /src/coredump/polkit/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | 3 | add_executable(drkonqi-polkit-helper main.cpp) 4 | target_link_libraries(drkonqi-polkit-helper Qt6::DBus PolkitQt6-1::Core drkonqi-coredumpexcavator) 5 | install(TARGETS drkonqi-polkit-helper DESTINATION ${KDE_INSTALL_LIBEXECDIR_KF}) 6 | 7 | install(FILES org.kde.drkonqi.conf DESTINATION ${KDE_INSTALL_DBUSDIR}/system.d) 8 | install(FILES org.kde.drkonqi.policy DESTINATION ${KDE_INSTALL_DATADIR}/polkit-1/actions) 9 | configure_file(org.kde.drkonqi.service.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.drkonqi.service) 10 | install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.drkonqi.service DESTINATION ${KDE_INSTALL_DBUSSYSTEMSERVICEDIR}) 11 | -------------------------------------------------------------------------------- /src/settings.kcfg: -------------------------------------------------------------------------------- 1 | 2 | 6 | 10 | 11 | 12 | false 13 | 14 | 15 | false 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/productclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef PRODUCTCLIENT_H 8 | #define PRODUCTCLIENT_H 9 | 10 | #include "clientbase.h" 11 | #include "models/product.h" 12 | 13 | namespace Bugzilla 14 | { 15 | class ProductClient : public ClientBase 16 | { 17 | public: 18 | using ClientBase::ClientBase; 19 | 20 | /// Gets a single Product by its name 21 | Product::Ptr get(KJob *kjob); 22 | KJob *get(const QString &idOrName); 23 | }; 24 | 25 | } // namespace Bugzilla 26 | 27 | #endif // PRODUCTCLIENT_H 28 | -------------------------------------------------------------------------------- /src/parser/backtraceparserlldb.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2014-2016 René J.V. Bertin 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | 7 | #ifndef BACKTRACEPARSERLLDB_H 8 | #define BACKTRACEPARSERLLDB_H 9 | 10 | #include "backtraceparser.h" 11 | 12 | class BacktraceParserLldb : public BacktraceParser 13 | { 14 | Q_OBJECT 15 | Q_DECLARE_PRIVATE(BacktraceParser) 16 | public: 17 | explicit BacktraceParserLldb(QObject *parent = nullptr); 18 | 19 | protected Q_SLOTS: 20 | void newLine(const QString &lineStr) override; 21 | 22 | protected: 23 | BacktraceParserPrivate *constructPrivate() const override; 24 | }; 25 | 26 | #endif // BACKTRACEPARSERLLDB_H 27 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/fakebacktracegenerator.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | 7 | #ifndef FAKEBACKTRACEGENERATOR_H 8 | #define FAKEBACKTRACEGENERATOR_H 9 | 10 | #include 11 | 12 | class FakeBacktraceGenerator : public QObject 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit FakeBacktraceGenerator(QObject *parent = nullptr) 17 | : QObject(parent) 18 | { 19 | } 20 | void sendData(const QString &filename); 21 | 22 | Q_SIGNALS: 23 | void starting(); 24 | void newLine(const QString &line); 25 | }; 26 | 27 | #endif // FAKEBACKTRACEGENERATOR_H 28 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-KDE-Accepted-GPL.txt: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or 2 | modify it under the terms of the GNU General Public License as 3 | published by the Free Software Foundation; either version 3 of 4 | the license or (at your option) at any later version that is 5 | accepted by the membership of KDE e.V. (or its successor 6 | approved by the membership of KDE e.V.), which shall act as a 7 | proxy as defined in Section 14 of version 3 of the license. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | -------------------------------------------------------------------------------- /cmake/FindGDB.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | find_program(GDB_EXE gdb) 5 | 6 | if(GDB_EXE) 7 | execute_process(COMMAND ${GDB_EXE} --version OUTPUT_VARIABLE GDB_VERSION) 8 | # Match the first line only 9 | string(REGEX MATCH "[^\n]+" GDB_VERSION ${GDB_VERSION}) 10 | # Then match the version number only 11 | string(REGEX MATCH "[-_]?([0-9][\-+\.:\~0-9a-zA-Z]*)" GDB_VERSION ${GDB_VERSION}) 12 | endif() 13 | 14 | include(FindPackageHandleStandardArgs) 15 | find_package_handle_standard_args(GDB 16 | FOUND_VAR 17 | GDB_FOUND 18 | VERSION_VAR 19 | GDB_VERSION 20 | REQUIRED_VARS 21 | GDB_EXE 22 | ) 23 | -------------------------------------------------------------------------------- /src/sentry/lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | set(sentry_SRCS) 5 | ecm_qt_declare_logging_category( 6 | sentry_SRCS 7 | HEADER debug.h 8 | IDENTIFIER SENTRY_DEBUG 9 | CATEGORY_NAME org.kde.drkonqi.sentry 10 | DESCRIPTION "drkonqi-sentry" 11 | EXPORT DRKONQI 12 | ) 13 | 14 | add_library(DrKonqiSentryInternal STATIC 15 | ${sentry_SRCS} 16 | sentryconnection.cpp 17 | sentrydsns.cpp 18 | sentryenvelope.cpp 19 | sentrypostbox.cpp 20 | sentrypaths.cpp 21 | sentrypostman.cpp 22 | sentryscope.cpp) 23 | target_link_libraries(DrKonqiSentryInternal 24 | Qt::Core 25 | Qt::Network 26 | ) 27 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/fakebacktracegenerator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #include "fakebacktracegenerator.h" 7 | #include 8 | #include 9 | 10 | void FakeBacktraceGenerator::sendData(const QString &filename) 11 | { 12 | QFile file(filename); 13 | file.open(QIODevice::ReadOnly | QIODevice::Text); 14 | QTextStream stream(&file); 15 | 16 | Q_EMIT starting(); 17 | while (!stream.atEnd()) { 18 | Q_EMIT newLine(stream.readLine() + QLatin1Char('\n')); 19 | } 20 | Q_EMIT newLine(QString()); 21 | } 22 | 23 | #include "moc_fakebacktracegenerator.cpp" 24 | -------------------------------------------------------------------------------- /LICENSES/LicenseRef-KDE-Accepted-LGPL.txt: -------------------------------------------------------------------------------- 1 | This library is free software; you can redistribute it and/or 2 | modify it under the terms of the GNU Lesser General Public 3 | License as published by the Free Software Foundation; either 4 | version 3 of the license or (at your option) any later version 5 | that is accepted by the membership of KDE e.V. (or its successor 6 | approved by the membership of KDE e.V.), which shall act as a 7 | proxy as defined in Section 6 of version 3 of the license. 8 | 9 | This program is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | GNU General Public License for more details. 13 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/jsoncommand.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef JSONCOMMAND_H 8 | #define JSONCOMMAND_H 9 | 10 | #include 11 | 12 | #include "commandbase.h" 13 | 14 | namespace Bugzilla 15 | { 16 | class JsonCommand : public QObject 17 | { 18 | Q_OBJECT 19 | public: 20 | using QObject::QObject; 21 | 22 | virtual QByteArray toJson() const; 23 | virtual QVariantHash toVariantHash() const; 24 | }; 25 | 26 | } // namespace Bugzilla 27 | 28 | Q_DECLARE_METATYPE(Bugzilla::JsonCommand *) 29 | 30 | #endif // JSONCOMMAND_H 31 | -------------------------------------------------------------------------------- /src/tests/data/os-release: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: CC0-1.0 2 | # SPDX-FileCopyrightText: none 3 | 4 | NAME="Name" 5 | VERSION="100.5" 6 | ID=theid 7 | ID_LIKE="otherid otherotherid" 8 | VERSION_CODENAME=versioncodename 9 | VERSION_ID="500.1" 10 | PRETTY_NAME="FreeBSD #1" 11 | ANSI_COLOR="1;34" 12 | CPE_NAME="cpe:/o:foo:bar:100" 13 | HOME_URL="https://url.home" 14 | DOCUMENTATION_URL="https://url.docs" 15 | SUPPORT_URL="https://url.support" 16 | BUG_REPORT_URL="https://url.bugs" 17 | PRIVACY_POLICY_URL="https://url.privacy" 18 | BUILD_ID="105.5" 19 | # comment 20 | VARIANT="Test = Edition" 21 | BROKENLINE_SHOULD_BE_IGNORED 22 | VARIANT_ID=test 23 | # indented comment 24 | LOGO=start-here-test 25 | DEBIAN_BTS="debbugs://bugs.debian.org/" 26 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/querycommand.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef QUERYCOMMAND_H 8 | #define QUERYCOMMAND_H 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "commandbase.h" 15 | #include "query.h" 16 | 17 | namespace Bugzilla 18 | { 19 | class QueryCommand : public QObject 20 | { 21 | public: 22 | using QObject::QObject; 23 | 24 | virtual Query toQuery() const; 25 | Query expandQuery(Query &query, const QSet &seen) const; 26 | }; 27 | 28 | } // namespace Bugzilla 29 | 30 | #endif // QUERYCOMMAND_H 31 | -------------------------------------------------------------------------------- /src/sentry/lib/sentrypostman.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022-2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include "sentryconnection.h" 7 | 8 | // Collects not sent envelopes and sends them off to sentry every once in a while. 9 | // Will just fail when there is no network connectivity. 10 | // Should things go wrong we'll eventually get killed by systemd. 11 | class SentryPostman : public QObject 12 | { 13 | Q_OBJECT 14 | public: 15 | using QObject::QObject; 16 | void run(); 17 | 18 | private: 19 | void post(const QString &path, const QString &filename, const QDateTime &mtime); 20 | SentryNetworkConnection m_connection; 21 | }; 22 | -------------------------------------------------------------------------------- /src/Messages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | # SPDX-FileCopyrightText: 2020-2022 Harald Sitter 4 | 5 | # Ensure passing shellcheck: 6 | # Our l10n scripting isn't working with spaces anywhere and we actively rely on word splitting in our Messages.sh. 7 | # shellcheck disable=SC2046 8 | podir=${podir:?} # ensure it is defined 9 | 10 | $XGETTEXT $(find . -name \*.cpp -o -name \*.h) -o "$podir"/drkonqi.pot 11 | # Extract JavaScripty files as what they are, otherwise for example template literals won't work correctly (by default we extract as C++). 12 | # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals 13 | $XGETTEXT --join-existing --language=JavaScript $(find . -name \*.qml -o -name \*.js) -o "$podir"/drkonqi.pot 14 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/bugzilla.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef BUGZILLA_H 8 | #define BUGZILLA_H 9 | 10 | #include "connection.h" 11 | #include "models/logindetails.h" 12 | 13 | namespace Bugzilla 14 | { 15 | QString version(KJob *kjob); 16 | APIJob *version(const Connection &connection = Bugzilla::connection()); 17 | 18 | // https://bugzilla.readthedocs.io/en/5.0/api/core/v1/user.html#login 19 | LoginDetails login(KJob *kjob); 20 | APIJob *login(const QString &username, const QString &password, const Connection &connection = Bugzilla::connection()); 21 | } // namespace Bugzilla 22 | 23 | #endif // BUGZILLA_H 24 | -------------------------------------------------------------------------------- /src/qmlextensions/qobjectlistmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | class QObjectListModel : public QAbstractListModel 10 | { 11 | Q_OBJECT 12 | public: 13 | enum class Role { 14 | Object = Qt::UserRole, 15 | UserRole, 16 | }; 17 | Q_ENUM(Role) 18 | 19 | using QAbstractListModel::QAbstractListModel; 20 | 21 | virtual QObject *object(const QModelIndex &index) const = 0; 22 | 23 | [[nodiscard]] QVariant data(const QModelIndex &index, int intRole) const override; 24 | [[nodiscard]] QHash roleNames() const override; 25 | }; 26 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/attachmentclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef ATTACHMENTCLIENT_H 8 | #define ATTACHMENTCLIENT_H 9 | 10 | #include "clientbase.h" 11 | #include "commands/newattachment.h" 12 | 13 | namespace Bugzilla 14 | { 15 | class AttachmentClient : public ClientBase 16 | { 17 | public: 18 | using ClientBase::ClientBase; 19 | 20 | /// Attach to a bug. @returns list of bugs that were attached to. 21 | QList createAttachment(KJob *kjob); 22 | KJob *createAttachment(int bugId, const NewAttachment &attachment); 23 | }; 24 | 25 | } // namespace Bugzilla 26 | 27 | #endif // ATTACHMENTCLIENT_H 28 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/models/comment.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "comment.h" 8 | 9 | #include 10 | 11 | namespace Bugzilla 12 | { 13 | Comment::Comment(const QVariantHash &object, QObject *parent) 14 | : QObject(parent) 15 | { 16 | for (auto it = object.constBegin(); it != object.constEnd(); ++it) { 17 | setProperty(qPrintable(it.key()), it.value()); 18 | } 19 | } 20 | 21 | int Comment::bug_id() const 22 | { 23 | return m_bug_id; 24 | } 25 | 26 | QString Comment::text() const 27 | { 28 | return m_text; 29 | } 30 | 31 | } // namespace Bugzilla 32 | 33 | #include "moc_comment.cpp" 34 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/newattachment.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "newattachment.h" 8 | 9 | #include 10 | 11 | namespace Bugzilla 12 | { 13 | QVariantHash NewAttachment::toVariantHash() const 14 | { 15 | auto hash = JsonCommand::toVariantHash(); 16 | 17 | QVariantList idsVariant; 18 | for (int id : ids) { 19 | idsVariant << QVariant::fromValue(id); 20 | } 21 | hash[QStringLiteral("ids")] = idsVariant; 22 | hash[QStringLiteral("data")] = data.toUtf8().toBase64(); 23 | 24 | return hash; 25 | } 26 | 27 | } // namespace Bugzilla 28 | 29 | #include "moc_newattachment.cpp" 30 | -------------------------------------------------------------------------------- /cmake/FindPythonModule.cmake.in: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2015 Aleix Pol Gonzalez 3 | # SPDX-FileCopyrightText: 2022 Harald Sitter 4 | 5 | include(FindPackageHandleStandardArgs) 6 | 7 | execute_process(COMMAND @Python3_EXECUTABLE@ -c "import @MODULE_NAME@" ERROR_VARIABLE ERRORS_OUTPUT OUTPUT_VARIABLE DISREGARD_VARIABLE RESULT_VARIABLE ExitCode TIMEOUT 30) 8 | 9 | if(ExitCode EQUAL 0) 10 | set(@GENMODULE@_FOUND TRUE) 11 | else() 12 | message(STATUS "python3 import failed for @MODULE_NAME@.") 13 | set(@GENMODULE@_FOUND FALSE) 14 | endif() 15 | 16 | find_package_handle_standard_args(@GENMODULE@ 17 | FOUND_VAR 18 | @GENMODULE@_FOUND 19 | REQUIRED_VARS 20 | @GENMODULE@_FOUND 21 | HANDLE_COMPONENTS 22 | ) 23 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/bugupdate.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef BUGUPDATE_H 8 | #define BUGUPDATE_H 9 | 10 | #include "jsoncommand.h" 11 | 12 | namespace Bugzilla 13 | { 14 | class BugUpdateCC : public JsonCommand 15 | { 16 | Q_OBJECT 17 | BUGZILLA_MEMBER_PROPERTY(QStringList, add); 18 | BUGZILLA_MEMBER_PROPERTY(QStringList, remove); 19 | 20 | public: 21 | using JsonCommand::JsonCommand; 22 | }; 23 | 24 | class BugUpdate : public JsonCommand 25 | { 26 | Q_OBJECT 27 | BUGZILLA_MEMBER_PROPERTY(BugUpdateCC *, cc) = new BugUpdateCC(this); 28 | }; 29 | 30 | } // namespace Bugzilla 31 | 32 | #endif // BUGUPDATE_H 33 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/newbug.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "newbug.h" 8 | 9 | #include 10 | 11 | namespace Bugzilla 12 | { 13 | NewBug::NewBug(QObject *parent) 14 | : JsonCommand(parent) 15 | { 16 | } 17 | 18 | NewBug::NewBug(const NewBug &other) 19 | : JsonCommand(other.parent()) 20 | { 21 | const auto propertyCount = staticMetaObject.propertyCount(); 22 | for (int i = 0; i < propertyCount; ++i) { 23 | const auto property = staticMetaObject.property(i); 24 | property.write(this, property.read(&other)); 25 | } 26 | } 27 | 28 | } // namespace Bugzilla 29 | 30 | #include "moc_newbug.cpp" 31 | -------------------------------------------------------------------------------- /src/linuxprocmapsparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-2.0-or-later 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | namespace LinuxProc 11 | { 12 | enum class Check { 13 | DeletedMarker, // < checks the data without disk IO (purely relies on deleted annotation - process must be running!) 14 | Stat, // < includes inode check 15 | }; 16 | 17 | // Checks if the /maps content has deleted libraries, or the executable is deleted. 18 | bool hasMapsDeletedFiles(const QString &exePathString, const QByteArray &maps, Check check); 19 | 20 | // Checks if a given path is a library path (this is also true if it has a "(deleted)" qualifier) 21 | // This is a standalone function to ease testing. 22 | bool isLibraryPath(const QString &path); 23 | } 24 | -------------------------------------------------------------------------------- /src/coredump/gui/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2020-2022 Harald Sitter 3 | 4 | add_executable(drkonqi-coredump-gui main.cpp PatientModel.cpp Patient.cpp DetailsLoader.cpp PatientModel.h Patient.h DetailsLoader.h qml/qml.qrc) 5 | target_compile_definitions(drkonqi-coredump-gui 6 | PRIVATE $<$,$>:QT_QML_DEBUG> 7 | PRIVATE -DTRANSLATION_DOMAIN=\"drkonqi\") 8 | 9 | target_link_libraries(drkonqi-coredump-gui 10 | DrKonqiInternal 11 | Qt::Quick 12 | KF6::I18n 13 | drkonqi-core 14 | drkonqi-coredump 15 | drkonqi-coredumpexcavator 16 | ) 17 | 18 | install(TARGETS drkonqi-coredump-gui ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) 19 | install(FILES org.kde.drkonqi.coredump.gui.desktop DESTINATION ${KDE_INSTALL_APPDIR}) 20 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/bugfieldclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef BUGFIELDCLIENT_H 8 | #define BUGFIELDCLIENT_H 9 | 10 | #include "clientbase.h" 11 | #include "models/bugfield.h" 12 | 13 | namespace Bugzilla 14 | { 15 | class BugFieldClient : public ClientBase 16 | { 17 | public: 18 | using ClientBase::ClientBase; 19 | 20 | KJob *getFields(const QString &idOrName = QString()); 21 | QList getFields(KJob *kjob) const; 22 | 23 | KJob *getField(const QString &idOrName); 24 | /// Ptr may be null if the idOrName matched nothing! 25 | BugField::Ptr getField(KJob *kjob) const; 26 | }; 27 | 28 | } // namespace Bugzilla 29 | 30 | #endif // BUGFIELDCLIENT_H 31 | -------------------------------------------------------------------------------- /src/bugreportaddress.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #ifndef BUGREPORTADDRESS_H 7 | #define BUGREPORTADDRESS_H 8 | 9 | #include 10 | 11 | #include "drkonqi_globals.h" 12 | 13 | class BugReportAddress : public QString 14 | { 15 | public: 16 | inline BugReportAddress() 17 | : QString() 18 | { 19 | } 20 | inline BugReportAddress(const QString &address) 21 | : QString(address == QLatin1String("submit@bugs.kde.org") ? KDE_BUGZILLA_URL : address) 22 | { 23 | } 24 | 25 | inline bool isKdeBugzilla() const 26 | { 27 | return *this == KDE_BUGZILLA_URL; 28 | } 29 | 30 | inline bool isEmail() const 31 | { 32 | return contains(QLatin1Char('@')); 33 | } 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /cmake/FindPythonModule.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2015 Aleix Pol Gonzalez 3 | # SPDX-FileCopyrightText: 2022 Harald Sitter 4 | 5 | set(SELENIUM_ATSPI_MODULES_DIR ${CMAKE_CURRENT_LIST_DIR}) 6 | 7 | function(find_pythonmodule MODULE_NAME) 8 | set(GENMODULE "${MODULE_NAME}-PythonModule") 9 | 10 | configure_file("${SELENIUM_ATSPI_MODULES_DIR}/FindPythonModule.cmake.in" "Find${GENMODULE}.cmake" @ONLY) 11 | 12 | set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}" ${CMAKE_MODULE_PATH}) 13 | find_package(${GENMODULE} ${ARGN}) 14 | 15 | if(COMMAND set_package_properties) 16 | set_package_properties(${GENMODULE} PROPERTIES 17 | DESCRIPTION "Python module '${MODULE_NAME}' is a runtime dependency." 18 | TYPE RUNTIME) 19 | endif() 20 | endfunction() 21 | -------------------------------------------------------------------------------- /cmake/FindSystemd.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2021 Henri Chain 3 | # SPDX-FileCopyrightText: 2021 Harald Sitter 4 | 5 | # Try to find systemd on a linux system 6 | # This will define the following variables: 7 | # 8 | # ``Systemd_FOUND`` 9 | # True if systemd is available 10 | # ``Systemd_VERSION`` 11 | # The version of systemd 12 | 13 | find_package(PkgConfig QUIET) 14 | pkg_check_modules(Systemd QUIET IMPORTED_TARGET GLOBAL libsystemd) 15 | 16 | if(TARGET PkgConfig::Systemd) 17 | add_library(Systemd::systemd ALIAS PkgConfig::Systemd) 18 | endif() 19 | 20 | include(FindPackageHandleStandardArgs) 21 | find_package_handle_standard_args(Systemd 22 | REQUIRED_VARS 23 | Systemd_FOUND 24 | VERSION_VAR 25 | Systemd_VERSION 26 | ) 27 | 28 | mark_as_advanced(Systemd_VERSION) 29 | -------------------------------------------------------------------------------- /src/systemd/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | set(SYSTEMD_DBUS_XMLS 5 | org.freedesktop.systemd1.Manager.xml 6 | org.freedesktop.systemd1.Unit.xml 7 | org.freedesktop.DBus.Properties.xml 8 | ) 9 | 10 | set_source_files_properties(${SYSTEMD_DBUS_XMLS} PROPERTIES INCLUDE dbustypes.h) 11 | qt_add_dbus_interfaces(dbus_SRCS ${SYSTEMD_DBUS_XMLS}) 12 | 13 | add_library(systemd-dbus OBJECT ${dbus_SRCS}) 14 | target_link_libraries(systemd-dbus PRIVATE Qt::DBus) 15 | target_include_directories(systemd-dbus PUBLIC "$") 16 | 17 | target_sources(DrKonqiInternal PRIVATE 18 | memoryfence.cpp 19 | memorypressure.cpp 20 | ) 21 | 22 | target_link_libraries(DrKonqiInternal 23 | Systemd::systemd 24 | systemd-dbus 25 | ) 26 | -------------------------------------------------------------------------------- /src/coredump/gui/DetailsLoader.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "Patient.h" 12 | 13 | Q_DECLARE_METATYPE(Patient *) 14 | class DetailsLoader : public QObject 15 | { 16 | Q_OBJECT 17 | 18 | Q_PROPERTY(Patient *patient MEMBER m_patient WRITE setPatient NOTIFY patientChanged) 19 | Patient *m_patient = nullptr; 20 | void setPatient(Patient *patient); 21 | Q_SIGNAL void patientChanged(); 22 | 23 | public: 24 | using QObject::QObject; 25 | 26 | Q_SIGNALS: 27 | void details(const QString &details); 28 | void error(const QString &error); 29 | 30 | private: 31 | void load(); 32 | std::unique_ptr m_LoaderProcess; 33 | }; 34 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/bugsearch.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "bugsearch.h" 8 | 9 | namespace Bugzilla 10 | { 11 | Query BugSearch::toQuery() const 12 | { 13 | Query query; 14 | QSet seen; 15 | 16 | for (const QString &product : products) { 17 | query.addQueryItem(QStringLiteral("product"), product); 18 | } 19 | seen << QStringLiteral("products"); 20 | 21 | if (!order.isEmpty()) { 22 | query.addQueryItem(QStringLiteral("order"), order.join(QLatin1Char(','))); 23 | } 24 | seen << QStringLiteral("order"); 25 | 26 | expandQuery(query, seen); 27 | 28 | return query; 29 | } 30 | 31 | } // namespace Bugzilla 32 | 33 | #include "moc_bugsearch.cpp" 34 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_h: -------------------------------------------------------------------------------- 1 | [Current thread is 0 (process 12545)] 2 | 3 | Thread 1 (Thread 0x7fddaac76740 (LWP 12545)): 4 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 5 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 6 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 7 | #3 8 | #4 0x00007f44eff82065 in *__GI_raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 9 | #5 0x00007f44eff85153 in *__GI_abort () at abort.c:88 10 | #6 0x00007f44f1b6d775 in qt_message_output (msgType=QtFatalMsg, buf=) at global/qglobal.cpp:2017 11 | #7 0x00007f44f1b6d8bb in qFatal (msg=) at global/qglobal.cpp:2216 12 | #8 0x0000000000402815 in main () 13 | -------------------------------------------------------------------------------- /src/parser/backtraceparser_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009-2010 George Kiagiadakis 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | 5 | SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | #ifndef BACKTRACEPARSER_P_H 8 | #define BACKTRACEPARSER_P_H 9 | 10 | #include "backtraceparser.h" 11 | 12 | class BacktraceParserPrivate 13 | { 14 | public: 15 | BacktraceParserPrivate() 16 | : m_usefulness(BacktraceParser::InvalidUsefulness) 17 | { 18 | } 19 | ~BacktraceParserPrivate() 20 | { 21 | } 22 | 23 | QStringList m_infoLines; 24 | QList m_linesList; 25 | QList m_linesToRate; 26 | QString m_simplifiedBacktrace; 27 | QStringList m_librariesWithMissingDebugSymbols; 28 | BacktraceParser::Usefulness m_usefulness; 29 | bool m_compositorCrashed = false; 30 | }; 31 | 32 | #endif // BACKTRACEPARSER_P_H 33 | -------------------------------------------------------------------------------- /src/coredump/cleanup/drkonqi-coredump-cleanup.service.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | [Unit] 5 | Description=Cleanup lingering KCrash metadata 6 | ConditionPathExistsGlob=%C/kcrash-metadata/*.ini 7 | PartOf=graphical-session.target 8 | After=plasma-core.target 9 | 10 | [Service] 11 | ExecStart=@KDE_INSTALL_FULL_LIBEXECDIR@/drkonqi-coredump-cleanup %C/kcrash-metadata/ 12 | RuntimeMaxSec=30 minutes 13 | 14 | [Install] 15 | # This is a bit of a stop-gap. Ideally we should have a different service run on login to 16 | # pick up lingering crashes that are relevant (e.g. crash on last logout) and only what is 17 | # left over should then get cleaned up (if the file is old enough). 18 | # Since we currently lack the UI infrastructure for that we had better clean up on login 19 | # unconditionally. 20 | WantedBy=default.target 21 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/bugclient.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef BUGCLIENT_H 8 | #define BUGCLIENT_H 9 | 10 | #include "clientbase.h" 11 | #include "commands/bugsearch.h" 12 | #include "commands/bugupdate.h" 13 | #include "commands/newbug.h" 14 | 15 | #include 16 | 17 | namespace Bugzilla 18 | { 19 | class BugClient : public ClientBase 20 | { 21 | public: 22 | using ClientBase::ClientBase; 23 | 24 | QList search(KJob *kjob) const; 25 | KJob *search(const BugSearch &search); 26 | 27 | qint64 create(KJob *kjob) const; 28 | KJob *create(const NewBug &bug); 29 | 30 | qint64 update(KJob *kjob) const; 31 | KJob *update(qint64 bugId, BugUpdate &bug); 32 | }; 33 | 34 | } // namespace Bugzilla 35 | 36 | #endif // BUGCLIENT_H 37 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/models/comment.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019-2022 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef COMMENT_H 8 | #define COMMENT_H 9 | 10 | #include 11 | #include 12 | 13 | namespace Bugzilla 14 | { 15 | class Comment : public QObject 16 | { 17 | Q_OBJECT 18 | Q_PROPERTY(int bug_id READ bug_id MEMBER m_bug_id NOTIFY changed) 19 | Q_PROPERTY(QString text READ text MEMBER m_text NOTIFY changed) 20 | public: 21 | using Ptr = QPointer; 22 | 23 | explicit Comment(const QVariantHash &object, QObject *parent = nullptr); 24 | 25 | int bug_id() const; 26 | QString text() const; 27 | 28 | Q_SIGNALS: 29 | void changed(); 30 | 31 | private: 32 | int m_bug_id = -1; 33 | QString m_text; 34 | }; 35 | 36 | } // namespace Bugzilla 37 | 38 | #endif // COMMENT_H 39 | -------------------------------------------------------------------------------- /src/coredump/cleanup/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | if(BUILD_TESTING) 5 | add_subdirectory(autotests) 6 | endif() 7 | 8 | add_executable(drkonqi-coredump-cleanup main.cpp) 9 | install(TARGETS drkonqi-coredump-cleanup DESTINATION ${KDE_INSTALL_LIBEXECDIR}) 10 | 11 | configure_file(drkonqi-coredump-cleanup.service.cmake ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-cleanup.service) 12 | install( 13 | FILES drkonqi-coredump-cleanup.timer ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-cleanup.service 14 | DESTINATION ${KDE_INSTALL_SYSTEMDUSERUNITDIR} 15 | ) 16 | install(CODE " 17 | include(${CMAKE_SOURCE_DIR}/cmake/SystemctlEnable.cmake) 18 | systemctl_enable(drkonqi-coredump-cleanup.service default.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 19 | systemctl_enable(drkonqi-coredump-cleanup.timer timers.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 20 | ") 21 | -------------------------------------------------------------------------------- /src/qml/FooterActionBar.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2021 Harald Sitter 3 | // SPDX-FileCopyrightText: 2025 Thomas Duckworth 4 | 5 | import QtQuick 2.15 6 | import QtQuick.Controls 2.15 as QQC2 7 | import org.kde.kirigami 2.19 as Kirigami 8 | 9 | QQC2.ToolBar { 10 | property alias actions: _actionToolBar.actions 11 | 12 | height: Kirigami.Units.smallSpacing * 2 + _actionToolBar.height + 1 13 | position: QQC2.ToolBar.Footer 14 | 15 | Kirigami.Theme.inherit: false 16 | Kirigami.Theme.colorSet: Kirigami.Theme.Header 17 | 18 | Kirigami.ActionToolBar { 19 | id: _actionToolBar 20 | 21 | anchors.left: parent.left 22 | anchors.right: parent.right 23 | anchors.verticalCenter: parent.verticalCenter 24 | 25 | alignment: Qt.AlignRight 26 | flat: false 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/qml/qml.qrc: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | main.qml 8 | MainPage.qml 9 | DeveloperPage.qml 10 | BugzillaPage.qml 11 | RatingItem.qml 12 | ReportPage.qml 13 | WelcomePage.qml 14 | ContextPage.qml 15 | LoginPage.qml 16 | PreviewPage.qml 17 | BacktracePage.qml 18 | Globals.qml 19 | FooterActionBar.qml 20 | SendingPage.qml 21 | SentPage.qml 22 | SentryPage.qml 23 | MainPageButton.qml 24 | DownloadSymbolsCheckBox.qml 25 | qmldir 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/bugsearch.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef BUGSEARCH_H 8 | #define BUGSEARCH_H 9 | 10 | #include "querycommand.h" 11 | 12 | namespace Bugzilla 13 | { 14 | class BugSearch : public QueryCommand 15 | { 16 | Q_OBJECT 17 | BUGZILLA_MEMBER_PROPERTY(QStringList, products); 18 | BUGZILLA_MEMBER_PROPERTY(QString, severity); 19 | BUGZILLA_MEMBER_PROPERTY(QString, creationTime); 20 | BUGZILLA_MEMBER_PROPERTY(qint64, id) = -1; 21 | BUGZILLA_MEMBER_PROPERTY(qint64, limit) = -1; 22 | BUGZILLA_MEMBER_PROPERTY(qint64, offset) = -1; 23 | BUGZILLA_MEMBER_PROPERTY(QString, longdesc); 24 | BUGZILLA_MEMBER_PROPERTY(QStringList, order); 25 | 26 | public: 27 | Query toQuery() const override; 28 | }; 29 | 30 | } // namespace Bugzilla 31 | 32 | #endif // BUGSEARCH_H 33 | -------------------------------------------------------------------------------- /src/coredump/gui/qml/main.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2020-2022 Harald Sitter 3 | 4 | import QtQuick 2.15 5 | import QtQuick.Layouts 1.15 6 | import org.kde.config as KConfig 7 | import org.kde.kirigami 2.19 as Kirigami 8 | 9 | 10 | Kirigami.ApplicationWindow { 11 | id: root 12 | 13 | title: i18nc("@title:window", "Overview") 14 | minimumWidth: Kirigami.Settings.isMobile ? 0 : Kirigami.Units.gridUnit * 22 15 | minimumHeight: Kirigami.Settings.isMobile ? 0 : Kirigami.Units.gridUnit * 22 16 | width: Kirigami.Settings.isMobile ? undefined : Kirigami.Units.gridUnit * 42 17 | height: Kirigami.Settings.isMobile ? undefined : Kirigami.Units.gridUnit * 34 18 | 19 | KConfig.WindowStateSaver { 20 | configGroupName: "MainWindow" 21 | } 22 | 23 | pageStack.initialPage: ListPage {} 24 | pageStack.defaultColumnWidth: root.width // show single page 25 | } 26 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/query.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #include "query.h" 7 | 8 | namespace Bugzilla 9 | { 10 | bool Query::hasQueryItem(const QString &key) 11 | { 12 | return contains(key); 13 | } 14 | 15 | void Query::addQueryItem(const QString &key, const QString &value) 16 | { 17 | insert(key, value); 18 | } 19 | 20 | // Don't use this to do anything other than streaming to qDebug. 21 | // The output is not encoded and thus not necessarily a valid URL query. 22 | QString Query::toString() const 23 | { 24 | QString output; 25 | for (auto it = cbegin(); it != cend(); ++it) { 26 | if (!output.isEmpty()) { 27 | output += QStringLiteral("&"); 28 | } 29 | output += it.key() + QStringLiteral("=") + it.value(); 30 | } 31 | return output; 32 | } 33 | 34 | } // namespace Bugzilla 35 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/commandbase.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef COMMANDBASE_H 8 | #define COMMANDBASE_H 9 | 10 | #define BUGZILLA_MEMBER_PROPERTY(type, member) \ 11 | private: \ 12 | Q_PROPERTY(type member MEMBER member) \ 13 | public: \ 14 | type member 15 | 16 | #endif // COMMANDBASE_H 17 | -------------------------------------------------------------------------------- /src/qmlextensions/reproducibilitymodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "bugzillaintegration/reportinterface.h" 9 | 10 | class ReproducibilityModel : public QAbstractListModel 11 | { 12 | Q_OBJECT 13 | public: 14 | enum class Role { 15 | String = Qt::UserRole, 16 | Integer, 17 | }; 18 | Q_ENUM(Role) 19 | 20 | using QAbstractListModel::QAbstractListModel; 21 | 22 | [[nodiscard]] int rowCount(const QModelIndex &parent) const override; 23 | [[nodiscard]] QVariant data(const QModelIndex &index, int intRole) const override; 24 | [[nodiscard]] QHash roleNames() const override; 25 | 26 | private: 27 | static QList reproducibilities(); 28 | const QList m_list = reproducibilities(); 29 | }; 30 | -------------------------------------------------------------------------------- /src/systemd/memorypressure.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | class SDPressureMonitor; 9 | 10 | class MemoryPressure : public QObject 11 | { 12 | Q_OBJECT 13 | public: 14 | enum class Level { 15 | // Low memory pressure 16 | Low, 17 | // Memory pressure is high 18 | High, 19 | }; 20 | 21 | [[nodiscard]] static MemoryPressure *instance(); 22 | 23 | ~MemoryPressure() override; 24 | Q_DISABLE_COPY_MOVE(MemoryPressure) 25 | 26 | void reset(); 27 | 28 | [[nodiscard]] Level level() const; 29 | 30 | Q_SIGNALS: 31 | void levelChanged(); 32 | void monitoring(pid_t pid); 33 | void pidReset(); 34 | 35 | private: 36 | explicit MemoryPressure(QObject *parent = nullptr); 37 | 38 | Level m_level = Level::Low; 39 | SDPressureMonitor *m_monitor = nullptr; 40 | }; 41 | -------------------------------------------------------------------------------- /src/core/drkonqipaths.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2019-2025 Harald Sitter 3 | 4 | #include "drkonqipaths.h" 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | QString Paths::drkonqiExe() 12 | { 13 | // Borrowed from kcrash.cpp 14 | static QStringList paths = QFile::decodeName(qgetenv("LIBEXEC_PATH")).split(QLatin1Char(':'), Qt::SkipEmptyParts) 15 | + QStringList{ 16 | QCoreApplication::applicationDirPath(), // then look where our application binary is located 17 | QLibraryInfo::path(QLibraryInfo::LibraryExecutablesPath), // look where libexec path is (can be set in qt.conf) 18 | QFile::decodeName(KDE_INSTALL_FULL_LIBEXECDIR), // look at our installation location 19 | }; 20 | static QString exec = QStandardPaths::findExecutable(QStringLiteral("drkonqi"), paths); 21 | return exec; 22 | } 23 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/data.ini: -------------------------------------------------------------------------------- 1 | [usefulness] 2 | test_a=Useless 3 | test_b=MayBeUseful 4 | test_c=ProbablyUseless 5 | test_d=ReallyUseful 6 | test_e=ProbablyUseless 7 | test_f=ProbablyUseless 8 | test_g=ReallyUseful 9 | test_h=ProbablyUseless 10 | test_bug190882=ReallyUseful 11 | test_bug192412_a=Useless 12 | test_bug192412_b=Useless 13 | test_bug168000=MayBeUseful 14 | test_bug200993=ReallyUseful 15 | 16 | [debugger] 17 | test_a=gdb 18 | test_b=gdb 19 | test_c=gdb 20 | test_d=gdb 21 | test_e=gdb 22 | test_f=gdb 23 | test_g=gdb 24 | test_h=gdb 25 | test_bug190882=gdb 26 | test_bug192412_a=gdb 27 | test_bug192412_b=gdb 28 | test_bug168000=gdb 29 | test_bug200993=gdb 30 | test_usefulfunctions=gdb 31 | test_usefulfunctions2=gdb 32 | test_usefulfunctions3=gdb 33 | test_usefulfunctions4=gdb 34 | test_usefulfunctions5=gdb 35 | test_trailing_const=gdb 36 | test_anon_namespace=gdb 37 | test_compositorCrashBug431561=gdb 38 | 39 | [compositorCrash] 40 | test_a=false 41 | test_compositorCrashBug431561=true 42 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/jobdouble.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef JOBDOUBLE_H 8 | #define JOBDOUBLE_H 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace Bugzilla 16 | { 17 | class JobDouble : public APIJob 18 | { 19 | public: 20 | using APIJob::APIJob; 21 | 22 | JobDouble(const QString &fixture) 23 | : m_fixture(fixture) 24 | { 25 | } 26 | 27 | QByteArray data() const override 28 | { 29 | Q_ASSERT(!m_fixture.isEmpty()); 30 | QFile file(m_fixture); 31 | if (!file.open(QFile::ReadOnly | QFile::Text)) { 32 | return {}; 33 | } 34 | QTextStream in(&file); 35 | return in.readAll().toUtf8(); 36 | } 37 | 38 | QString m_fixture; 39 | }; 40 | 41 | } // namespace Bugzilla 42 | 43 | #endif // JOBDOUBLE_H 44 | -------------------------------------------------------------------------------- /src/qml/Globals.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | pragma Singleton 5 | import QtQuick 2.6 6 | 7 | import org.kde.drkonqi 1.0 8 | 9 | QtObject { 10 | readonly property string bugzillaUrl: DrKonqi.kdeBugzillaURL() 11 | readonly property string bugzillaCreateAccountUrl: bugzillaUrl + "createaccount.cgi" 12 | readonly property string ownBugzillaUrl: bugzillaUrl + "enter_bug.cgi?product=drkonqi&format=guided" 13 | readonly property string bugzillaShortUrl: DrKonqi.kdeBugzillaDomain() 14 | readonly property string techbaseHowtoDoc: "https://community.kde.org/Guidelines_and_HOWTOs/Debugging/How_to_create_useful_crash_reports#Preparing_your_KDE_packages" 15 | readonly property string aboutBugReportingUrl: "https://community.kde.org/Get_Involved/Issue_Reporting" 16 | 17 | function bugUrl(bugNumber) { 18 | return bugzillaUrl + "show_bug.cgi?id=" + bugNumber 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_bug168000: -------------------------------------------------------------------------------- 1 | [Current thread is 0 (process 12545)] 2 | 3 | Thread 1 (Thread 0x7fddaac76740 (LWP 12545)): 4 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 5 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 6 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 7 | #3 8 | #5 0x00007f50e99f776f in QWidget::testAttribute_helper (this=0x6e6440, 9 | attribute=Qt::WA_WState_Created) at kernel/qwidget.cpp:9081 10 | #6 0x00007f50e9a37d51 in QWidget::mapFromGlobal (this=0x6e6440, 11 | pos=@0x7ffff350ff90) 12 | at ../../include/QtGui/../../src/gui/kernel/qwidget.h:991 13 | #7 0x00007f50e9a37e79 in QWidget::mapFromGlobal (this=0x6e6450, 14 | pos=@0x7ffff350ff90) at kernel/qwidget_x11.cpp:1069 15 | #8 0x000000000041fb6c in _start () 16 | #0 0x00007f50e75ff241 in nanosleep () from /lib/libc.so.6 17 | -------------------------------------------------------------------------------- /src/statusnotifier.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2016 Kai Uwe Broulik 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | 7 | #ifndef DRKONQI_STATUSNOTIFIER_H 8 | #define DRKONQI_STATUSNOTIFIER_H 9 | 10 | #include 11 | 12 | class QTimer; 13 | 14 | class KStatusNotifierItem; 15 | 16 | class CrashedApplication; 17 | 18 | class StatusNotifier : public QObject 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | enum class Activation { NotAllowed, Allowed, AlreadySubmitting }; 24 | 25 | explicit StatusNotifier(QObject *parent = nullptr); 26 | ~StatusNotifier() override; 27 | 28 | void show(); 29 | void notify(Activation activation); 30 | 31 | static bool notificationServiceRegistered(); 32 | 33 | Q_SIGNALS: 34 | void expired(); 35 | void activated(); 36 | void sentryActivated(); 37 | 38 | private: 39 | static bool canBeRestarted(CrashedApplication *app); 40 | 41 | KStatusNotifierItem *m_sni = nullptr; 42 | QString m_title; 43 | }; 44 | 45 | #endif // DRKONQI_STATUSNOTIFIER_H 46 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | 5 | SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | #ifndef BACKTRACEPARSERTEST_H 8 | #define BACKTRACEPARSERTEST_H 9 | 10 | #include "../../parser/backtraceparser.h" 11 | #include "fakebacktracegenerator.h" 12 | #include 13 | #include 14 | 15 | class BacktraceParserTest : public QObject 16 | { 17 | Q_OBJECT 18 | public: 19 | BacktraceParserTest(QObject *parent = nullptr); 20 | 21 | private Q_SLOTS: 22 | void btParserUsefulnessTest_data(); 23 | void btParserUsefulnessTest(); 24 | void btParserBenchmark_data(); 25 | void btParserBenchmark(); 26 | void btParserCompositorCrashTest_data(); 27 | void btParserCompositorCrashTest(); 28 | 29 | private: 30 | void fetchData(const QString &group); 31 | 32 | QSettings m_settings; 33 | FakeBacktraceGenerator *m_generator = nullptr; 34 | }; 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/detachedprocessmonitor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #include "detachedprocessmonitor.h" 7 | #include "drkonqi_debug.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | using namespace std::chrono_literals; 16 | 17 | DetachedProcessMonitor::DetachedProcessMonitor(QObject *parent) 18 | : QObject(parent) 19 | , m_pid(0) 20 | { 21 | } 22 | 23 | void DetachedProcessMonitor::startMonitoring(int pid) 24 | { 25 | m_pid = pid; 26 | startTimer(10ms); 27 | } 28 | 29 | void DetachedProcessMonitor::timerEvent(QTimerEvent *event) 30 | { 31 | Q_ASSERT(m_pid != 0); 32 | if (::kill(m_pid, 0) < 0) { 33 | qCDebug(DRKONQI_LOG) << "Process" << m_pid << "finished. kill(2) returned errno:" << errno; 34 | killTimer(event->timerId()); 35 | m_pid = 0; 36 | Q_EMIT processFinished(); 37 | } 38 | } 39 | 40 | #include "moc_detachedprocessmonitor.cpp" 41 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/newattachment.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef NEWATTACHMENT_H 8 | #define NEWATTACHMENT_H 9 | 10 | #include "jsoncommand.h" 11 | 12 | namespace Bugzilla 13 | { 14 | class NewAttachment : public JsonCommand 15 | { 16 | Q_OBJECT 17 | BUGZILLA_MEMBER_PROPERTY(QList, ids); 18 | BUGZILLA_MEMBER_PROPERTY(QString, data); 19 | BUGZILLA_MEMBER_PROPERTY(QString, file_name); 20 | BUGZILLA_MEMBER_PROPERTY(QString, summary); 21 | BUGZILLA_MEMBER_PROPERTY(QString, content_type); 22 | BUGZILLA_MEMBER_PROPERTY(QString, comment); 23 | BUGZILLA_MEMBER_PROPERTY(bool, is_patch) = false; 24 | BUGZILLA_MEMBER_PROPERTY(bool, is_private) = false; 25 | 26 | // flags property is not supported at this time 27 | 28 | public: 29 | QVariantHash toVariantHash() const override; 30 | }; 31 | 32 | } // namespace Bugzilla 33 | 34 | #endif // NEWATTACHMENT_H 35 | -------------------------------------------------------------------------------- /src/coredump/launcher/drkonqi-coredump-launcher.socket: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | [Unit] 5 | Description=Socket to launch DrKonqi for a systemd-coredump crash 6 | DefaultDependencies=no 7 | ConditionUser=!@system 8 | 9 | [Socket] 10 | # This is a bit problematic. Technically the user should be able to set the runtime dir via env as well, but we need 11 | # a persistent location so the system-level service can talk to us :| 12 | ListenSequentialPacket=/run/user/%U/drkonqi-coredump-launcher 13 | SocketMode=0600 14 | Accept=yes 15 | # Disable trigger limit for the benefit of older systemds 16 | # TODO: remove in favor of PollLimitBurst mechanism once systemd 255 is in ubuntu LTS 17 | TriggerLimitBurst=0 18 | # NB: this effectively also limits how many concurrent drkonqis run! 19 | MaxConnections=16 20 | 21 | [Install] 22 | WantedBy=sockets.target 23 | # Prevents trigger-limit-hit failure state by restarting the unit (systemd 250[?]) 24 | UpheldBy=sockets.target 25 | -------------------------------------------------------------------------------- /src/debuggermanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | 5 | SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | #ifndef DEBUGGERMANAGER_H 8 | #define DEBUGGERMANAGER_H 9 | 10 | #include 11 | 12 | class BacktraceGenerator; 13 | class Debugger; 14 | class AbstractDrKonqiBackend; 15 | 16 | class DebuggerManager : public QObject 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit DebuggerManager(const Debugger &internalDebugger, AbstractDrKonqiBackend *backendParent); 21 | ~DebuggerManager() override; 22 | 23 | bool debuggerIsRunning() const; 24 | BacktraceGenerator *backtraceGenerator() const; 25 | 26 | Q_SIGNALS: 27 | void debuggerStarting(); 28 | void debuggerFinished(); 29 | void debuggerRunning(bool running); 30 | 31 | private Q_SLOTS: 32 | void onDebuggerStarting(); 33 | void onDebuggerFinished(); 34 | 35 | private: 36 | struct Private; 37 | Private *const d; 38 | }; 39 | 40 | #endif // DEBUGGERMANAGER_H 41 | -------------------------------------------------------------------------------- /src/tests/sentrytest/sentryfilereply.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | class FileReply : public SentryReply 11 | { 12 | public: 13 | explicit FileReply(const QString &path, QObject *parent = nullptr) 14 | : SentryReply(parent) 15 | , m_file(path) 16 | { 17 | const auto open = m_file.open(QFile::ReadOnly); 18 | QMetaObject::invokeMethod(this, &FileReply::finished, Qt::QueuedConnection); 19 | Q_ASSERT(open); 20 | } 21 | 22 | QByteArray readAll() override 23 | { 24 | return m_file.readAll(); 25 | } 26 | 27 | QNetworkReply::NetworkError error() override 28 | { 29 | return m_error; 30 | } 31 | 32 | QString errorString() override 33 | { 34 | return m_errorString; 35 | } 36 | 37 | QNetworkReply::NetworkError m_error = QNetworkReply::NoError; 38 | QString m_errorString; 39 | QFile m_file; 40 | }; 41 | -------------------------------------------------------------------------------- /.kde-ci.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: None 2 | # SPDX-License-Identifier: CC0-1.0 3 | 4 | Dependencies: 5 | - 'on': ['@all'] 6 | 'require': 7 | 'frameworks/extra-cmake-modules': '@latest-kf6' 8 | 'frameworks/kauth': '@latest-kf6' 9 | 'frameworks/kcodecs': '@latest-kf6' 10 | 'frameworks/kconfig': '@latest-kf6' 11 | 'frameworks/kcoreaddons': '@latest-kf6' 12 | 'frameworks/kcrash': '@latest-kf6' 13 | 'frameworks/ki18n': '@latest-kf6' 14 | 'frameworks/kidletime': '@latest-kf6' 15 | 'frameworks/kitemmodels': '@latest-kf6' 16 | 'frameworks/kio': '@latest-kf6' 17 | 'frameworks/kjobwidgets': '@latest-kf6' 18 | 'frameworks/knotifications': '@latest-kf6' 19 | 'frameworks/kservice': '@latest-kf6' 20 | 'frameworks/kwallet': '@latest-kf6' 21 | 'frameworks/kwidgetsaddons': '@latest-kf6' 22 | 'frameworks/kwindowsystem': '@latest-kf6' 23 | 'frameworks/solid': '@latest-kf6' 24 | 'frameworks/syntax-highlighting': '@latest-kf6' 25 | 'frameworks/kcmutils': '@latest-kf6' 26 | 'frameworks/kstatusnotifieritem': '@latest-kf6' 27 | 28 | Options: 29 | require-passing-tests-on: ['Linux', 'FreeBSD'] 30 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/productclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019-2021 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "productclient.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace Bugzilla 15 | { 16 | Product::Ptr ProductClient::get(KJob *kjob) 17 | { 18 | auto job = qobject_cast(kjob); 19 | 20 | const QJsonArray productsArray = job->object().value(QLatin1String("products")).toArray(); 21 | if (productsArray.isEmpty()) { 22 | throw Bugzilla::RuntimeException(QStringLiteral("Failed to resolve bugzilla product")); 23 | } 24 | Q_ASSERT(productsArray.size() == 1); 25 | 26 | auto obj = productsArray.at(0).toObject().toVariantHash(); 27 | 28 | return Product::Ptr(new Product(obj, m_connection)); 29 | } 30 | 31 | KJob *ProductClient::get(const QString &idOrName) 32 | { 33 | return m_connection.get(QStringLiteral("/product/%1").arg(idOrName)); 34 | } 35 | 36 | } // namespace Bugzilla 37 | -------------------------------------------------------------------------------- /src/backtraceratingwidget.h: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * backtraceratingwidget.h 3 | * SPDX-FileCopyrightText: 2009 Dario Andres Rodriguez 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * 7 | ******************************************************************/ 8 | 9 | #ifndef BACKTRACERATINGWIDGET__H 10 | #define BACKTRACERATINGWIDGET__H 11 | 12 | #include 13 | 14 | #include "backtracegenerator.h" 15 | #include "parser/backtraceparser.h" 16 | 17 | class QPixmap; 18 | 19 | class BacktraceRatingWidget : public QWidget 20 | { 21 | Q_OBJECT 22 | 23 | public: 24 | explicit BacktraceRatingWidget(QWidget *); 25 | void setUsefulness(BacktraceParser::Usefulness); 26 | void setState(BacktraceGenerator::State s) 27 | { 28 | m_state = s; 29 | update(); 30 | } 31 | 32 | protected: 33 | void paintEvent(QPaintEvent *event) override; 34 | 35 | private: 36 | BacktraceGenerator::State m_state; 37 | 38 | int m_numStars; 39 | QPixmap m_errorPixmap; 40 | 41 | QPixmap m_starPixmap; 42 | QPixmap m_disabledStarPixmap; 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/parser/backtraceparsergdb.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009-2010 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #ifndef BACKTRACEPARSERGDB_H 7 | #define BACKTRACEPARSERGDB_H 8 | 9 | #include "backtraceparser.h" 10 | class BacktraceParserGdbPrivate; 11 | 12 | class BacktraceLineGdb : public BacktraceLine 13 | { 14 | public: 15 | BacktraceLineGdb(const QString &line); 16 | 17 | private: 18 | void parse(); 19 | void rate(); 20 | }; 21 | 22 | class BacktraceParserGdb : public BacktraceParser 23 | { 24 | Q_OBJECT 25 | Q_DECLARE_PRIVATE(BacktraceParserGdb) 26 | public: 27 | explicit BacktraceParserGdb(QObject *parent = nullptr); 28 | 29 | QString parsedBacktrace() const override; 30 | QList parsedBacktraceLines() const override; 31 | static const QLatin1String KCRASH_INFO_MESSAGE; 32 | 33 | protected: 34 | BacktraceParserPrivate *constructPrivate() const override; 35 | 36 | protected Q_SLOTS: 37 | void newLine(const QString &lineStr) override; 38 | 39 | private: 40 | void parseLine(const QString &lineStr); 41 | }; 42 | 43 | #endif // BACKTRACEPARSERGDB_H 44 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/attachmentclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "attachmentclient.h" 8 | 9 | #include 10 | 11 | namespace Bugzilla 12 | { 13 | QList AttachmentClient::createAttachment(KJob *kjob) 14 | { 15 | auto *job = qobject_cast(kjob); 16 | 17 | auto ary = job->object().value(QStringLiteral("ids")).toArray(); 18 | // It's unclear if this can happen. When the ids would be empty there was 19 | // an error, and when there was an error the API should have sent an error. 20 | Q_ASSERT(ary.size() > 0); 21 | 22 | QList list; 23 | for (auto ids : ary) { 24 | bool ok = false; 25 | list.append(ids.toVariant().toInt(&ok)); 26 | Q_ASSERT(ok); 27 | } 28 | 29 | return list; 30 | } 31 | 32 | KJob *AttachmentClient::createAttachment(int bugId, const NewAttachment &attachment) 33 | { 34 | return m_connection.post(QStringLiteral("/bug/%1/attachment").arg(bugId), attachment.toJson()); 35 | } 36 | 37 | } // namespace Bugzilla 38 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/bugfieldclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "bugfieldclient.h" 8 | 9 | namespace Bugzilla 10 | { 11 | KJob *BugFieldClient::getFields(const QString &idOrName) 12 | { 13 | return m_connection.get(QStringLiteral("/field/bug/") + idOrName); 14 | } 15 | 16 | QList BugFieldClient::getFields(KJob *kjob) const 17 | { 18 | auto *job = qobject_cast(kjob); 19 | 20 | const auto ary = job->object().value(QStringLiteral("fields")).toArray(); 21 | 22 | QList list; 23 | list.reserve(ary.size()); 24 | for (const auto &bug : std::as_const(ary)) { 25 | list.append(BugField::Ptr(new BugField(bug.toObject().toVariantHash()))); 26 | } 27 | return list; 28 | } 29 | 30 | KJob *BugFieldClient::getField(const QString &idOrName) 31 | { 32 | return getFields(idOrName); 33 | } 34 | 35 | BugField::Ptr BugFieldClient::getField(KJob *kjob) const 36 | { 37 | return getFields(kjob).value(0, nullptr); 38 | } 39 | 40 | } // namespace Bugzilla 41 | -------------------------------------------------------------------------------- /src/sentry/postman/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-2-Clause 2 | # SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | add_executable(drkonqi-sentry-postman main.cpp) 5 | target_link_libraries(drkonqi-sentry-postman 6 | DrKonqiSentryInternal 7 | ) 8 | 9 | install(TARGETS drkonqi-sentry-postman DESTINATION ${KDE_INSTALL_LIBEXECDIR}) 10 | 11 | configure_file(drkonqi-sentry-postman.service.cmake ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-sentry-postman.service) 12 | install( 13 | FILES drkonqi-sentry-postman.timer drkonqi-sentry-postman.path ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-sentry-postman.service 14 | DESTINATION ${KDE_INSTALL_SYSTEMDUSERUNITDIR} 15 | ) 16 | install(CODE " 17 | include(${CMAKE_SOURCE_DIR}/cmake/SystemctlEnable.cmake) 18 | systemctl_enable(drkonqi-sentry-postman.path default.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 19 | systemctl_enable(drkonqi-sentry-postman.path plasma-core.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 20 | systemctl_enable(drkonqi-sentry-postman.timer timers.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 21 | systemctl_enable(drkonqi-sentry-postman.timer plasma-core.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 22 | ") 23 | -------------------------------------------------------------------------------- /src/qmlextensions/qobjectlistmodel.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #include "qobjectlistmodel.h" 5 | 6 | QVariant QObjectListModel::data(const QModelIndex &index, int intRole) const 7 | { 8 | if (!index.isValid()) { 9 | return {}; 10 | } 11 | 12 | switch (static_cast(intRole)) { 13 | case Role::Object: 14 | return QVariant::fromValue(object(index)); 15 | case Role::UserRole: 16 | return {}; 17 | } 18 | 19 | return {}; 20 | } 21 | 22 | QHash QObjectListModel::roleNames() const 23 | { 24 | static QHash roles; 25 | if (!roles.isEmpty()) { 26 | return roles; 27 | } 28 | 29 | roles = QAbstractListModel::roleNames(); 30 | const QMetaEnum roleEnum = QMetaEnum::fromType(); 31 | for (int i = 0; i < roleEnum.keyCount(); ++i) { 32 | const int value = roleEnum.value(i); 33 | Q_ASSERT(value != -1); 34 | roles[value] = QByteArray("ROLE_") + roleEnum.valueToKey(value); 35 | } 36 | return roles; 37 | } 38 | 39 | #include "moc_qobjectlistmodel.cpp" 40 | -------------------------------------------------------------------------------- /src/parser/backtraceparsernull.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009-2010 George Kiagiadakis 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #include "backtraceparsernull.h" 7 | #include "backtraceparser_p.h" 8 | 9 | // BEGIN BacktraceLineNull 10 | 11 | class BacktraceLineNull : public BacktraceLine 12 | { 13 | public: 14 | BacktraceLineNull(const QString &line); 15 | }; 16 | 17 | BacktraceLineNull::BacktraceLineNull(const QString &line) 18 | : BacktraceLine() 19 | { 20 | d->m_line = line; 21 | d->m_rating = MissingEverything; 22 | } 23 | 24 | // END BacktraceLineNull 25 | 26 | // BEGIN BacktraceParserNull 27 | 28 | BacktraceParserNull::BacktraceParserNull(QObject *parent) 29 | : BacktraceParser(parent) 30 | { 31 | } 32 | 33 | BacktraceParserPrivate *BacktraceParserNull::constructPrivate() const 34 | { 35 | BacktraceParserPrivate *d = BacktraceParser::constructPrivate(); 36 | d->m_usefulness = MayBeUseful; 37 | return d; 38 | } 39 | 40 | void BacktraceParserNull::newLine(const QString &lineStr) 41 | { 42 | d_ptr->m_linesList.append(BacktraceLineNull(lineStr)); 43 | } 44 | 45 | // END BacktraceParserNull 46 | 47 | #include "moc_backtraceparsernull.cpp" 48 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/newbug.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #ifndef NEWBUG_H 8 | #define NEWBUG_H 9 | 10 | #include "jsoncommand.h" 11 | 12 | namespace Bugzilla 13 | { 14 | class NewBug : public JsonCommand 15 | { 16 | Q_OBJECT 17 | BUGZILLA_MEMBER_PROPERTY(QString, product); 18 | BUGZILLA_MEMBER_PROPERTY(QString, component); 19 | BUGZILLA_MEMBER_PROPERTY(QString, summary); // aka shortdesc 20 | BUGZILLA_MEMBER_PROPERTY(QString, version); 21 | BUGZILLA_MEMBER_PROPERTY(QString, description); 22 | BUGZILLA_MEMBER_PROPERTY(QString, op_sys); 23 | BUGZILLA_MEMBER_PROPERTY(QString, platform); 24 | BUGZILLA_MEMBER_PROPERTY(QString, priority); 25 | BUGZILLA_MEMBER_PROPERTY(QString, severity); 26 | BUGZILLA_MEMBER_PROPERTY(QStringList, keywords); // not documented but also supported 27 | public: 28 | // only needed because we impl the copy ctor, otherwise this could be `using` 29 | explicit NewBug(QObject *parent = nullptr); 30 | NewBug(const NewBug &other); 31 | }; 32 | 33 | } // namespace Bugzilla 34 | 35 | #endif // NEWBUG_H 36 | -------------------------------------------------------------------------------- /src/tests/sentrytest/sentryenvelopetest.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #include 5 | 6 | #include 7 | 8 | using namespace Qt::StringLiterals; 9 | 10 | class SentryEnvelopeTest : public QObject 11 | { 12 | Q_OBJECT 13 | private Q_SLOTS: 14 | void testConstruction() 15 | { 16 | const auto payload = "{\"event_id\":\"9ec79c33ec9942ab8353589fcb2e04dc\",\"message\":\"hello world\",\"level\":\"error\"}\n"_qba; 17 | SentryEnvelope envelope; 18 | // Fixate for test 19 | envelope.m_headers["event_id"] = "9ec79c33ec9942ab8353589fcb2e04dc"; 20 | envelope.setDSN(QUrl("https://foo.bar"_L1)); 21 | envelope.addItem(SentryEvent(payload)); 22 | envelope.addItem(SentryUserFeedback("{\"email\":\"john@me.com\",\"name\":\"John Me\",\"comments\":\"It broke.\"}\n"_qba)); 23 | 24 | QFile f(QFINDTESTDATA("data/sentryenvelope")); 25 | QVERIFY(f.open(QFile::ReadOnly)); 26 | QCOMPARE(envelope.toEnvelope(), f.readAll()); 27 | } 28 | }; 29 | 30 | QTEST_GUILESS_MAIN(SentryEnvelopeTest) 31 | 32 | #include "sentryenvelopetest.moc" 33 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commentclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "commentclient.h" 8 | 9 | #include 10 | 11 | namespace Bugzilla 12 | { 13 | QList CommentClient::getFromBug(KJob *kjob) const 14 | { 15 | auto *job = qobject_cast(kjob); 16 | QJsonObject bugs = job->object().value(QStringLiteral("bugs")).toObject(); 17 | 18 | // The API should never return anything other than the single bug we asked for. 19 | Q_ASSERT(bugs.keys().size() == 1); 20 | 21 | QJsonObject bug = bugs.value(bugs.keys().at(0)).toObject(); 22 | QJsonArray comments = bug.value(QStringLiteral("comments")).toArray(); 23 | 24 | QList list; 25 | for (auto it = comments.constBegin(); it != comments.constEnd(); ++it) { 26 | list.append(new Comment((*it).toObject().toVariantHash())); 27 | } 28 | 29 | return list; 30 | } 31 | 32 | KJob *CommentClient::getFromBug(int bugId) 33 | { 34 | return m_connection.get(QStringLiteral("/bug/%1/comment").arg(QString::number(bugId))); 35 | } 36 | 37 | } // namespace Bugzilla 38 | -------------------------------------------------------------------------------- /src/sentry/lib/sentrypostbox.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022-2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | #include "sentrydsns.h" 12 | #include "sentryenvelope.h" 13 | 14 | // Manager for sentry envelope construction and delivery 15 | class SentryPostbox : public QObject 16 | { 17 | Q_OBJECT 18 | public: 19 | explicit SentryPostbox(const QString &applicationName, std::shared_ptr connection, QObject *parent = nullptr); 20 | 21 | void addEventPayload(const QJsonDocument &document); 22 | void addUserFeedback(const QString &feedbackString); 23 | 24 | void deliver(); 25 | bool hasDelivered() const; 26 | bool isReadyToDeliver() const; 27 | [[nodiscard]] QString eventId() const; 28 | 29 | Q_SIGNALS: 30 | void hasDeliveredChanged(); 31 | 32 | private Q_SLOTS: 33 | void onDSNsLoaded(); 34 | 35 | private: 36 | SentryEnvelope m_envelope; 37 | SentryDSNs m_dsns; 38 | SentryDSNContext m_dsnContext; 39 | 40 | QString m_applicationName; 41 | bool m_hasDelivered = false; 42 | bool m_dsnSet = false; 43 | }; 44 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/README: -------------------------------------------------------------------------------- 1 | This is a unit test for the BacktraceInfo class, which is used in drkonqi 2 | to rate the usefulness of a backtrace. 3 | 4 | This test dynamically loads test data from the "backtraceinfotest_data" directory. 5 | To add new data, simply create a file starting with the "test_" prefix and paste 6 | a backtrace in it. Then, in the "usefulness_map" file, add a line with the following format: 7 | 8 | test_file: UsefulnessValue 9 | 10 | where "test_file" is the exact filename of the file containing the backtrace and 11 | UsefulnessValue is the usefulness value that you expect the backtrace to get. 12 | Whitespaces do not matter, they are ignored. Valid usefulness values can be seen 13 | in backtraceinfotest.h, in the enum BacktraceInfoTest::Usefulness. 14 | 15 | The UsefulnessValue has to be the enum's text representation of the 16 | value and not an integer. For example, having the enum like this: 17 | 18 | enum Usefulness { ReallyUseful = 0, MayBeUseful=1, ProbablyUseless=2, Useless = 3 }; 19 | 20 | "ReallyUseful" is a valid value, but "0" isn't. 21 | 22 | 23 | All files in the "backtraceinfotest_data" directory that do not start with the 24 | "test_" prefix are ignored (except the "usefulness_map" file, which has a special 25 | purpose, as described above) 26 | -------------------------------------------------------------------------------- /src/qml/DownloadSymbolsCheckBox.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2024 Harald Sitter 3 | 4 | import QtQuick 5 | import QtQuick.Layouts 6 | import QtQuick.Controls as QQC2 7 | import org.kde.kirigami as Kirigami 8 | 9 | import org.kde.drkonqi as DrKonqi 10 | 11 | RowLayout { 12 | id: root 13 | 14 | spacing: Kirigami.Units.smallSpacing 15 | 16 | QQC2.CheckBox { 17 | Layout.fillWidth: true 18 | Layout.maximumWidth: Math.min(implicitWidth, root.width) 19 | checked: DrKonqi.Settings.downloadSymbols 20 | text: i18nc("@label", "Automatically download debug symbols to enhance crash reports") 21 | onToggled: { 22 | DrKonqi.Settings.downloadSymbols = checked 23 | DrKonqi.Settings.save() 24 | } 25 | } 26 | 27 | Kirigami.ContextualHelpButton { 28 | toolTipText: i18nc("@info:tooltip", 29 | `Crash reports can be of greater value if additional debugging resources are downloaded from your distributor first. 30 | This may also cause increased memory usage, will take longer, and causes downloads of unknown size when a crash occurs. This is skipped automatically when using a metered internet connection.`) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/qmlextensions/doctore.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #include "doctore.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "crashedapplication.h" 11 | #include "drkonqi.h" 12 | 13 | void Doctore::saveReport(const QString &text) 14 | { 15 | DrKonqi::saveReport(text, nullptr); 16 | } 17 | 18 | void Doctore::copyToClipboard(const QString &text) 19 | { 20 | QGuiApplication::clipboard()->setText(text.trimmed()); 21 | } 22 | 23 | QString Doctore::appName() 24 | { 25 | return DrKonqi::crashedApplication()->name(); 26 | } 27 | 28 | QString Doctore::kdeBugzillaURL() 29 | { 30 | return DrKonqi::kdeBugzillaURL(); 31 | } 32 | 33 | QString Doctore::kdeBugzillaDomain() 34 | { 35 | QUrl bugzillaUrl(DrKonqi::kdeBugzillaURL()); 36 | return bugzillaUrl.host(); 37 | } 38 | 39 | bool Doctore::isSafer() 40 | { 41 | return DrKonqi::isSafer(); 42 | } 43 | 44 | SystemInformation *Doctore::systemInformation() 45 | { 46 | return DrKonqi::systemInformation(); 47 | } 48 | 49 | Q_INVOKABLE bool Doctore::ignoreQuality() 50 | { 51 | return DrKonqi::ignoreQuality(); 52 | } 53 | 54 | #include "moc_doctore.cpp" 55 | -------------------------------------------------------------------------------- /src/coredump/processor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2019-2022 Harald Sitter 3 | 4 | add_executable(drkonqi-coredump-processor main.cpp) 5 | target_link_libraries(drkonqi-coredump-processor Qt::Core drkonqi-coredump) 6 | install(TARGETS drkonqi-coredump-processor DESTINATION ${KDE_INSTALL_LIBEXECDIR}) 7 | 8 | configure_file( 9 | drkonqi-coredump-processor@.service.cmake 10 | ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-processor@.service 11 | ) 12 | install( 13 | FILES ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-processor@.service 14 | DESTINATION ${KDE_INSTALL_SYSTEMDUNITDIR}/system 15 | ) 16 | 17 | configure_file( 18 | drkonqi-coredump-pickup.service.cmake 19 | ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-pickup.service 20 | ) 21 | install( 22 | FILES ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-pickup.service 23 | DESTINATION ${KDE_INSTALL_SYSTEMDUSERUNITDIR} 24 | ) 25 | 26 | install(CODE " 27 | include(${CMAKE_SOURCE_DIR}/cmake/SystemctlEnable.cmake) 28 | systemctl_enable(drkonqi-coredump-processor@.service systemd-coredump@.service ${KDE_INSTALL_FULL_SYSTEMDUNITDIR}/system) 29 | systemctl_enable(drkonqi-coredump-pickup.service plasma-core.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 30 | ") 31 | -------------------------------------------------------------------------------- /src/drkonqi_globals.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #ifndef DRKONQI_GLOBALS_H 7 | #define DRKONQI_GLOBALS_H 8 | 9 | #include 10 | #include 11 | 12 | #include "drkonqi.h" 13 | 14 | /** This class provides a custom constructor to fill the "toolTip" 15 | * and "whatsThis" texts of KGuiItem with the same text. 16 | */ 17 | class KGuiItem2 : public KGuiItem 18 | { 19 | public: 20 | inline KGuiItem2(const QString &text, const QIcon &icon, const QString &toolTip) 21 | : KGuiItem(text, icon, toolTip, toolTip) 22 | { 23 | } 24 | }; 25 | 26 | namespace DrStandardGuiItem 27 | { 28 | KGuiItem2 appRestart(); 29 | }; // namespace DrStandardGuiItem 30 | 31 | /* Urls are defined globally here, so that they can change easily */ 32 | #define KDE_BUGZILLA_URL DrKonqi::kdeBugzillaURL() 33 | #define KDE_BUGZILLA_CREATE_ACCOUNT_URL KDE_BUGZILLA_URL + QStringLiteral("createaccount.cgi") 34 | #define KDE_BUGZILLA_SHORT_URL "bugs.kde.org" 35 | #define TECHBASE_HOWTO_DOC "https://community.kde.org/Guidelines_and_HOWTOs/Debugging/How_to_create_useful_crash_reports#Preparing_your_KDE_packages" 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /src/qml/SentPage.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | import QtQuick 2.15 5 | import QtQuick.Layouts 1.15 6 | import QtQuick.Controls 2.15 as QQC2 7 | import org.kde.kirigami 2.19 as Kirigami 8 | 9 | import org.kde.drkonqi 1.0 10 | 11 | Kirigami.ScrollablePage { 12 | title: i18nc("@title", "Crash Report Sent") 13 | 14 | property int bugNumber: 0 15 | 16 | actions: [ 17 | Kirigami.Action { 18 | icon.name: "system-reboot-symbolic" 19 | text: i18nc("@action %1 is an application name e.g. kwrite", "Restart %1", CrashedApplication.name) 20 | visible: !CrashedApplication.hasBeenRestarted 21 | onTriggered: CrashedApplication.restart() 22 | } 23 | ] 24 | 25 | ColumnLayout { 26 | QQC2.Label { 27 | text: xi18nc("@info", "URL: %1", Globals.bugUrl(bugNumber)) 28 | wrapMode: Text.Wrap 29 | onLinkActivated: link => Qt.openUrlExternally(link) 30 | } 31 | QQC2.Label { 32 | text: i18nc("@info", "Thank you for being a part of KDE. You may now close this window.") 33 | wrapMode: Text.Wrap 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/drkonqiwidgetsdialog.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // SPDX-FileCopyrightText: 2009 Dario Andres Rodriguez 3 | // SPDX-FileCopyrightText: 2022 Harald Sitter 4 | 5 | #ifndef DRKONQIDIALOG__H 6 | #define DRKONQIDIALOG__H 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "ui_maindialog.h" 14 | 15 | class BacktraceWidget; 16 | class QTabWidget; 17 | class QDialogButtonBox; 18 | class QMenu; 19 | 20 | class DrKonqiWidgetsDialog : public QDialog 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit DrKonqiWidgetsDialog(QObject *parent = nullptr); 26 | ~DrKonqiWidgetsDialog() override; 27 | 28 | private Q_SLOTS: 29 | void linkActivated(const QString &); 30 | 31 | void applicationRestarted(bool success); 32 | 33 | // GUI 34 | void buildIntroWidget(); 35 | void buildDialogButtons(); 36 | 37 | void tabIndexChanged(int); 38 | 39 | private: 40 | QTabWidget *m_tabWidget = nullptr; 41 | 42 | QWidget *m_introWidget = nullptr; 43 | Ui::MainWidget ui; 44 | 45 | BacktraceWidget *m_backtraceWidget = nullptr; 46 | 47 | QDialogButtonBox *m_buttonBox = nullptr; 48 | QPushButton *m_restartButton = nullptr; 49 | bool m_debugButtonInBox = false; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/coredump/launcher/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # SPDX-FileCopyrightText: 2019-2022 Harald Sitter 3 | 4 | add_executable(drkonqi-coredump-launcher main.cpp GlobalNotifierTruck.cpp DevNotifierTruck.cpp) 5 | target_link_libraries(drkonqi-coredump-launcher Qt::Core KF6::ConfigCore KF6::Notifications KF6::KIOGui KF6::I18n drkonqi-core drkonqi-coredump) 6 | if(WITH_GLOBAL_NOTIFIER) 7 | target_compile_definitions(drkonqi-coredump-launcher PRIVATE -DWITH_GLOBAL_NOTIFIER) 8 | endif() 9 | if(WITH_DRKONQI_REPORTING) 10 | target_compile_definitions(drkonqi-coredump-launcher PRIVATE -DWITH_DRKONQI_REPORTING) 11 | endif() 12 | install(TARGETS drkonqi-coredump-launcher DESTINATION ${KDE_INSTALL_LIBEXECDIR}) 13 | 14 | configure_file(drkonqi-coredump-launcher@.service.cmake ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-launcher@.service) 15 | install( 16 | FILES drkonqi-coredump-launcher.socket ${CMAKE_CURRENT_BINARY_DIR}/drkonqi-coredump-launcher@.service 17 | DESTINATION ${KDE_INSTALL_SYSTEMDUSERUNITDIR} 18 | ) 19 | install(CODE " 20 | include(${CMAKE_SOURCE_DIR}/cmake/SystemctlEnable.cmake) 21 | systemctl_enable(drkonqi-coredump-launcher.socket sockets.target ${KDE_INSTALL_FULL_SYSTEMDUSERUNITDIR}) 22 | ") 23 | install( FILES drkonqi-coredump-launcher.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR}) 24 | -------------------------------------------------------------------------------- /src/coredump/coredump.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2019-2022 Harald Sitter 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include "memory.h" 14 | 15 | class Coredump 16 | { 17 | public: 18 | using EntriesHash = QHash; 19 | 20 | Coredump(QByteArray cursor, EntriesHash data); 21 | explicit Coredump(const QJsonDocument &document); 22 | 23 | ~Coredump() = default; 24 | 25 | // In a function cause it is used in more than one location. 26 | static QByteArray keyFilename(); 27 | static QByteArray keyPickup(); 28 | static QByteArray keyCursor(); 29 | 30 | // Other bits and bobs 31 | QByteArray m_cursor; 32 | EntriesHash m_rawData; 33 | 34 | // Journal Entry values 35 | uid_t uid = 0; 36 | pid_t pid = -1; 37 | QString exe; 38 | QString filename; // core dump file if available (may be /dev/null if the core is stored in journal directly - only in older systemds) 39 | QString systemd_unit; 40 | QString bootId; 41 | QString timestamp; 42 | 43 | private: 44 | static EntriesHash documentToHash(const QJsonDocument &document); 45 | Q_DISABLE_COPY_MOVE(Coredump) 46 | }; 47 | -------------------------------------------------------------------------------- /src/qmlextensions/platformmodel.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | class BugzillaManager; 9 | 10 | class PlatformModel : public QAbstractListModel 11 | { 12 | Q_OBJECT 13 | public: 14 | enum class Role { 15 | Name, 16 | }; 17 | Q_ENUM(Role) 18 | 19 | using QAbstractListModel::QAbstractListModel; 20 | 21 | Q_PROPERTY(BugzillaManager *manager MEMBER m_manager WRITE setManager NOTIFY managerChanged) 22 | BugzillaManager *m_manager = nullptr; 23 | void setManager(BugzillaManager *manager); 24 | Q_SIGNAL void managerChanged(); 25 | 26 | Q_PROPERTY(int detectedPlatformRow READ detectedPlatformRow NOTIFY detectedPlatformRowChanged) 27 | [[nodiscard]] int detectedPlatformRow(); 28 | Q_SIGNAL void detectedPlatformRowChanged(); 29 | 30 | Q_PROPERTY(QString error MEMBER m_error NOTIFY errorChanged) 31 | QString m_error; 32 | Q_SIGNAL void errorChanged(); 33 | 34 | [[nodiscard]] int rowCount(const QModelIndex &parent) const override; 35 | [[nodiscard]] QVariant data(const QModelIndex &index, int intRole) const override; 36 | [[nodiscard]] QHash roleNames() const override; 37 | 38 | private: 39 | QStringList m_list; 40 | }; 41 | -------------------------------------------------------------------------------- /src/coredump/coredumpwatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2019-2022 Harald Sitter 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "memory.h" 14 | 15 | class Coredump; 16 | class CoredumpWatcher : public QObject 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit CoredumpWatcher(std::unique_ptr context_, QString bootId_, const QString &instance_, QObject *parent = nullptr); 21 | 22 | // must be called before start! 23 | void addMatch(const QString &str); 24 | void start(); 25 | 26 | Q_SIGNALS: 27 | void finished(); 28 | void error(const QString &msg); 29 | void newDump(const Coredump &dump); 30 | /// Emitted when the current iteration has reached the log end. Roughly meaning that it has loaded all past entries. 31 | void atLogEnd(); 32 | 33 | private: 34 | void processLog(); 35 | void errnoError(const QString &msg, int err); 36 | 37 | const std::unique_ptr context = nullptr; 38 | std::unique_ptr notifier = nullptr; 39 | const QString bootId; 40 | const QString instance; 41 | const QString instanceFilter; // systemd-coredump@%1 instance name 42 | QStringList matches; 43 | }; 44 | -------------------------------------------------------------------------------- /src/parser/backtraceparserlldb.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2014 René J.V. Bertin 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | #include "backtraceparserlldb.h" 7 | #include "backtraceparser_p.h" 8 | 9 | // BEGIN BacktraceParserLldb 10 | 11 | class BacktraceLineLldb : public BacktraceLine 12 | { 13 | public: 14 | BacktraceLineLldb(const QString &line); 15 | }; 16 | 17 | BacktraceLineLldb::BacktraceLineLldb(const QString &line) 18 | : BacktraceLine() 19 | { 20 | d->m_line = line; 21 | // For now we'll have faith that lldb provides useful information, and that it would 22 | // be unwarranted to give it a rating of "MissingEverything". 23 | d->m_rating = Good; 24 | } 25 | 26 | // END BacktraceLineLldb 27 | 28 | // BEGIN BacktraceParserLldb 29 | 30 | BacktraceParserLldb::BacktraceParserLldb(QObject *parent) 31 | : BacktraceParser(parent) 32 | { 33 | } 34 | 35 | BacktraceParserPrivate *BacktraceParserLldb::constructPrivate() const 36 | { 37 | BacktraceParserPrivate *d = BacktraceParser::constructPrivate(); 38 | d->m_usefulness = MayBeUseful; 39 | return d; 40 | } 41 | 42 | void BacktraceParserLldb::newLine(const QString &lineStr) 43 | { 44 | d_ptr->m_linesList.append(BacktraceLineLldb(lineStr)); 45 | } 46 | 47 | // END BacktraceParserLldb 48 | 49 | #include "moc_backtraceparserlldb.cpp" 50 | -------------------------------------------------------------------------------- /LICENSES/BSD-2-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, 7 | this list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 17 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 22 | USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_e: -------------------------------------------------------------------------------- 1 | Thread 1 (Thread 0xb4eda700 (LWP 9067)): 2 | #0 0xa985f5b5 in waitpid () from /lib/libpthread.so.0 3 | #1 0xaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 4 | #2 0xaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 5 | #3 6 | #6 0xffffe430 in __kernel_vsyscall () 7 | #7 0xb5f05990 in raise () from /lib/libc.so.6 8 | #8 0xb5f072c8 in abort () from /lib/libc.so.6 9 | #9 0xb5f47683 in ?? () from /lib/libc.so.6 10 | #10 0xb5f48edb in free () from /lib/libc.so.6 11 | #11 0xb6128ec1 in operator delete(void*) () from /usr/lib/libstdc++.so.6 12 | #12 0x08054227 in ?? () 13 | #13 0xb7c6466a in K3StaticDeleterPrivate::deleteStaticDeleters () at 14 | /usr/src/debug/kdelibs-4.2.0/kde3support/kdecore/k3staticdeleter.cpp:56 15 | #14 0xb6ce9efb in qt_call_post_routines() () from /usr/lib/libQtCore.so.4 16 | #15 0xb6289c18 in QApplication::~QApplication() () from /usr/lib/libQtGui.so.4 17 | #16 0xb7eb019e in ~KApplication (this=0xbfbdb0a0) at 18 | /usr/src/debug/kdelibs-4.2.0/kdeui/kernel/kapplication.cpp:928 19 | #17 0xb7eb7318 in ~KUniqueApplication (this=0xbfbdb0a0) at 20 | /usr/src/debug/kdelibs-4.2.0/kdeui/kernel/kuniqueapplication.cpp:372 21 | #18 0x0805116a in _start () -------------------------------------------------------------------------------- /src/qmlextensions/doctore.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include "systeminformation.h" 9 | 10 | /** 11 | * @brief QML exposure class for DrKonqi. 12 | * Since DrKonqi is not meant for construction but also not a proper singleton it sports 13 | * static functions that we'll want to pull into a context object that actually can serve 14 | * as singleton. This is meant to be a temporary crutch, ideally DrKonqi gets 15 | * refactored to a proper singleton. 16 | */ 17 | class Doctore : public QObject 18 | { 19 | Q_OBJECT 20 | // TODO redo DrKonqi so it can work with QML and convert everything to properties. 21 | public: 22 | using QObject::QObject; 23 | 24 | static Q_INVOKABLE void saveReport(const QString &text); 25 | static Q_INVOKABLE void copyToClipboard(const QString &text); 26 | static Q_INVOKABLE QString appName(); 27 | static Q_INVOKABLE QString kdeBugzillaURL(); 28 | static Q_INVOKABLE QString kdeBugzillaDomain(); 29 | static Q_INVOKABLE bool isSafer(); 30 | static Q_INVOKABLE bool ignoreQuality(); 31 | 32 | private: 33 | Q_PROPERTY(SystemInformation *systemInformation READ systemInformation CONSTANT) 34 | static SystemInformation *systemInformation(); 35 | }; 36 | -------------------------------------------------------------------------------- /src/systemd/org.freedesktop.DBus.Properties.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/bugzilla.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "bugzilla.h" 8 | 9 | namespace Bugzilla 10 | { 11 | QString version(KJob *kjob) 12 | { 13 | const APIJob *job = qobject_cast(kjob); 14 | const QString version = job->object().value(QLatin1String("version")).toString(); 15 | return version; 16 | } 17 | 18 | APIJob *version(const Connection &connection) 19 | { 20 | return connection.get(QStringLiteral("/version")); 21 | } 22 | 23 | LoginDetails login(KJob *kjob) 24 | { 25 | const APIJob *job = qobject_cast(kjob); 26 | const auto obj = job->object(); 27 | const QString token = obj.value(QLatin1String("token")).toString(); 28 | const int id = obj.value(QLatin1String("id")).toInt(-1); 29 | return LoginDetails{id, token}; 30 | } 31 | 32 | APIJob *login(const QString &username, const QString &password, const Connection &connection) 33 | { 34 | Query query; 35 | query.addQueryItem(QStringLiteral("login"), username); 36 | query.addQueryItem(QStringLiteral("password"), password); 37 | query.addQueryItem(QStringLiteral("restrict_login"), QStringLiteral("true")); 38 | return connection.get(QStringLiteral("/login"), query); 39 | } 40 | 41 | } // namespace Bugzilla 42 | -------------------------------------------------------------------------------- /src/org.kde.drkonqi.desktop.cmake: -------------------------------------------------------------------------------- 1 | # KDE Config File 2 | [Desktop Entry] 3 | Type=Application 4 | Exec=${KDE_INSTALL_FULL_LIBEXECDIR}/drkonqi 5 | Name=Dr Konqi 6 | Name[ar]=د.كوينكي 7 | Name[ast]=Dr Konqi 8 | Name[az]=Dr Konqi 9 | Name[bg]=Dr Konqi 10 | Name[ca]=Dr Konqi 11 | Name[ca@valencia]=Dr Konqi 12 | Name[cs]=Dr Konqi 13 | Name[da]=Dr Konqi 14 | Name[de]=Dr Konqi 15 | Name[el]=Dr Konqi 16 | Name[en_GB]=Dr Konqi 17 | Name[eo]=Dr Konqi 18 | Name[es]=Dr Konqi 19 | Name[et]=Dr Konqi 20 | Name[eu]=Dr Konqi 21 | Name[fi]=Dr Konqi 22 | Name[fr]=Dr Konqi 23 | Name[gl]=Dr Konqi 24 | Name[he]=Dr Konqi 25 | Name[hu]=Dr Konqi 26 | Name[ia]=Dr Konqi 27 | Name[id]=Dr Konqi 28 | Name[is]=Dr Konqi 29 | Name[it]=Dr Konqi 30 | Name[ja]=Dr Konqi 31 | Name[ka]=Dr Konqi 32 | Name[ko]=Dr Konqi 33 | Name[lt]=Dr. Konqi 34 | Name[lv]=Dr Konqi 35 | Name[nb]=Dr Konqi 36 | Name[nl]=Dr Konqi 37 | Name[nn]=Dr Konqi 38 | Name[pa]=ਡਾ Konqi 39 | Name[pl]=Dr Konqi 40 | Name[pt]=Dr Konqi 41 | Name[pt_BR]=Dr Konqi 42 | Name[ro]=Dr. Konqi 43 | Name[ru]=Dr Konqi 44 | Name[sa]=डॉ. कोन्की 45 | Name[sk]=Dr Konqi 46 | Name[sl]=Dr Konqi 47 | Name[sr]=Др Конки 48 | Name[sr@ijekavian]=Др Конки 49 | Name[sr@ijekavianlatin]=DrKonqi 50 | Name[sr@latin]=DrKonqi 51 | Name[sv]=Dr Konqi 52 | Name[tg]=Dr Konqi 53 | Name[tr]=Dr. Konqi 54 | Name[uk]=Dr Konqi 55 | Name[vi]=Dr Konqi 56 | Name[zh_CN]=Dr Konqi 57 | Name[zh_TW]=Dr Konqi 58 | Icon=tools-report-bug 59 | NoDisplay=true 60 | -------------------------------------------------------------------------------- /src/qml/BacktracePage.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | import QtQuick 2.15 5 | import QtQuick.Layouts 1.15 6 | import org.kde.kirigami 2.19 as Kirigami 7 | 8 | import org.kde.drkonqi 1.0 9 | 10 | DeveloperPage { 11 | title: i18nc("@title:window", "Fetching the Backtrace (Automatic Crash Information)") 12 | reportActionVisible: false 13 | 14 | onTraceChanged: { 15 | reportInterface.backtrace = trace 16 | } 17 | 18 | footerActions: [ 19 | Kirigami.Action { 20 | enabled: { 21 | if (DrKonqi.ignoreQuality() && state == BacktraceGenerator.Loaded) { 22 | return true; 23 | } 24 | switch (usefulness) { 25 | case BacktraceParser.ReallyUseful: 26 | case BacktraceParser.MayBeUseful: 27 | return true 28 | case BacktraceParser.ProbablyUseless: 29 | case BacktraceParser.Useless: 30 | case BacktraceParser.InvalidUsefulness: 31 | return false 32 | } 33 | } 34 | icon.name: "go-next" 35 | text: i18nc("@action:button", "Next") 36 | onTriggered: pageStack.push("qrc:/ui/BugzillaPage.qml") 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /src/systemd/memoryfence.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | class MemoryFence : public QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | enum class Size { 14 | Spacious, 15 | Some, 16 | Little, 17 | Cramped, 18 | }; 19 | Q_ENUM(Size) 20 | 21 | Q_PROPERTY(Size size MEMBER m_size NOTIFY sizeChanged) 22 | 23 | using QObject::QObject; 24 | 25 | void surroundMe(); 26 | [[nodiscard]] Size size() const; 27 | 28 | Q_SIGNALS: 29 | void loaded(); 30 | void sizeChanged(); 31 | 32 | private: 33 | bool registerDBusTypes(); 34 | void getUnit(); 35 | [[nodiscard]] std::optional freeRAM(); 36 | void getMemory(); 37 | void applyProperties(qulonglong memoryCurrent, qulonglong memoryAvailable); 38 | 39 | QDBusConnection m_bus = QDBusConnection::sessionBus(); 40 | inline const static QString s_service = QStringLiteral("org.freedesktop.systemd1"); 41 | inline const static QString s_manager = QStringLiteral("org.freedesktop.systemd1.Manager"); 42 | inline const static QString s_unit = QStringLiteral("org.freedesktop.systemd1.Unit"); 43 | QString m_unitPath; 44 | std::optional m_memory; 45 | Size m_size = Size::Spacious; 46 | }; 47 | -------------------------------------------------------------------------------- /src/sentry/lib/sentryenvelope.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | // A generic item in the envelope 10 | class SentryItem 11 | { 12 | public: 13 | QByteArray toEnvelopePayload() const; 14 | 15 | QVariantMap m_headers; 16 | QByteArray m_payload; 17 | }; 18 | 19 | // A crash event item in the envelope 20 | class SentryEvent : public SentryItem 21 | { 22 | public: 23 | explicit SentryEvent(const QByteArray &payload); 24 | }; 25 | 26 | // A user feedback item in the envelope 27 | class SentryUserFeedback : public SentryItem 28 | { 29 | public: 30 | explicit SentryUserFeedback(const QByteArray &payload); 31 | }; 32 | 33 | // A blob of data for ingestion in the envelope endpoint of sentry 34 | class SentryEnvelope 35 | { 36 | public: 37 | SentryEnvelope(); 38 | void addItem(const SentryEvent &event); 39 | void addItem(const SentryItem &item); 40 | QByteArray toEnvelope() const; 41 | 42 | void setDSN(const QUrl &dsn); 43 | QString eventId() const; 44 | bool isEmpty() const; 45 | 46 | private: 47 | friend class SentryEnvelopeTest; 48 | // Using map to have an easier time testing this because order will be always the same. 49 | QVariantMap m_headers; 50 | QList m_items; 51 | bool m_hasEvent = false; 52 | }; 53 | -------------------------------------------------------------------------------- /src/sentry/lib/sentryconnection.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #include "sentryconnection.h" 5 | 6 | SentryNetworkReply::SentryNetworkReply(QNetworkReply *reply, QObject *parent) 7 | : SentryReply(parent) 8 | , m_reply(reply) 9 | { 10 | connect(reply, &QNetworkReply::finished, this, &SentryReply::finished); 11 | } 12 | 13 | SentryNetworkReply::~SentryNetworkReply() 14 | { 15 | m_reply->deleteLater(); 16 | } 17 | 18 | QByteArray SentryNetworkReply::readAll() 19 | { 20 | return m_reply->readAll(); 21 | } 22 | 23 | QNetworkReply::NetworkError SentryNetworkReply::error() 24 | { 25 | return m_reply->error(); 26 | } 27 | 28 | QString SentryNetworkReply::errorString() 29 | { 30 | return m_reply->errorString(); 31 | } 32 | 33 | SentryNetworkConnection::SentryNetworkConnection(QObject *parent) 34 | : SentryConnection(parent) 35 | { 36 | m_manager.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy); 37 | } 38 | 39 | SentryReply *SentryNetworkConnection::get(const QNetworkRequest &request) 40 | { 41 | return new SentryNetworkReply(m_manager.get(request), this); 42 | } 43 | 44 | SentryReply *SentryNetworkConnection::post(const QNetworkRequest &request, const QByteArray &data) 45 | { 46 | return new SentryNetworkReply(m_manager.post(request, data), this); 47 | } 48 | 49 | #include "moc_sentryconnection.cpp" 50 | -------------------------------------------------------------------------------- /src/coredump/dumpexcavator/coredumpexcavator.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | 3 | #include "coredumpexcavator.h" 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace Qt::StringLiterals; 10 | 11 | void CoredumpExcavator::excavateFromTo(const QString &coreFile, const std::shared_ptr &coreFileTarget) 12 | { 13 | auto proc = new QProcess(this); 14 | proc->setProcessChannelMode(QProcess::ForwardedErrorChannel); // stdout goes to file 15 | proc->setProgram("coredumpctl"_L1); 16 | proc->setArguments({"dump"_L1, "COREDUMP_FILENAME=%1"_L1.arg(coreFile)}); 17 | qDebug() << "excavating" << proc->arguments(); 18 | connect(proc, &QProcess::readyReadStandardOutput, coreFileTarget.get(), [proc, coreFileTarget] { 19 | auto data = proc->readAllStandardOutput(); 20 | while (data.size() != 0) { 21 | auto written = coreFileTarget->write(data); 22 | data = data.mid(written); 23 | } 24 | }); 25 | connect(proc, &QProcess::finished, this, [this, proc, coreFileTarget](int exitCode, QProcess::ExitStatus exitStatus) mutable { 26 | qDebug() << "Core dump excavation complete" << exitCode << exitStatus; 27 | proc->deleteLater(); 28 | coreFileTarget->flush(); 29 | Q_ASSERT(proc->readAllStandardOutput().size() == 0); 30 | Q_EMIT excavated(exitCode); 31 | }); 32 | proc->start(); 33 | } 34 | -------------------------------------------------------------------------------- /LICENSES/BSD-3-Clause.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) . 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 12 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_usefulfunctions4: -------------------------------------------------------------------------------- 1 | [Current thread is 0 (process 12545)] 2 | 3 | Thread 1 (Thread 0x7fddaac76740 (LWP 12545)): 4 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 5 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 6 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 7 | #3 8 | #6 0x00471f42 in qt_meta_stringdata_QAnimationGroup () from /usr/lib/libQtCore.so.4 9 | #7 0x0087f7fc in __dynamic_cast () from /usr/lib/libstdc++.so.6 10 | #8 0x0521ae26 in KarbonPart::addShape(KoShape*) () from /usr/lib/libkarbonui.so.6 11 | #9 0x0437c9b0 in KoShapeDeleteCommand::undo() () from /usr/lib/libflake.so.6 12 | #10 0x089e4a78 in QUndoCommand::undo (this=0xa70abb0) at util/qundostack.cpp:226 13 | #11 0x0437c562 in KoShapeCreateCommand::undo() () from /usr/lib/libflake.so.6 14 | #12 0x089e6147 in QUndoStack::undo (this=0x9e107d8) at util/qundostack.cpp:659 15 | #13 0x08a0d703 in QUndoStack::qt_metacall (this=0x9e107d8, _c=QMetaObject::InvokeMetaMethod, _id=8, _a=0xbfba6d28) at .moc/release-shared/moc_qundostack.cpp:105 16 | #14 0x011b5482 in KUndoStack::qt_metacall (this=0x9e107d8, _c=QMetaObject::InvokeMetaMethod, _id=12, _a=0xbfba6d28) at ./kundostack.moc:64 17 | #15 0x07398a52 in KoUndoStack::qt_metacall(QMetaObject::Call, int, void**) () from /usr/lib/libkotext.so.6 18 | -------------------------------------------------------------------------------- /src/coredump/cleanup/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace std::chrono_literals; 13 | 14 | int main(int argc, char **argv) 15 | { 16 | if (argc != 2) { 17 | std::cerr << "Need cache path as argument\n"; 18 | return 1; 19 | } 20 | 21 | const std::filesystem::path cachePath = argv[1]; 22 | if (!std::filesystem::exists(cachePath)) { 23 | std::cerr << "Cache path doesn't exist " << cachePath << "\n"; 24 | return 1; 25 | } 26 | 27 | for (const auto &path : std::filesystem::directory_iterator(cachePath)) { 28 | if (path.path().extension() != ".ini") { 29 | continue; 30 | } 31 | try { 32 | const auto lastModified = path.last_write_time(); 33 | const auto now = decltype(lastModified)::clock().now(); 34 | const auto age = now - lastModified; 35 | // Plenty of time so we won't take away the file from underneath drkonqi. 36 | if (age >= std::chrono::weeks(1)) { 37 | std::filesystem::remove(path); 38 | } 39 | } catch (const std::filesystem::filesystem_error &error) { 40 | std::cerr << error.what(); 41 | continue; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/query.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | namespace Bugzilla 12 | { 13 | // Query container. Do not use QUrlQuery. Since bugzilla wants more encoding 14 | // than QUrlQuery would provide by default we always store the input values 15 | // in this Query container. Only once we are actually ready to construct 16 | // the final request is this container converted to a QUrlQuery. 17 | // 18 | // NB: This class intentionally has no QUrlQuery converter function because 19 | // any behavior we need must be implemented in this container, not run 20 | // through QUrlQuery to prevent encoding confusion. 21 | // 22 | // QMap is used as base because order makes test assertions easier to check. 23 | class Query : public QMultiMap 24 | { 25 | public: 26 | using QMultiMap::QMultiMap; 27 | 28 | // Compat rigging so this feels like QUrlQuery and reduces porting 29 | // noise for bugfix backport. 30 | bool hasQueryItem(const QString &key); 31 | void addQueryItem(const QString &key, const QString &value); 32 | 33 | // Don't use this to do anything other than streaming to qDebug. 34 | // The output is not encoded and thus not necessarily a valid URL query. 35 | QString toString() const; 36 | }; 37 | 38 | } // namespace Bugzilla 39 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/field.rep_platform.json: -------------------------------------------------------------------------------- 1 | { 2 | "fields" : [ 3 | { 4 | "display_name" : "Platform", 5 | "id" : 5, 6 | "is_custom" : false, 7 | "is_mandatory" : false, 8 | "is_on_bug_entry" : false, 9 | "name" : "rep_platform", 10 | "type" : 2, 11 | "value_field" : null, 12 | "values" : [ 13 | { 14 | "name" : "Unlisted Binaries", 15 | "sort_key" : 100, 16 | "sortkey" : 100, 17 | "visibility_values" : [] 18 | }, 19 | { 20 | "name" : "Compiled Sources", 21 | "sort_key" : 200, 22 | "sortkey" : 200, 23 | "visibility_values" : [] 24 | }, 25 | { 26 | "name" : "MS Windows", 27 | "sort_key" : 930, 28 | "sortkey" : 930, 29 | "visibility_values" : [] 30 | }, 31 | { 32 | "name" : "unspecified", 33 | "sort_key" : 2300, 34 | "sortkey" : 2300, 35 | "visibility_values" : [] 36 | }, 37 | { 38 | "name" : "Other", 39 | "sort_key" : 2350, 40 | "sortkey" : 2350, 41 | "visibility_values" : [] 42 | } 43 | ], 44 | "visibility_field" : null, 45 | "visibility_values" : [] 46 | } 47 | ] 48 | } 49 | 50 | -------------------------------------------------------------------------------- /src/sentry/lib/sentrydsns.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | class SentryConnection; 12 | 13 | // A SentryDSNContext is KDE-specific data blob. It defaults to a hardcoded builtin variant of the fallthrough DSN. 14 | struct SentryDSNContext { 15 | QString project = u"fallthrough"_qs; 16 | QString key = u"456f53a71a074438bbb786d6add63241"_qs; 17 | QString index = u"11"_qs; 18 | 19 | QUrl dsnUrl() const; 20 | QUrl envelopeUrl() const; 21 | }; 22 | 23 | // Manages retrieval of DSNContexts from the sentry server. 24 | class SentryDSNs : public QObject 25 | { 26 | Q_OBJECT 27 | public: 28 | enum class Cache { Yes, No }; 29 | explicit SentryDSNs(std::shared_ptr connection, Cache cache = Cache::Yes, QObject *parent = nullptr); 30 | void load(); 31 | // The context for the specified applicationName (aka project). This may return the fallthrough DSN if 32 | // no mapping was found. 33 | SentryDSNContext context(const QString &applicationName); 34 | 35 | Q_SIGNALS: 36 | void loaded(); 37 | 38 | private: 39 | void loadData(const QByteArray &data); 40 | std::shared_ptr m_connection; 41 | bool m_loaded = false; 42 | QHash m_applicationContexts; 43 | QString m_cachePath; 44 | bool m_cache; 45 | }; 46 | -------------------------------------------------------------------------------- /src/coredump/cleanup/autotests/cleanuptest.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std::chrono_literals; 16 | namespace fs = std::filesystem; 17 | 18 | class CleanupTest : public QObject 19 | { 20 | Q_OBJECT 21 | private Q_SLOTS: 22 | void testRun() 23 | { 24 | const QString binary = QFINDTESTDATA("drkonqi-coredump-cleanup"); 25 | QTemporaryDir tempDir; 26 | QVERIFY(tempDir.isValid()); 27 | 28 | const fs::path dir = tempDir.path().toStdString(); 29 | const fs::path recentFile = fs::path(dir) / "recent.ini"; 30 | const fs::path oldFile = fs::path(dir) / "old.ini"; 31 | { 32 | std::ofstream output(recentFile); 33 | } 34 | { 35 | std::ofstream output(oldFile); 36 | const auto time = fs::last_write_time(oldFile); 37 | fs::last_write_time(oldFile, time - std::chrono::weeks(2)); 38 | } 39 | 40 | const int exitCode = QProcess::execute(binary, {tempDir.path()}); 41 | QCOMPARE(exitCode, 0); 42 | QVERIFY(fs::exists(recentFile)); 43 | QVERIFY(!fs::exists(oldFile)); 44 | } 45 | }; 46 | 47 | QTEST_GUILESS_MAIN(CleanupTest) 48 | 49 | #include "cleanuptest.moc" 50 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/comments.json: -------------------------------------------------------------------------------- 1 | { 2 | "bugs" : { 3 | "407363" : { 4 | "comments" : [ 5 | { 6 | "attachment_id" : null, 7 | "bug_id" : 407363, 8 | "count" : 0, 9 | "creation_time" : "2019-05-09T13:49:28Z", 10 | "creator" : "sitter@kde.org", 11 | "id" : 1855155, 12 | "is_private" : null, 13 | "tags" : [], 14 | "text" : "uno", 15 | "time" : "2019-05-09T13:49:28Z" 16 | }, 17 | { 18 | "attachment_id" : 119931, 19 | "bug_id" : 407363, 20 | "count" : 1, 21 | "creation_time" : "2019-05-09T13:50:10Z", 22 | "creator" : "sitter@kde.org", 23 | "id" : 1855156, 24 | "is_private" : null, 25 | "tags" : [], 26 | "text" : "due", 27 | "time" : "2019-05-09T13:50:10Z" 28 | }, 29 | { 30 | "attachment_id" : 119932, 31 | "bug_id" : 407363, 32 | "count" : 2, 33 | "creation_time" : "2019-05-09T13:50:28Z", 34 | "creator" : "sitter@kde.org", 35 | "id" : 1855157, 36 | "is_private" : null, 37 | "tags" : [], 38 | "text" : "tre", 39 | "time" : "2019-05-09T13:50:28Z" 40 | } 41 | ] 42 | } 43 | }, 44 | "comments" : {} 45 | } 46 | -------------------------------------------------------------------------------- /src/coredumpbackend.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | SPDX-License-Identifier: GPL-2.0-or-later 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "drkonqibackends.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | class QProcess; 20 | 21 | class CoredumpBackend : public AbstractDrKonqiBackend 22 | { 23 | Q_OBJECT 24 | public: 25 | using AbstractDrKonqiBackend::AbstractDrKonqiBackend; 26 | bool init() override; 27 | void prepareForDebugger() override; 28 | 29 | protected: 30 | CrashedApplication *constructCrashedApplication() override; 31 | DebuggerManager *constructDebuggerManager() override; 32 | 33 | private: 34 | [[nodiscard]] std::optional bootId() const; 35 | [[nodiscard]] std::optional coreTimeSinceEpoch() const; 36 | [[nodiscard]] bool resolveApplicationNotResponding() const; 37 | [[nodiscard]] bool 38 | applicationNotRespondingFileExists(const QString &exe, const QByteArray &bootId, const std::chrono::microseconds &coreTimeSinceEpoch) const; 39 | std::unique_ptr m_crashedApplication; 40 | DebuggerManager *m_debuggerManager; // parented 41 | QHash m_journalEntry; 42 | const QByteArray m_cursor; 43 | std::unique_ptr m_preparationProc; 44 | std::unique_ptr m_excavator; 45 | QJsonDocument m_metadata; 46 | }; 47 | -------------------------------------------------------------------------------- /src/qmlextensions/credentialstore.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-or-later 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "drkonqi.h" 12 | 13 | class CredentialStore : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | using QObject::QObject; 18 | 19 | Q_INVOKABLE void load(); 20 | Q_INVOKABLE void store(); 21 | Q_INVOKABLE void drop(); 22 | 23 | Q_PROPERTY(bool canStore MEMBER m_canStore CONSTANT) 24 | const bool m_canStore = KWallet::Wallet::isEnabled(); 25 | 26 | Q_PROPERTY(QString url MEMBER m_url NOTIFY urlChanged) 27 | QString m_url; 28 | Q_SIGNAL void urlChanged(); 29 | 30 | Q_PROPERTY(QString email MEMBER m_email NOTIFY emailChanged) 31 | QString m_email; 32 | Q_SIGNAL void emailChanged(); 33 | 34 | Q_PROPERTY(QString password MEMBER m_password NOTIFY passwordChanged) 35 | QString m_password; 36 | Q_SIGNAL void passwordChanged(); 37 | 38 | Q_PROPERTY(QWindow *window MEMBER m_window NOTIFY windowChanged) 39 | QWindow *m_window = nullptr; 40 | Q_SIGNAL void windowChanged(); 41 | 42 | private: 43 | void openWallet(); 44 | static bool kWalletEntryExists(const QString &entryName); 45 | 46 | KWallet::Wallet *m_wallet = nullptr; 47 | const QString m_walletEntryName = DrKonqi::isTestingBugzilla() ? QStringLiteral("drkonqi_bugzilla_test_mode") : QStringLiteral("drkonqi_bugzilla"); 48 | bool m_walletWasOpenedBefore = false; 49 | }; 50 | -------------------------------------------------------------------------------- /src/debugpackageinstaller.h: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * debugpackageinstaller.h 3 | * SPDX-FileCopyrightText: 2009 Dario Andres Rodriguez 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * 7 | ******************************************************************/ 8 | #ifndef DEBUGPACKAGEINSTALLER__H 9 | #define DEBUGPACKAGEINSTALLER__H 10 | 11 | #include 12 | #include 13 | 14 | class KProcess; 15 | class QProgressDialog; 16 | 17 | class DebugPackageInstaller : public QObject 18 | { 19 | Q_OBJECT 20 | Q_PROPERTY(bool canInstallDebugPackages READ canInstallDebugPackages CONSTANT) 21 | 22 | public: 23 | enum Results { 24 | ResultInstalled = 0, 25 | ResultError = 1, 26 | ResultSymbolsNotFound = 2, 27 | ResultCanceled = 3, 28 | }; 29 | Q_ENUM(Results) 30 | 31 | explicit DebugPackageInstaller(QObject *parent = nullptr); 32 | bool canInstallDebugPackages() const; 33 | Q_INVOKABLE void setMissingLibraries(const QStringList &); 34 | Q_INVOKABLE void installDebugPackages(); 35 | 36 | private Q_SLOTS: 37 | void processFinished(int, QProcess::ExitStatus); 38 | void progressDialogCanceled(); 39 | 40 | Q_SIGNALS: 41 | void packagesInstalled(); 42 | void error(const QString &); 43 | void canceled(); 44 | 45 | private: 46 | KProcess *m_installerProcess = nullptr; 47 | QProgressDialog *m_progressDialog = nullptr; 48 | QString m_executablePath; 49 | QStringList m_missingLibraries; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/qml/PreviewPage.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | import QtQuick 2.15 5 | import QtQuick.Layouts 1.15 6 | import QtQuick.Controls 2.15 as QQC2 7 | import org.kde.kirigami 2.19 as Kirigami 8 | 9 | import org.kde.drkonqi 1.0 10 | 11 | Kirigami.ScrollablePage { 12 | id: page 13 | 14 | title: i18nc("@title", "Bug Report Preview") 15 | 16 | ColumnLayout { 17 | QQC2.Label { 18 | Layout.fillWidth: true 19 | wrapMode: Text.Wrap 20 | text: xi18nc("@label/rich", "This is a preview of the contents of the report which will be sent.If you want to modify the report, return to the previous pages.") 21 | } 22 | 23 | // FIXME height is off maybe put the scrollview on the area instead of scrolling the page? 24 | QQC2.TextArea { 25 | Layout.fillWidth: true 26 | Layout.fillHeight: true 27 | implicitHeight: contentHeight 28 | readOnly: true 29 | text: reportInterface.generateReportFullText(ReportInterface.DrKonqiStamp.Include, ReportInterface.Backtrace.Complete) 30 | wrapMode: TextEdit.Wrap 31 | 32 | } 33 | } 34 | 35 | footer: FooterActionBar { 36 | actions: [ 37 | Kirigami.Action { 38 | icon.name: "submit" 39 | text: i18nc("@action:button", "Submit") 40 | onTriggered: pageStack.push("qrc:/ui/SendingPage.qml") 41 | } 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/coredump/memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2019-2021 Harald Sitter 4 | */ 5 | 6 | #pragma once 7 | 8 | #include 9 | #include 10 | 11 | namespace std 12 | { 13 | template<> 14 | struct default_delete { 15 | void operator()(sd_journal *ptr) const 16 | { 17 | sd_journal_close(ptr); 18 | } 19 | }; 20 | } // namespace std 21 | 22 | template 23 | struct Expected { 24 | const int ret; // return value of call 25 | const int error; // errno immediately after the call 26 | std::unique_ptr value; // the newly owned object (may be null) 27 | }; 28 | 29 | // Wrapper around C double pointer API of which we must take ownership. 30 | // errno may or may not be 31 | template 32 | Expected> owning_ptr_call(Func func, Args &&...args) 33 | { 34 | T *raw = nullptr; 35 | const int ret = func(&raw, std::forward(args)...); 36 | return {ret, errno, std::unique_ptr(raw)}; 37 | } 38 | 39 | // Same as owning_ptr_call but for (sd_journal *, foo **, ...) API 40 | template 41 | Expected contextual_owning_ptr_call(Func func, sd_journal *context, Deleter deleter = std::default_delete{}, Args &&...args) 42 | { 43 | T *raw = nullptr; 44 | const int ret = func(context, &raw, std::forward(args)...); 45 | return {ret, errno, std::unique_ptr(raw, deleter)}; 46 | } 47 | -------------------------------------------------------------------------------- /src/coredump/gui/DetailsLoader.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022 Harald Sitter 3 | 4 | #include "DetailsLoader.h" 5 | 6 | #include 7 | 8 | void DetailsLoader::setPatient(Patient *patient) 9 | { 10 | m_patient = patient; 11 | if (m_patient) { 12 | load(); 13 | } else { 14 | m_LoaderProcess = nullptr; 15 | } 16 | } 17 | 18 | void DetailsLoader::load() 19 | { 20 | m_LoaderProcess = std::make_unique(); 21 | m_LoaderProcess->setProgram(QStringLiteral("coredumpctl")); 22 | m_LoaderProcess->setArguments(m_patient->coredumpctlArguments(QStringLiteral("info"))); 23 | m_LoaderProcess->setProcessChannelMode(QProcess::MergedChannels); 24 | connect(m_LoaderProcess.get(), &QProcess::finished, this, [this](int exitCode, QProcess::ExitStatus exitStatus) { 25 | switch (exitStatus) { 26 | case QProcess::NormalExit: 27 | if (exitCode == 0) { 28 | Q_EMIT details(QString::fromLocal8Bit(m_LoaderProcess->readAll())); 29 | } else { 30 | Q_EMIT error(i18nc("@info", "Subprocess exited with error: %1", QString::fromLocal8Bit(m_LoaderProcess->readAll()))); 31 | } 32 | break; 33 | case QProcess::CrashExit: 34 | Q_EMIT error(i18nc("@info", "Subprocess crashed. Check your installation.")); 35 | break; 36 | } 37 | m_LoaderProcess.release()->deleteLater(); 38 | }); 39 | m_LoaderProcess->start(); 40 | } 41 | 42 | #include "moc_DetailsLoader.cpp" 43 | -------------------------------------------------------------------------------- /src/core/metadata.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2019-2025 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | // Please note that we have two types of metadata. The incoming kcrash data and the internal drkonqi data. 10 | // The principal difference is that the drkonqi data is more comprehensive and persistent. KCrash data gets 11 | // consumed and deleted once it got turned into a drkonqi variant. 12 | // Generally speaking after coredump-launcher ran the drkonqi data is available, before that only kcrash is available. 13 | namespace Metadata 14 | { 15 | constexpr auto DRKONQI_KEY = QLatin1StringView("drkonqi"); 16 | constexpr auto PICKED_UP_KEY = QLatin1StringView("PickedUp"); 17 | constexpr auto SENTRY_EVENT_ID_KEY = QLatin1StringView("sentryEventId"); 18 | 19 | constexpr auto KCRASH_KEY = QLatin1StringView("kcrash"); 20 | constexpr auto KCRASH_TAGS_KEY = QLatin1StringView("kcrash-tags"); 21 | constexpr auto KCRASH_EXTRA_DATA_KEY = QLatin1StringView("kcrash-extra-data"); 22 | constexpr auto KCRASH_GPU_KEY = QLatin1StringView("kcrash-gpu"); 23 | 24 | [[nodiscard]] QString drkonqiMetadataPath(const QString &exe, const QString &bootId, const QString ×tamp, int pid); 25 | [[nodiscard]] QString resolveKCrashMetadataPath(const QString &exe, const QString &bootId, int pid); 26 | [[nodiscard]] QJsonObject readFromDisk(const QString &drkonqiMetadataPath); 27 | [[nodiscard]] bool isPickedUp(const QJsonObject &metadata); 28 | [[nodiscard]] QStringList metadataArguments(const QVariantHash &kcrash); 29 | } // namespace Metadata 30 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/jsoncommand.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "jsoncommand.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | namespace Bugzilla 15 | { 16 | QByteArray JsonCommand::toJson() const 17 | { 18 | QJsonDocument doc; 19 | doc.setObject(QJsonObject::fromVariantHash(toVariantHash())); 20 | return doc.toJson(); 21 | } 22 | 23 | QVariantHash JsonCommand::toVariantHash() const 24 | { 25 | QVariantHash hash; 26 | 27 | const auto propertyCount = metaObject()->propertyCount(); 28 | for (int i = 0; i < propertyCount; ++i) { 29 | const auto property = metaObject()->property(i); 30 | const auto name = QString::fromLatin1(property.name()); 31 | const auto value = property.read(this); 32 | 33 | if (name == QLatin1String("objectName")) { // Builtin property. 34 | continue; 35 | } 36 | 37 | if (value.isNull()) { 38 | continue; 39 | } 40 | 41 | // If this is a nested representation, serialize it and glue it in. 42 | if (value.canConvert()) { 43 | auto *repValue = value.value(); 44 | hash.insert(name, repValue->toVariantHash()); 45 | continue; 46 | } 47 | 48 | hash.insert(name, value); 49 | } 50 | 51 | return hash; 52 | } 53 | 54 | } // namespace Bugzilla 55 | 56 | #include "moc_jsoncommand.cpp" 57 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/models/bugfield.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "bugfield.h" 8 | 9 | namespace Bugzilla 10 | { 11 | BugField::BugField(const QVariantHash &obj, QObject *parent) 12 | : QObject(parent) 13 | { 14 | registerVariantConverters(); 15 | 16 | for (auto it = obj.constBegin(); it != obj.constEnd(); ++it) { 17 | setProperty(qPrintable(it.key()), it.value()); 18 | } 19 | } 20 | 21 | QList BugField::values() const 22 | { 23 | return m_values; 24 | } 25 | 26 | void BugField::registerVariantConverters() 27 | { 28 | static bool convertersRegistered = false; 29 | if (convertersRegistered) { 30 | return; 31 | } 32 | convertersRegistered = true; 33 | 34 | QMetaType::registerConverter>([](QVariantList v) -> QList { 35 | QList list; 36 | list.reserve(v.size()); 37 | for (const QVariant &variant : std::as_const(v)) { 38 | list.append(new BugFieldValue(variant.toHash())); 39 | } 40 | return list; 41 | }); 42 | } 43 | 44 | BugFieldValue::BugFieldValue(const QVariantHash &obj, QObject *parent) 45 | : QObject(parent) 46 | { 47 | for (auto it = obj.constBegin(); it != obj.constEnd(); ++it) { 48 | setProperty(qPrintable(it.key()), it.value()); 49 | } 50 | } 51 | 52 | QString BugFieldValue::name() const 53 | { 54 | return m_name; 55 | } 56 | 57 | } // namespace Bugzilla 58 | 59 | #include "moc_bugfield.cpp" 60 | -------------------------------------------------------------------------------- /src/coredump/gui/PatientModel.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 2 | // SPDX-FileCopyrightText: 2020-2022 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | 10 | class PatientModel : public QAbstractListModel 11 | { 12 | Q_OBJECT 13 | public: 14 | enum ItemRole { 15 | IndexRole = Qt::UserRole + 1, 16 | ObjectRole, 17 | }; 18 | Q_ENUM(ItemRole) 19 | 20 | explicit PatientModel(const QMetaObject &mo, QObject *parent = nullptr); 21 | 22 | [[nodiscard]] QHash roleNames() const final; 23 | [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const final; 24 | [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; 25 | bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; 26 | [[nodiscard]] int role(const QByteArray &roleName) const; 27 | 28 | // Takes ownership. 29 | void addObject(std::unique_ptr patient); 30 | 31 | Q_PROPERTY(bool ready READ ready WRITE setReady NOTIFY readyChanged) 32 | bool ready() const; 33 | void setReady(bool ready); 34 | Q_SIGNAL void readyChanged(); 35 | 36 | private Q_SLOTS: 37 | void propertyChanged(); 38 | 39 | private: 40 | int initRoleNames(const QMetaObject &mo); 41 | void addDynamicRoleNames(int maxEnumValue, QObject *object); 42 | [[nodiscard]] QMetaMethod propertyChangedMetaMethod() const; 43 | 44 | QList m_objects; 45 | QHash m_roles; 46 | QHash m_objectProperties; 47 | QHash m_signalIndexToProperties; 48 | bool m_ready = false; 49 | }; 50 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(lib_SRCS 2 | apijob.cpp 3 | bugzilla.cpp 4 | connection.cpp 5 | exceptions.cpp 6 | query.cpp 7 | clients/attachmentclient.cpp 8 | clients/bugclient.cpp 9 | clients/bugfieldclient.cpp 10 | clients/commentclient.cpp 11 | clients/clientbase.cpp 12 | clients/productclient.cpp 13 | clients/commands/bugsearch.cpp 14 | clients/commands/bugupdate.cpp 15 | clients/commands/jsoncommand.cpp 16 | clients/commands/newattachment.cpp 17 | clients/commands/newbug.cpp 18 | clients/commands/querycommand.cpp 19 | models/bug.cpp 20 | models/bugfield.cpp 21 | models/comment.cpp 22 | models/logindetails.cpp 23 | models/product.cpp 24 | 25 | apijob.h 26 | bugzilla.h 27 | connection.h 28 | exceptions.h 29 | query.h 30 | clients/attachmentclient.h 31 | clients/bugclient.h 32 | clients/bugfieldclient.h 33 | clients/commentclient.h 34 | clients/clientbase.h 35 | clients/productclient.h 36 | clients/commands/bugsearch.h 37 | clients/commands/bugupdate.h 38 | clients/commands/jsoncommand.h 39 | clients/commands/newattachment.h 40 | clients/commands/newbug.h 41 | clients/commands/querycommand.h 42 | models/bug.h 43 | models/bugfield.h 44 | models/comment.h 45 | models/logindetails.h 46 | models/product.h 47 | ) 48 | 49 | ecm_qt_declare_logging_category( 50 | lib_SRCS 51 | HEADER bugzilla_debug.h 52 | IDENTIFIER BUGZILLA_LOG 53 | CATEGORY_NAME org.kde.drkonqi.bugzilla 54 | DEFAULT_SEVERITY Warning 55 | DESCRIPTION "drkonqi bugzilla" 56 | EXPORT DRKONQI 57 | ) 58 | 59 | add_library(qbugzilla STATIC ${lib_SRCS}) 60 | target_link_libraries(qbugzilla PUBLIC Qt::Core Qt::Network KF6::CoreAddons) 61 | -------------------------------------------------------------------------------- /src/sentry/lib/sentryscope.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2025 Harald Sitter 3 | 4 | #include "sentryscope.h" 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace Qt::StringLiterals; 11 | 12 | SentryScope *SentryScope::instance() 13 | { 14 | static SentryScope scope = [] { 15 | SentryScope scope; 16 | scope.traceId = QUuid::createUuid().toString(QUuid::Id128); 17 | constexpr auto spanIdLength = 16; // per the spec 18 | scope.spanId = QUuid::createUuid().toString(QUuid::Id128).mid(0, spanIdLength); 19 | return scope; 20 | }(); 21 | return &scope; 22 | } 23 | 24 | QHash SentryScope::environment() 25 | { 26 | QHash env; 27 | // These variables are used to transfer context from one process to another; 28 | // in absence of on-the-wire context propagation. 29 | // WARNING: this is our context, not the one of the crashed app. Keep them separate! 30 | // This one is used to tie problems in our preamble to us. 31 | // https://develop.sentry.dev/sdk/telemetry/traces/distributed-tracing/ 32 | // https://develop.sentry.dev/sdk/telemetry/traces/dynamic-sampling-context/#baggage-header 33 | env.insert(u"SENTRY_TRACE"_s, traceId + '-'_L1 + spanId); 34 | env.insert(u"SENTRY_BAGGAGE"_s, [this]() -> QString { 35 | QList baggage; 36 | baggage.append("sentry-trace_id="_L1 + traceId); 37 | baggage.append("sentry-release="_L1 + release); 38 | baggage.append(u"sentry-public_key=d6d53bb0121041dd97f59e29051a1781"_s); // our DSN key 39 | baggage.append(u"sentry-environment=production"_s); 40 | return baggage.join(','_L1); 41 | }()); 42 | return env; 43 | } 44 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/bugclient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "bugclient.h" 8 | 9 | namespace Bugzilla 10 | { 11 | QList BugClient::search(KJob *kjob) const 12 | { 13 | auto *job = qobject_cast(kjob); 14 | 15 | auto ary = job->object().value(QStringLiteral("bugs")).toArray(); 16 | 17 | QList list; 18 | for (auto bug : ary) { 19 | list.append(Bug::Ptr(new Bug(bug.toObject().toVariantHash()))); 20 | } 21 | 22 | return list; 23 | } 24 | 25 | KJob *BugClient::search(const BugSearch &search) 26 | { 27 | return m_connection.get(QStringLiteral("/bug"), search.toQuery()); 28 | } 29 | 30 | qint64 BugClient::create(KJob *kjob) const 31 | { 32 | auto *job = qobject_cast(kjob); 33 | 34 | qint64 ret = job->object().value(QStringLiteral("id")).toInt(-1); 35 | Q_ASSERT(ret != -1); 36 | return ret; 37 | } 38 | 39 | KJob *BugClient::create(const NewBug &bug) 40 | { 41 | return m_connection.post(QStringLiteral("/bug"), bug.toJson()); 42 | } 43 | 44 | qint64 BugClient::update(KJob *kjob) const 45 | { 46 | auto *job = qobject_cast(kjob); 47 | 48 | auto ary = job->object().value(QStringLiteral("bugs")).toArray(); 49 | // It's unclear if this can happen. When the ids would be empty there was 50 | // an error, and when there was an error the API should have sent an error. 51 | Q_ASSERT(ary.size() == 1); 52 | 53 | int value = ary.at(0).toObject().value(QStringLiteral("id")).toInt(-1); 54 | Q_ASSERT(value != -1); 55 | 56 | return value; 57 | } 58 | 59 | KJob *BugClient::update(qint64 bugId, BugUpdate &bug) 60 | { 61 | return m_connection.put(QStringLiteral("/bug/%1").arg(bugId), bug.toJson()); 62 | } 63 | 64 | } // namespace Bugzilla 65 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/clients/commands/querycommand.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2019 Harald Sitter 3 | 4 | SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 5 | */ 6 | 7 | #include "querycommand.h" 8 | #include 9 | #include 10 | 11 | namespace Bugzilla 12 | { 13 | Query QueryCommand::toQuery() const 14 | { 15 | Query query; 16 | return expandQuery(query, QSet()); 17 | } 18 | 19 | Query QueryCommand::expandQuery(Query &query, const QSet &seen) const 20 | { 21 | const auto propertyCount = metaObject()->propertyCount(); 22 | for (int i = 0; i < propertyCount; ++i) { 23 | const auto property = metaObject()->property(i); 24 | const auto name = QString::fromLatin1(property.name()); 25 | const auto value = property.read(this); 26 | 27 | if (query.hasQueryItem(name) || seen.contains(name) || name == QLatin1String("objectName")) { 28 | // The element was manually set or builtin property. 29 | continue; 30 | } 31 | 32 | if (value.toLongLong() < 0) { 33 | // Invalid value => member was not set! 34 | // This does generally also work for all integers, ulonglong of 35 | // course being the only one that can cause trouble. 36 | continue; 37 | } 38 | 39 | // Lists must be serialized manually. They could have a number of representations. 40 | Q_ASSERT_X(value.type() != QVariant::StringList, Q_FUNC_INFO, qPrintable(QStringLiteral("Trying to auto serialize string list %1").arg(name))); 41 | 42 | // Either can't serialize or not set. 43 | if (value.toString().isEmpty()) { 44 | continue; 45 | } 46 | 47 | query.addQueryItem(name, property.read(this).toString()); 48 | } 49 | 50 | return query; 51 | } 52 | 53 | } // namespace Bugzilla 54 | -------------------------------------------------------------------------------- /src/coredump/coredump.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 3 | SPDX-FileCopyrightText: 2019-2022 Harald Sitter 4 | */ 5 | 6 | #include "coredump.h" 7 | 8 | #include 9 | 10 | using namespace Qt::StringLiterals; 11 | 12 | Coredump::Coredump(QByteArray cursor, EntriesHash data) 13 | : m_cursor(std::move(cursor)) 14 | , m_rawData(std::move(data)) 15 | , uid(m_rawData[QByteArrayLiteral("COREDUMP_UID")].toInt()) 16 | , pid(m_rawData[QByteArrayLiteral("COREDUMP_PID")].toInt()) 17 | , exe(QString::fromLocal8Bit(m_rawData[QByteArrayLiteral("COREDUMP_EXE")])) 18 | , filename(QString::fromLocal8Bit(m_rawData[keyFilename()])) 19 | , systemd_unit(QString::fromLocal8Bit(m_rawData[QByteArrayLiteral("_SYSTEMD_UNIT")])) 20 | , bootId(QString::fromUtf8(m_rawData["_BOOT_ID"_ba])) 21 | , timestamp(QString::fromUtf8(m_rawData["COREDUMP_TIMESTAMP"_ba])) 22 | { 23 | if (!m_rawData.contains(keyCursor())) { 24 | m_rawData[keyCursor()] = m_cursor; // so we can easily access it in launcher & drkonqi 25 | } 26 | } 27 | 28 | Coredump::Coredump(const QJsonDocument &document) 29 | : Coredump(QByteArray() /* not from journal, has no cursor */, documentToHash(document)) 30 | { 31 | } 32 | 33 | QByteArray Coredump::keyFilename() 34 | { 35 | return QByteArrayLiteral("COREDUMP_FILENAME"); 36 | } 37 | 38 | Coredump::EntriesHash Coredump::documentToHash(const QJsonDocument &document) 39 | { 40 | const QVariantMap variantMap = document.toVariant().toMap(); 41 | EntriesHash hash; 42 | for (auto it = variantMap.cbegin(); it != variantMap.cend(); ++it) { 43 | hash.insert(it.key().toUtf8(), it->value()); 44 | } 45 | return hash; 46 | } 47 | 48 | QByteArray Coredump::keyPickup() 49 | { 50 | return "_DRKONQI_PICKUP"_ba; 51 | } 52 | 53 | QByteArray Coredump::keyCursor() 54 | { 55 | return "_DRKONQI_SD_CURSOR"_ba; 56 | } 57 | -------------------------------------------------------------------------------- /src/bugzillaintegration/libbugzilla/autotests/data/bugs.unresolved.json: -------------------------------------------------------------------------------- 1 | { 2 | "bugs" : [ 3 | { 4 | "alias" : [], 5 | "assigned_to" : "dragon-bugs@dragonplayer.org", 6 | "assigned_to_detail" : { 7 | "email" : "dragon-bugs@dragonplayer.org", 8 | "id" : 94747, 9 | "name" : "dragon-bugs@dragonplayer.org", 10 | "real_name" : "Dragon Player Mailing List" 11 | }, 12 | "blocks" : [], 13 | "cc" : [], 14 | "cc_detail" : [], 15 | "cf_commitlink" : "", 16 | "cf_versionfixedin" : "", 17 | "classification" : "Unclassified", 18 | "component" : "general", 19 | "creation_time" : "2008-06-16T21:29:47Z", 20 | "creator" : "flabbergasted@gmx.de", 21 | "creator_detail" : { 22 | "email" : "flabbergasted@gmx.de", 23 | "id" : 80677, 24 | "name" : "flabbergasted@gmx.de", 25 | "real_name" : "Tobias" 26 | }, 27 | "deadline" : null, 28 | "depends_on" : [], 29 | "dupe_of" : null, 30 | "flags" : [], 31 | "groups" : [], 32 | "id" : 164250, 33 | "is_cc_accessible" : null, 34 | "is_confirmed" : null, 35 | "is_creator_accessible" : null, 36 | "is_open" : null, 37 | "keywords" : [], 38 | "last_change_time" : "2008-06-17T18:36:52Z", 39 | "op_sys" : "Linux", 40 | "platform" : "Ubuntu Packages", 41 | "priority" : "NOR", 42 | "product" : "dragonplayer", 43 | "qa_contact" : "", 44 | "resolution" : "", 45 | "see_also" : [], 46 | "severity" : "wishlist", 47 | "status" : "UNCONFIRMED", 48 | "summary" : "Save position of DVDs", 49 | "target_milestone" : "---", 50 | "url" : "", 51 | "version" : "2.0.x", 52 | "whiteboard" : "" 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /src/backtracewidget.h: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * backtracewidget.h 3 | * SPDX-FileCopyrightText: 2009 Dario Andres Rodriguez 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * 7 | ******************************************************************/ 8 | 9 | #ifndef BACKTRACEWIDGET__H 10 | #define BACKTRACEWIDGET__H 11 | 12 | #include 13 | 14 | #include "debugpackageinstaller.h" 15 | #include "ui_backtracewidget.h" 16 | 17 | namespace KSyntaxHighlighting 18 | { 19 | class SyntaxHighlighter; 20 | } 21 | class BacktraceRatingWidget; 22 | class BacktraceGenerator; 23 | 24 | class BacktraceWidget : public QWidget 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | explicit BacktraceWidget(BacktraceGenerator *generator, QWidget *parent = nullptr, bool showToggleBacktrace = false); 30 | 31 | bool canInstallDebugPackages() const; 32 | 33 | public Q_SLOTS: 34 | void generateBacktrace(); 35 | void highlightExtraDetailsLabel(bool highlight); 36 | void focusImproveBacktraceButton(); 37 | 38 | void toggleBacktrace(bool show); 39 | void extraDetailsLinkActivated(QString link); 40 | 41 | Q_SIGNALS: 42 | void stateChanged(); 43 | 44 | private: 45 | BacktraceGenerator *m_btGenerator = nullptr; 46 | Ui::Form ui; 47 | BacktraceRatingWidget *m_backtraceRatingWidget = nullptr; 48 | KSyntaxHighlighting::SyntaxHighlighter *m_highlighter = nullptr; 49 | DebugPackageInstaller *m_debugPackageInstaller = nullptr; 50 | 51 | void setAsLoading(); 52 | 53 | private Q_SLOTS: 54 | void loadData(); 55 | void backtraceNewLine(const QString &); 56 | 57 | void regenerateBacktrace(); 58 | 59 | void saveClicked(); 60 | void copyClicked(); 61 | 62 | void anotherDebuggerRunning(); 63 | 64 | void installDebugPackages(); 65 | void debugPackageError(const QString &); 66 | void debugPackageCanceled(); 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/coredump/processor/drkonqi-coredump-processor@.service.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | # SPDX-FileCopyrightText: 2021 Harald Sitter 3 | 4 | [Unit] 5 | Description=Pass systemd-coredump journal entries to relevant user for potential DrKonqi handling 6 | 7 | [Service] 8 | ExecStart=@KDE_INSTALL_FULL_LIBEXECDIR@/drkonqi-coredump-processor --boot-id %b --instance %i 9 | # If it doesn't manage to find its relevant coredump in a short while it never will. 10 | # This job is instantiated when systemd-coredump@ starts. They run roughly at the 11 | # same time. Any slow down will at most occur on dumping in of itself. 12 | # This limit is already incredibly lenient. 13 | RuntimeMaxSec=5 minutes 14 | Nice=10 15 | OOMScoreAdjust=500 16 | # Mountain of confinement options. We kind of need to run as root to write to all the 17 | # the various sockets, but we don't need a whole lot of capabilities. 18 | # Largely based on systemd-coredump@'s own configuration. 19 | NoNewPrivileges=yes 20 | CapabilityBoundingSet=~CAP_SYS_PTRACE CAP_SYS_ADMIN CAP_NET_ADMIN CAP_KILL CAP_SYS_CHROOT CAP_BLOCK_SUSPEND CAP_LINUX_IMMUTABLE 21 | SystemCallFilter=@system-service 22 | SystemCallFilter=~@privileged @resources 23 | ProtectClock=yes 24 | IPAddressDeny=any 25 | LockPersonality=yes 26 | MemoryDenyWriteExecute=yes 27 | PrivateDevices=yes 28 | PrivateNetwork=yes 29 | PrivateTmp=yes 30 | ProtectControlGroups=yes 31 | ProtectHostname=yes 32 | ProtectKernelModules=yes 33 | ProtectKernelTunables=yes 34 | ProtectKernelLogs=yes 35 | ProtectSystem=strict 36 | RestrictAddressFamilies=AF_UNIX 37 | RestrictNamespaces=yes 38 | RestrictRealtime=yes 39 | RestrictSUIDSGID=yes 40 | SystemCallArchitectures=native 41 | SystemCallErrorNumber=EPERM 42 | 43 | [Install] 44 | # NOTE: This service must be enabled (symlinked) manually - systemctl enable will not do! 45 | # https://github.com/systemd/systemd/issues/19437 46 | WantedBy=systemd-coredump@.service 47 | -------------------------------------------------------------------------------- /src/sentry/lib/sentryconnection.h: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2023 Harald Sitter 3 | 4 | #pragma once 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | // Represents a NetworkReply. Implemented for QNetwork, and testing mocks. 13 | class SentryReply : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | virtual QByteArray readAll() = 0; 18 | virtual QNetworkReply::NetworkError error() = 0; 19 | virtual QString errorString() = 0; 20 | 21 | Q_SIGNALS: 22 | void finished(); 23 | 24 | protected: 25 | using QObject::QObject; 26 | }; 27 | 28 | // Represents a NetworkAccessManager. Implemented for QNetwork, and testing mocks. 29 | class SentryConnection : public QObject 30 | { 31 | Q_OBJECT 32 | public: 33 | using QObject::QObject; 34 | virtual SentryReply *get(const QNetworkRequest &request) = 0; 35 | virtual SentryReply *post(const QNetworkRequest &request, const QByteArray &data) = 0; 36 | }; 37 | 38 | // A QNetworkReply based reply implementation. 39 | class SentryNetworkReply final : public SentryReply 40 | { 41 | public: 42 | explicit SentryNetworkReply(QNetworkReply *reply, QObject *parent = nullptr); 43 | ~SentryNetworkReply() final; 44 | Q_DISABLE_COPY_MOVE(SentryNetworkReply) 45 | 46 | QByteArray readAll() final; 47 | QNetworkReply::NetworkError error() final; 48 | QString errorString() final; 49 | 50 | private: 51 | QNetworkReply *m_reply; 52 | }; 53 | 54 | // A QNetworkAccessManager based connection implementation. 55 | class SentryNetworkConnection final : public SentryConnection 56 | { 57 | public: 58 | explicit SentryNetworkConnection(QObject *parent = nullptr); 59 | 60 | SentryReply *get(const QNetworkRequest &request) final; 61 | SentryReply *post(const QNetworkRequest &request, const QByteArray &data) final; 62 | 63 | private: 64 | QNetworkAccessManager m_manager; 65 | }; 66 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_bug200993: -------------------------------------------------------------------------------- 1 | Thread 1 (Thread 0x7fe4756407f0 (LWP 9487)): 2 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 3 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 4 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 5 | #3 6 | #6 0xffffe430 in __kernel_vsyscall () 7 | #7 0xb617b990 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 8 | #8 0xb617d2c8 in *__GI_abort () at abort.c:88 9 | #9 0xb617478e in *__GI___assert_fail (assertion=0xb3391928 "!s_refcnt", file=0xb3391720 "/local/svn/kde/trunk/KDE/kdelibs/khtml/khtml_global.cpp", line=258, 10 | function=0xb3391ac0 "static void KHTMLGlobal::finalCheck()") at assert.c:78 11 | #10 0xb2f947d3 in KHTMLGlobal::finalCheck () at /local/svn/kde/trunk/KDE/kdelibs/khtml/khtml_global.cpp:258 12 | #11 0xb418554d in ~KHTMLFactory (this=0x825fcd0, __in_chrg=) at /local/svn/kde/trunk/KDE/kdelibs/khtml/khtml_factory.cpp:35 13 | #12 0xb70e8e86 in QObjectCleanupHandler::clear (this=0x825d9e0) at /local/git/Qt/qt/src/corelib/kernel/qobjectcleanuphandler.cpp:140 14 | #13 0xb70e8ed0 in ~QObjectCleanupHandler (this=0x825d9e0, __in_chrg=) at /local/git/Qt/qt/src/corelib/kernel/qobjectcleanuphandler.cpp:86 15 | #14 0xb741fc21 in destroy () at /local/svn/kde/trunk/KDE/kdelibs/kdecore/util/kpluginfactory.cpp:29 16 | #15 0xb72e154b in ~KCleanUpGlobalStatic (this=0xb74d15d4, __in_chrg=) at /local/svn/kde/trunk/KDE/kdelibs/kdecore/kernel/kglobal.h:62 17 | #16 0xb617e9b1 in *__GI_exit (status=0) at exit.c:75 18 | #17 0xb616770d in __libc_start_main (main=0x804877e
, argc=1, ubp_av=0xbf97df04, init=0x80487b0 <__libc_csu_init>, fini=0x80487a0 <__libc_csu_fini>, rtld_fini=0xb7f70220 <_dl_fini>, 19 | stack_end=0xbf97defc) at libc-start.c:252 20 | #18 0x080486d1 in _start () at ../sysdeps/i386/elf/start.S:119 21 | -------------------------------------------------------------------------------- /src/sentry/lib/sentrypaths.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2022-2023 Harald Sitter 3 | 4 | #include "sentrypaths.h" 5 | 6 | #include 7 | #include 8 | 9 | using namespace Qt::StringLiterals; 10 | 11 | namespace 12 | { 13 | QString cacheDir(const QString &subdir) 14 | { 15 | const auto dir = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation); 16 | Q_ASSERT(!dir.isEmpty()); 17 | if (dir.isEmpty()) { 18 | return {}; 19 | } 20 | return dir + "/drkonqi/"_L1 + subdir; 21 | } 22 | } // namespace 23 | 24 | namespace SentryPaths 25 | { 26 | 27 | QString payloadsDir() 28 | { 29 | static const auto payloadsDir = []() { 30 | const auto dir = cacheDir(u"/sentry-envelopes"_qs); 31 | QDir().mkpath(dir); 32 | return dir; 33 | }(); 34 | return payloadsDir; 35 | } 36 | QString sentPayloadsDir() 37 | { 38 | static const auto sentPayloadsDir = []() { 39 | const auto dir = cacheDir(u"/sentry-sent-envelopes"_qs); 40 | QDir().mkpath(dir); 41 | return dir; 42 | }(); 43 | return sentPayloadsDir; 44 | } 45 | 46 | QString payloadPath(const QString &eventId) 47 | { 48 | const auto dir = payloadsDir(); 49 | if (dir.isEmpty()) { 50 | return {}; 51 | } 52 | // Note includes timestamp to facilitate multiple writes of the same event. We need this to support both 53 | // pre-submission feedback as well as post-submission feedback while also avoiding race conditions between 54 | // the postbox writing envelopes, and the postman picking them up. 55 | return dir + '/'_L1 + eventId + '.'_L1 + QString::number(std::chrono::system_clock::now().time_since_epoch().count()); 56 | } 57 | 58 | QString sentPayloadPath(const QString &eventId) 59 | { 60 | const auto dir = sentPayloadsDir(); 61 | if (dir.isEmpty()) { 62 | return {}; 63 | } 64 | return dir + '/'_L1 + eventId; 65 | } 66 | } // namespace SentryPaths 67 | -------------------------------------------------------------------------------- /src/qml/WelcomePage.qml: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 2 | // SPDX-FileCopyrightText: 2021-2022 Harald Sitter 3 | 4 | import QtQuick 2.15 5 | import QtQuick.Layouts 1.15 6 | import QtQuick.Controls 2.15 as QQC2 7 | import org.kde.kirigami 2.19 as Kirigami 8 | 9 | import org.kde.drkonqi 1.0 10 | 11 | Kirigami.ScrollablePage { 12 | id: page 13 | 14 | title: i18nc("@title:window", "Reporting Assistant") 15 | 16 | ColumnLayout { 17 | QQC2.Label { 18 | Layout.fillWidth: true 19 | text: xi18nc("@info/rich", `This assistant will analyze the crash information and guide you through the bug reporting process.`) 20 | wrapMode: Text.Wrap 21 | } 22 | RowLayout { 23 | Kirigami.Icon { 24 | implicitWidth: Kirigami.Units.iconSizes.large 25 | implicitHeight: implicitWidth 26 | source: "dialog-warning" 27 | } 28 | 29 | QQC2.Label { 30 | Layout.fillWidth: true 31 | text: xi18nc("@info/rich note before starting the bug reporting process", 32 | `Since communication between you and the developers is required for effective debugging, 33 | to continue reporting this bug it is required for you to agree that developers may contact you. 34 | Feel free to close this dialog if you do not wish to accept this.`) 35 | wrapMode: Text.Wrap 36 | } 37 | } 38 | // FIXME: maybe even disable i18n for the rest of the dialog seeing as one must be proficient enough in english 39 | } 40 | 41 | footer: FooterActionBar { 42 | actions: [ 43 | Kirigami.Action { 44 | icon.name: "document-sign" 45 | text: i18nc("@action:button", "I Agree to be Contacted") 46 | onTriggered: { 47 | pageStack.push("qrc:/ui/ContextPage.qml") 48 | } 49 | } 50 | ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Testing.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # Exec 7 | 8 | Drkonqi also doesn't technically require a process to actually crash, you can 9 | simply run it manually on any old pid. Do note that in most cases you only need 10 | to define the pid, however not giving certain cmdline options can change 11 | behavior somewhat drastically (e.g. kdeinit vs. notkdeinit behaves radically 12 | different as far as process name detection goes) 13 | 14 | example command to doctor a running dolphin: 15 | 16 | ``` 17 | DRKONQI_HTTP_DELAY_MS=1000 \ 18 | DRKONQI_TEST_MODE=1 \ 19 | DRKONQI_IGNORE_QUALITY=1 \ 20 | DRKONQI_KDE_BUGZILLA_URL="https://bugstest.kde.org/" \ 21 | bin/drkonqi \ 22 | -platform xcb -display :0 --appname org_kde_powerdevil --apppath /usr/lib/x86_64-linux-gnu/libexec --signal 11 --pid `pidof dolphin` --startupid 0 --restarted --bugaddress submit@bugs.kde.org --dialog 23 | ``` 24 | 25 | # Environment 26 | 27 | The following environment variables may be used to test drkonqi with actual reports. 28 | 29 | - DRKONQI_TEST_MODE: influences everything and the kitchen sink, influences 30 | UI behavior to streamline test-reporting and also forces bugstest.kde.org 31 | use so test reports do not clutter up the live bugzilla 32 | - DRKONQI_IGNORE_QUALITY: ignores quality constraints (e.g. backtrace scores 33 | are always assumed perfect) 34 | - DRKONQI_KDE_BUGZILLA_URL: changes the kde bugzilla url (only really useful 35 | to set this to bugstest.kde.org - must end with slash) 36 | - DRKONQI_HTTP_DELAY_MS: introduce a delay on every single API request 37 | (simulates slow connection) 38 | 39 | # Backends 40 | 41 | Drkonqi has a number of backends that may be used. Backends are stacked by 42 | order of preference, backends in the directory of the binary are most preferred. 43 | This means that you can dump debuggers/internal/ into your build's bin/ 44 | directory and override for example gdb. This essentially allows you to replace 45 | the gdb debugger with a `cat` of a fixture file to not have to trace live 46 | processes at all. 47 | -------------------------------------------------------------------------------- /src/drkonqibackends.h: -------------------------------------------------------------------------------- 1 | /* 2 | SPDX-FileCopyrightText: 2009 George Kiagiadakis 3 | SPDX-FileCopyrightText: 2021 Harald Sitter 4 | 5 | SPDX-License-Identifier: GPL-2.0-or-later 6 | */ 7 | #ifndef DRKONQIBACKENDS_H 8 | #define DRKONQIBACKENDS_H 9 | 10 | #include 11 | 12 | class CrashedApplication; 13 | class DebuggerManager; 14 | 15 | class AbstractDrKonqiBackend : public QObject 16 | { 17 | Q_OBJECT 18 | public: 19 | using QObject::QObject; 20 | virtual ~AbstractDrKonqiBackend(); 21 | virtual bool init(); 22 | virtual void prepareForDebugger(); 23 | 24 | inline CrashedApplication *crashedApplication() const 25 | { 26 | return m_crashedApplication; 27 | } 28 | 29 | inline DebuggerManager *debuggerManager() const 30 | { 31 | return m_debuggerManager; 32 | } 33 | 34 | static QString metadataPath(); 35 | 36 | Q_SIGNALS: 37 | void preparedForDebugger(); 38 | void failedToPrepare(); 39 | 40 | protected: 41 | virtual CrashedApplication *constructCrashedApplication() = 0; 42 | virtual DebuggerManager *constructDebuggerManager() = 0; 43 | 44 | private: 45 | CrashedApplication *m_crashedApplication = nullptr; 46 | DebuggerManager *m_debuggerManager = nullptr; 47 | }; 48 | 49 | class KCrashBackend : public AbstractDrKonqiBackend 50 | { 51 | Q_OBJECT 52 | public: 53 | using AbstractDrKonqiBackend::AbstractDrKonqiBackend; 54 | ~KCrashBackend() override; 55 | 56 | bool init() override; 57 | 58 | protected: 59 | CrashedApplication *constructCrashedApplication() override; 60 | DebuggerManager *constructDebuggerManager() override; 61 | 62 | private Q_SLOTS: 63 | void stopAttachedProcess(); 64 | void continueAttachedProcess(); 65 | void onDebuggerStarting(); 66 | void onDebuggerFinished(); 67 | 68 | private: 69 | static void emergencySaveFunction(int signal); 70 | static qint64 s_pid; // for use by the emergencySaveFunction 71 | 72 | enum State { ProcessRunning, ProcessStopped, DebuggerRunning }; 73 | State m_state = ProcessRunning; 74 | }; 75 | 76 | #endif // DRKONQIBACKENDS_H 77 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_usefulfunctions: -------------------------------------------------------------------------------- 1 | [Current thread is 0 (process 12545)] 2 | 3 | Thread 1 (Thread 0x7fddaac76740 (LWP 12545)): 4 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 5 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 6 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 7 | #3 8 | #6 0x00000000 in ?? () 9 | #6 QBasicAtomicInt::operator!= (this=0xa6bf968, result=...) at /usr/include/qt4/QtCore/qbasicatomic.h:69 10 | #7 QList >::detach (this=0xa6bf968, result=...) at /usr/include/qt4/QtCore/qlist.h:119 11 | #8 QList >::append (this=0xa6bf968, result=...) at /usr/include/qt4/QtCore/qlist.h:424 12 | #9 QList >::operator<< (this=0xa6bf968, result=...) at /usr/include/qt4/QtCore/qlist.h:304 13 | #10 SqlQueryMaker::handleTracks (this=0xa6bf968, result=...) at /build/buildd/amarok-2.2.0/src/collection/sqlcollection/SqlQueryMaker.cpp:975 14 | #11 0xb443a084 in SqlQueryMaker::handleResult (this=0xa6bf968, result=...) at /build/buildd/amarok-2.2.0/src/collection/sqlcollection/SqlQueryMaker.cpp:671 15 | #12 0xb443c32b in SqlWorkerThread::run() () from /usr/lib/kde4/amarok_collection-mysqlecollection.so 16 | #13 0x02b2137d in ThreadWeaver::JobRunHelper::runTheJob (this=0xb299a26c, th=0x9aeb9b8, job=0xa6c0e20) at ../../../threadweaver/Weaver/Job.cpp:106 17 | #14 0x02b216e1 in ThreadWeaver::Job::execute (this=0xa6c0e20, th=0x9aeb9b8) at ../../../threadweaver/Weaver/Job.cpp:135 18 | #15 0x02b2038a in ThreadWeaver::ThreadRunHelper::run (this=0xb299a2f4, parent=0x992bf40, th=0x9aeb9b8) at ../../../threadweaver/Weaver/Thread.cpp:95 19 | #16 0x02b209db in ThreadWeaver::Thread::run (this=0x9aeb9b8) at ../../../threadweaver/Weaver/Thread.cpp:142 20 | #17 0x089bfe32 in QThreadPrivate::start (arg=0x9aeb9b8) at thread/qthread_unix.cpp:188 21 | #18 0x06e2d80e in start_thread () from /lib/tls/i686/cmov/libpthread.so.0 22 | #19 0x086be8de in clone () from /lib/tls/i686/cmov/libc.so.6 23 | -------------------------------------------------------------------------------- /src/statuswidget.h: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * statuswidget.h 3 | * SPDX-FileCopyrightText: 2009, 2010 Dario Andres Rodriguez 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * 7 | ******************************************************************/ 8 | #ifndef STATUSWIDGET__H 9 | #define STATUSWIDGET__H 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | class WrapLabel; 17 | class KBusyIndicatorWidget; 18 | class QHideEvent; 19 | 20 | class StatusWidget : public QStackedWidget 21 | { 22 | Q_OBJECT 23 | public: 24 | explicit StatusWidget(QWidget *parent = nullptr); 25 | 26 | void setBusy(const QString &); 27 | void setIdle(const QString &); 28 | 29 | void addCustomStatusWidget(QWidget *); 30 | 31 | private: 32 | void showEvent(QShowEvent *) override; 33 | void hideEvent(QHideEvent *) override; 34 | 35 | void setBusyCursor(); 36 | void setIdleCursor(); 37 | 38 | WrapLabel *m_statusLabel; 39 | 40 | KBusyIndicatorWidget *m_throbberWidget; 41 | WrapLabel *m_busyLabel; 42 | 43 | QWidget *m_statusPage; 44 | QWidget *m_busyPage; 45 | 46 | int m_cursorStackCount; 47 | bool m_busy; 48 | }; 49 | 50 | // Dummy class to avoid a QLabel+wordWrap height bug 51 | class WrapLabel : public QLabel 52 | { 53 | Q_OBJECT 54 | public: 55 | explicit WrapLabel(QWidget *parent = nullptr) 56 | : QLabel(parent) 57 | { 58 | setWordWrap(true); 59 | } 60 | 61 | void setText(const QString &text) 62 | { 63 | QLabel::setText(text); 64 | adjustHeight(); 65 | } 66 | 67 | bool event(QEvent *e) override 68 | { 69 | if (e->type() == QEvent::ApplicationFontChange || e->type() == QEvent::Resize) { 70 | adjustHeight(); 71 | } 72 | return QLabel::event(e); 73 | } 74 | 75 | private: 76 | void adjustHeight() 77 | { 78 | QTextDocument document(text()); 79 | document.setTextWidth(width()); 80 | setMaximumHeight(document.size().height()); 81 | } 82 | }; 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/tests/backtraceparsertest/backtraceparsertest_data/test_c: -------------------------------------------------------------------------------- 1 | 0x00007fd2f44f4001 in nanosleep () from /lib/libc.so.6 2 | [Current thread is 0 (LWP 4414)] 3 | 4 | Thread 3 (Thread 0x7fd2c7276950 (LWP 4425)): 5 | #0 0x00007fd2f451bc66 in poll () from /lib/libc.so.6 6 | #1 0x00007fd2f6bbbc61 in net::DownloadThread::waitForSocketReady () from /usr/lib/libbtcore.so.7 7 | #2 0x00007fd2f6bbbccc in net::DownloadThread::update () from /usr/lib/libbtcore.so.7 8 | #3 0x00007fd2f6bbc6d9 in net::NetworkThread::run () from /usr/lib/libbtcore.so.7 9 | #4 0x00007fd2fba5ad79 in ?? () from /usr/lib/libQtCore.so.4 10 | #5 0x00007fd2fb7e9fc7 in start_thread () from /lib/libpthread.so.0 11 | #6 0x00007fd2f45245dd in clone () from /lib/libc.so.6 12 | #7 0x0000000000000000 in ?? () 13 | 14 | Thread 2 (Thread 0x7fd2c6a75950 (LWP 4426)): 15 | #0 0x00007fd2fb7edd69 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0 16 | #1 0x00007fd2fba5bb09 in QWaitCondition::wait () from /usr/lib/libQtCore.so.4 17 | #2 0x00007fd2f6bbb7a4 in net::UploadThread::update () from /usr/lib/libbtcore.so.7 18 | #3 0x00007fd2f6bbc6d9 in net::NetworkThread::run () from /usr/lib/libbtcore.so.7 19 | #4 0x00007fd2fba5ad79 in ?? () from /usr/lib/libQtCore.so.4 20 | #5 0x00007fd2fb7e9fc7 in start_thread () from /lib/libpthread.so.0 21 | #6 0x00007fd2f45245dd in clone () from /lib/libc.so.6 22 | #7 0x0000000000000000 in ?? () 23 | 24 | Thread 1 (Thread 0x7fd2fc35f750 (LWP 4414)): 25 | #0 0x00007fdda985f5b5 in waitpid () from /lib/libpthread.so.0 26 | #1 0x00007fddaa7e660d in KCrash::startDirectly (argv=0x7fffb2db2800) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:436 27 | #2 0x00007fddaa7e7581 in KCrash::defaultCrashHandler (sig=11) at /home/gkiagia/kde/src/KDE/kdelibs/kdeui/util/kcrash.cpp:340 28 | #3 29 | #5 0x00007fd2f44d272b in memcpy () from /lib/libc.so.6 30 | #6 0x00007fd2f6bd4add in bt::WebSeed::handleData () from /usr/lib/libbtcore.so.7 31 | #7 0x00007fd2f6bd5703 in bt::WebSeed::update () from /usr/lib/libbtcore.so.7 32 | #8 0x00007fd2f6bdc120 in bt::Downloader::update () from /usr/lib/libbtcore.so.7 33 | #9 0x00007fd2f6bfee5b in bt::TorrentControl::update () from /usr/lib/libbtcore.so.7 34 | #10 0x000000000042996a in _start () 35 | 36 | -------------------------------------------------------------------------------- /src/backtraceratingwidget.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************* 2 | * backtraceratingwidget.cpp 3 | * SPDX-FileCopyrightText: 2009 Dario Andres Rodriguez 4 | * 5 | * SPDX-License-Identifier: GPL-2.0-or-later 6 | * 7 | ******************************************************************/ 8 | 9 | #include "backtraceratingwidget.h" 10 | 11 | #include 12 | #include 13 | 14 | BacktraceRatingWidget::BacktraceRatingWidget(QWidget *parent) 15 | : QWidget(parent) 16 | , m_state(BacktraceGenerator::NotLoaded) 17 | { 18 | setMinimumSize(105, 24); 19 | 20 | m_starPixmap = QIcon::fromTheme(QStringLiteral("rating")).pixmap(QSize(22, 22)); 21 | m_disabledStarPixmap = QIcon::fromTheme(QStringLiteral("rating")).pixmap(QSize(22, 22), QIcon::Disabled); 22 | m_errorPixmap = QIcon::fromTheme(QStringLiteral("dialog-error")).pixmap(QSize(22, 22)); 23 | } 24 | 25 | void BacktraceRatingWidget::setUsefulness(BacktraceParser::Usefulness usefulness) 26 | { 27 | switch (usefulness) { 28 | case BacktraceParser::ReallyUseful: 29 | m_numStars = 3; 30 | break; 31 | case BacktraceParser::MayBeUseful: 32 | m_numStars = 2; 33 | break; 34 | case BacktraceParser::ProbablyUseless: 35 | m_numStars = 1; 36 | break; 37 | case BacktraceParser::Useless: 38 | case BacktraceParser::InvalidUsefulness: 39 | m_numStars = 0; 40 | break; 41 | } 42 | update(); 43 | } 44 | 45 | void BacktraceRatingWidget::paintEvent(QPaintEvent *event) 46 | { 47 | Q_UNUSED(event); 48 | 49 | QPainter p(this); 50 | p.drawPixmap(QPoint(30, 1), m_numStars >= 1 ? m_starPixmap : m_disabledStarPixmap); 51 | p.drawPixmap(QPoint(55, 1), m_numStars >= 2 ? m_starPixmap : m_disabledStarPixmap); 52 | p.drawPixmap(QPoint(80, 1), m_numStars >= 3 ? m_starPixmap : m_disabledStarPixmap); 53 | 54 | switch (m_state) { 55 | case BacktraceGenerator::Failed: 56 | case BacktraceGenerator::FailedToStart: { 57 | p.drawPixmap(QPoint(0, 1), m_errorPixmap); 58 | break; 59 | } 60 | default: 61 | break; 62 | } 63 | 64 | p.end(); 65 | } 66 | 67 | #include "moc_backtraceratingwidget.cpp" 68 | -------------------------------------------------------------------------------- /src/tests/integration/data/bugs: -------------------------------------------------------------------------------- 1 | { 2 | "bugs" : [ 3 | { 4 | "alias" : [], 5 | "assigned_to" : "dolphin-bugs-null@kde.org", 6 | "assigned_to_detail" : { 7 | "email" : "dolphin-bugs-null@kde.org", 8 | "id" : 168329, 9 | "name" : "dolphin-bugs-null@kde.org", 10 | "real_name" : "Dolphin Bug Assignee" 11 | }, 12 | "blocks" : [], 13 | "cc" : [ 14 | "elvis.angelaccio@kde.org" 15 | ], 16 | "cc_detail" : [ 17 | { 18 | "email" : "elvis.angelaccio@kde.org", 19 | "id" : 183313, 20 | "name" : "elvis.angelaccio@kde.org", 21 | "real_name" : "Elvis Angelaccio" 22 | } 23 | ], 24 | "cf_commitlink" : "", 25 | "cf_versionfixedin" : "", 26 | "classification" : "Unclassified", 27 | "component" : "general", 28 | "creation_time" : "2017-01-16T21:57:27Z", 29 | "creator" : "j.peter0123@gmail.com", 30 | "creator_detail" : { 31 | "email" : "j.peter0123@gmail.com", 32 | "id" : 199606, 33 | "name" : "j.peter0123@gmail.com", 34 | "real_name" : "Jung Péter" 35 | }, 36 | "deadline" : null, 37 | "depends_on" : [], 38 | "dupe_of" : null, 39 | "flags" : [], 40 | "groups" : [], 41 | "id" : 375161, 42 | "is_cc_accessible" : null, 43 | "is_confirmed" : null, 44 | "is_creator_accessible" : null, 45 | "is_open" : null, 46 | "keywords" : [ 47 | "drkonqi" 48 | ], 49 | "last_change_time" : "2017-10-28T09:58:26Z", 50 | "op_sys" : "Linux", 51 | "platform" : "openSUSE RPMs", 52 | "priority" : "NOR", 53 | "product" : "dolphin", 54 | "qa_contact" : "", 55 | "resolution" : "", 56 | "see_also" : [], 57 | "severity" : "crash", 58 | "status" : "UNCONFIRMED", 59 | "summary" : "Dolphin crash, copy from Samba share", 60 | "target_milestone" : "---", 61 | "url" : "", 62 | "version" : "16.08.2", 63 | "whiteboard" : "" 64 | } 65 | ], 66 | "faults" : [] 67 | } 68 | --------------------------------------------------------------------------------