Changeset View
Changeset View
Standalone View
Standalone View
src/kcrash.cpp
Show All 17 Lines | |||||
18 | * | 18 | * | ||
19 | * You should have received a copy of the GNU Library General Public License | 19 | * You should have received a copy of the GNU Library General Public License | ||
20 | * along with this library; see the file COPYING.LIB. If not, write to | 20 | * along with this library; see the file COPYING.LIB. If not, write to | ||
21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
22 | * Boston, MA 02110-1301, USA. | 22 | * Boston, MA 02110-1301, USA. | ||
23 | */ | 23 | */ | ||
24 | 24 | | |||
25 | #include "kcrash.h" | 25 | #include "kcrash.h" | ||
26 | #include "kcrashhandlerplugin.h" | ||||
26 | 27 | | |||
27 | #include <config-kcrash.h> | 28 | #include <config-kcrash.h> | ||
28 | 29 | | |||
29 | #include <string.h> | 30 | #include <string.h> | ||
30 | #include <signal.h> | 31 | #include <signal.h> | ||
31 | #include <stdio.h> | 32 | #include <stdio.h> | ||
32 | #include <stdlib.h> | 33 | #include <stdlib.h> | ||
33 | 34 | | |||
34 | #include <qplatformdefs.h> | 35 | #include <qplatformdefs.h> | ||
35 | #ifndef Q_OS_WIN | 36 | #ifndef Q_OS_WIN | ||
36 | #include <sys/resource.h> | 37 | #include <sys/resource.h> | ||
37 | #include <sys/un.h> | 38 | #include <sys/un.h> | ||
38 | #include <errno.h> | 39 | #include <errno.h> | ||
39 | #else | 40 | #else | ||
40 | #include <qt_windows.h> | 41 | #include <qt_windows.h> | ||
41 | #endif | 42 | #endif | ||
42 | #ifdef Q_OS_LINUX | 43 | #ifdef Q_OS_LINUX | ||
43 | #include <sys/prctl.h> | 44 | #include <sys/prctl.h> | ||
44 | #endif | 45 | #endif | ||
45 | 46 | | |||
46 | #include <kaboutdata.h> | | |||
47 | #include <kstartupinfo.h> | | |||
48 | | ||||
49 | #include <QDebug> | 47 | #include <QDebug> | ||
50 | #include <QGuiApplication> | 48 | #include <QGuiApplication> | ||
51 | #include <QtCore/QFileInfo> | 49 | #include <QtCore/QFileInfo> | ||
52 | #include <QtCore/QDir> | 50 | #include <QtCore/QDir> | ||
53 | #include <QStandardPaths> | 51 | #include <QStandardPaths> | ||
52 | #include <QPluginLoader> | ||||
53 | #include <QDirIterator> | ||||
54 | #include <QThread> | 54 | #include <QThread> | ||
55 | #include <QLibraryInfo> | 55 | #include <QLibraryInfo> | ||
56 | 56 | | |||
57 | #include <QLoggingCategory> | 57 | #include <QLoggingCategory> | ||
58 | Q_DECLARE_LOGGING_CATEGORY(LOG_KCRASH) | 58 | Q_DECLARE_LOGGING_CATEGORY(LOG_KCRASH) | ||
59 | 59 | | |||
60 | // logging category for this framework, default: log stuff >= info | 60 | // logging category for this framework, default: log stuff >= info | ||
61 | Q_LOGGING_CATEGORY(LOG_KCRASH, "org.kde.kcrash", QtInfoMsg) | 61 | Q_LOGGING_CATEGORY(LOG_KCRASH, "org.kde.kcrash", QtInfoMsg) | ||
▲ Show 20 Lines • Show All 366 Lines • ▼ Show 20 Line(s) | 427 | #endif | |||
428 | 428 | | |||
429 | if (s_launchDrKonqi != 1) { | 429 | if (s_launchDrKonqi != 1) { | ||
430 | setCrashHandler(nullptr); | 430 | setCrashHandler(nullptr); | ||
431 | #if !defined(Q_OS_WIN) | 431 | #if !defined(Q_OS_WIN) | ||
432 | raise(sig); // dump core, or whatever is the default action for this signal. | 432 | raise(sig); // dump core, or whatever is the default action for this signal. | ||
433 | #endif | 433 | #endif | ||
434 | return; | 434 | return; | ||
435 | } | 435 | } | ||
436 | 436 | | |||
437 | const char *argv[29]; // don't forget to update this | 437 | QVarLengthArray<const char*, 50> argv; | ||
anthonyfieroni: You have a comment to follow :) | |||||
You can't use QVector here. We're crashing, likely due to corrupted memory, the whole point of this code is to NOT do any memory allocation. You should revert to const char*[], or use something that always allocates on the stack (e.g. QVarLengthArray, if preallocated to be big enough). dfaure: You can't use QVector here. We're crashing, likely due to corrupted memory, the whole point of… | |||||
Yes... that makes sense. But then possibly worse than that is the use of QMap. Will rethink the approach. apol: Yes... that makes sense.
But then possibly worse than that is the use of QMap.
Will rethink… | |||||
438 | int i = 0; | 438 | argv << s_drkonqiPath; | ||
439 | | ||||
440 | // argument 0 has to be drkonqi | | |||
441 | argv[i++] = s_drkonqiPath; | | |||
442 | 439 | | |||
443 | const QByteArray platformName = QGuiApplication::platformName().toUtf8(); | 440 | const QByteArray platformName = QGuiApplication::platformName().toUtf8(); | ||
444 | if (!platformName.isEmpty()) { | 441 | if (!platformName.isEmpty()) { | ||
445 | argv[i++] = "-platform"; | 442 | argv << "-platform" << platformName.constData(); | ||
446 | argv[i++] = platformName.constData(); | | |||
447 | } | | |||
448 | | ||||
449 | #if HAVE_X11 | | |||
450 | if (platformName == QByteArrayLiteral("xcb")) { | | |||
451 | // start up on the correct display | | |||
452 | argv[i++] = "-display"; | | |||
453 | if (QX11Info::display()) { | | |||
454 | argv[i++] = XDisplayString(QX11Info::display()); | | |||
455 | } else { | | |||
456 | argv[i++] = getenv("DISPLAY"); | | |||
457 | } | 443 | } | ||
458 | } | | |||
459 | #endif | | |||
460 | 444 | | |||
461 | argv[i++] = "--appname"; | 445 | argv << "--appname" << (s_appName ? s_appName : "<unknown>"); | ||
462 | argv[i++] = s_appName ? s_appName : "<unknown>"; | | |||
463 | 446 | | |||
464 | if (loadedByKdeinit) { | 447 | if (loadedByKdeinit) { | ||
465 | argv[i++] = "--kdeinit"; | 448 | argv << "--kdeinit"; | ||
466 | } | 449 | } | ||
467 | 450 | | |||
468 | // only add apppath if it's not NULL | 451 | // only add apppath if it's not NULL | ||
469 | if (s_appPath && *s_appPath) { | 452 | if (s_appPath && *s_appPath) { | ||
470 | argv[i++] = "--apppath"; | 453 | argv << "--apppath" << s_appPath; | ||
471 | argv[i++] = s_appPath; | | |||
472 | } | 454 | } | ||
473 | 455 | | |||
474 | // signal number -- will never be NULL | 456 | // signal number -- will never be NULL | ||
475 | char sigtxt[ 10 ]; | 457 | char sigtxt[ 10 ]; | ||
476 | sprintf(sigtxt, "%d", sig); | 458 | sprintf(sigtxt, "%d", sig); | ||
477 | argv[i++] = "--signal"; | 459 | argv << "--signal" << sigtxt; | ||
478 | argv[i++] = sigtxt; | | |||
479 | 460 | | |||
480 | char pidtxt[ 20 ]; | 461 | char pidtxt[ 20 ]; | ||
481 | sprintf(pidtxt, "%lld", QCoreApplication::applicationPid()); | 462 | sprintf(pidtxt, "%lld", QCoreApplication::applicationPid()); | ||
482 | argv[i++] = "--pid"; | 463 | argv << "--pid" << pidtxt; | ||
483 | argv[i++] = pidtxt; | | |||
484 | | ||||
485 | const KAboutData *about = KAboutData::applicationDataPointer(); | | |||
486 | if (about) { | | |||
487 | if (about->internalVersion()) { | | |||
488 | argv[i++] = "--appversion"; | | |||
489 | argv[i++] = about->internalVersion(); | | |||
490 | } | | |||
491 | | ||||
492 | if (about->internalProgramName()) { | | |||
493 | argv[i++] = "--programname"; | | |||
494 | argv[i++] = about->internalProgramName(); | | |||
495 | } | | |||
496 | | ||||
497 | if (about->internalBugAddress()) { | | |||
498 | argv[i++] = "--bugaddress"; | | |||
499 | argv[i++] = about->internalBugAddress(); | | |||
500 | } | | |||
501 | } | | |||
502 | 464 | | |||
503 | // make sure the constData() pointer remains valid when we call startProcess by making a copy | 465 | QDirIterator dirIt(QStringLiteral(KCRASH_PLUGIN_INSTALL_DIR), QDir::Files); | ||
504 | QByteArray startupId = KStartupInfo::startupId(); | 466 | QMap<QByteArray, QByteArray> args; | ||
505 | if (!startupId.isNull()) { | 467 | for (; dirIt.hasNext();) { | ||
506 | argv[i++] = "--startupid"; | 468 | dirIt.next(); | ||
507 | argv[i++] = startupId.constData(); | 469 | QPluginLoader loader(dirIt.filePath()); | ||
470 | KCrashHandlerPlugin *plugin = qobject_cast<KCrashHandlerPlugin*>(loader.instance()); | ||||
471 | plugin->extractHandlerArgs(argv); | ||||
508 | } | 472 | } | ||
509 | 473 | | |||
510 | if (s_flags & SaferDialog) { | 474 | if (s_flags & SaferDialog) { | ||
511 | argv[i++] = "--safer"; | 475 | argv << "--safer"; | ||
512 | } | 476 | } | ||
513 | 477 | | |||
514 | if ((s_flags & AutoRestart) && s_autoRestartCommand) { | 478 | if ((s_flags & AutoRestart) && s_autoRestartCommand) { | ||
515 | argv[i++] = "--restarted"; //tell drkonqi if the app has been restarted | 479 | argv << "--restarted"; //tell drkonqi if the app has been restarted | ||
516 | } | 480 | } | ||
517 | 481 | | |||
518 | #if defined(Q_OS_WIN) | 482 | #if defined(Q_OS_WIN) | ||
519 | char threadId[8] = { 0 }; | 483 | char threadId[8] = { 0 }; | ||
520 | sprintf(threadId, "%d", GetCurrentThreadId()); | 484 | sprintf(threadId, "%d", GetCurrentThreadId()); | ||
521 | argv[i++] = "--thread"; | 485 | argv << "--thread" << threadId; | ||
522 | argv[i++] = threadId; | | |||
523 | #endif | 486 | #endif | ||
524 | 487 | | |||
525 | // NULL terminated list | 488 | // NULL terminated list | ||
526 | argv[i] = nullptr; | 489 | argv << nullptr; | ||
527 | 490 | | |||
528 | startProcess(i, argv, true); | 491 | startProcess(argv.size()-1, argv.data(), true); | ||
529 | } | 492 | } | ||
530 | 493 | | |||
531 | if (crashRecursionCounter < 4) { | 494 | if (crashRecursionCounter < 4) { | ||
532 | fprintf(stderr, "Unable to start Dr. Konqi\n"); | 495 | fprintf(stderr, "Unable to start Dr. Konqi\n"); | ||
533 | } | 496 | } | ||
534 | 497 | | |||
535 | if (s_coreConfig->isProcess()) { | 498 | if (s_coreConfig->isProcess()) { | ||
536 | fprintf(stderr, "Re-raising signal for core dump handling.\n"); | 499 | fprintf(stderr, "Re-raising signal for core dump handling.\n"); | ||
▲ Show 20 Lines • Show All 295 Lines • Show Last 20 Lines |
You have a comment to follow :)