| 1 | // Licensed to the .NET Foundation under one or more agreements. |
| 2 | // The .NET Foundation licenses this file to you under the MIT license. |
| 3 | // See the LICENSE file in the project root for more information. |
| 4 | |
| 5 | #include "createdump.h" |
| 6 | |
| 7 | const char* g_help = "createdump [options] pid\n" |
| 8 | "-f, --name - dump path and file name. The pid can be placed in the name with %d. The default is '/tmp/coredump.%d'\n" |
| 9 | "-n, --normal - create minidump.\n" |
| 10 | "-h, --withheap - create minidump with heap (default).\n" |
| 11 | "-t, --triage - create triage minidump.\n" |
| 12 | "-u, --full - create full core dump.\n" |
| 13 | "-d, --diag - enable diagnostic messages.\n" ; |
| 14 | |
| 15 | bool CreateDumpCommon(const char* dumpPathTemplate, MINIDUMP_TYPE minidumpType, CrashInfo* crashInfo); |
| 16 | |
| 17 | // |
| 18 | // Main entry point |
| 19 | // |
| 20 | int __cdecl main(const int argc, const char* argv[]) |
| 21 | { |
| 22 | MINIDUMP_TYPE minidumpType = MiniDumpWithPrivateReadWriteMemory; |
| 23 | #ifdef ANDROID |
| 24 | const char* dumpPathTemplate = "/data/local/tmp/coredump.%d" ; |
| 25 | #else |
| 26 | const char* dumpPathTemplate = "/tmp/coredump.%d" ; |
| 27 | #endif |
| 28 | pid_t pid = 0; |
| 29 | |
| 30 | int exitCode = PAL_InitializeDLL(); |
| 31 | if (exitCode != 0) |
| 32 | { |
| 33 | fprintf(stderr, "PAL initialization FAILED %d\n" , exitCode); |
| 34 | return exitCode; |
| 35 | } |
| 36 | |
| 37 | // Parse the command line options and target pid |
| 38 | argv++; |
| 39 | for (int i = 1; i < argc; i++) |
| 40 | { |
| 41 | if (*argv != nullptr) |
| 42 | { |
| 43 | if ((strcmp(*argv, "-f" ) == 0) || (strcmp(*argv, "--name" ) == 0)) |
| 44 | { |
| 45 | dumpPathTemplate = *++argv; |
| 46 | } |
| 47 | else if ((strcmp(*argv, "-n" ) == 0) || (strcmp(*argv, "--normal" ) == 0)) |
| 48 | { |
| 49 | minidumpType = MiniDumpNormal; |
| 50 | } |
| 51 | else if ((strcmp(*argv, "-h" ) == 0) || (strcmp(*argv, "--withheap" ) == 0)) |
| 52 | { |
| 53 | minidumpType = MiniDumpWithPrivateReadWriteMemory; |
| 54 | } |
| 55 | else if ((strcmp(*argv, "-t" ) == 0) || (strcmp(*argv, "--triage" ) == 0)) |
| 56 | { |
| 57 | minidumpType = MiniDumpFilterTriage; |
| 58 | } |
| 59 | else if ((strcmp(*argv, "-u" ) == 0) || (strcmp(*argv, "--full" ) == 0)) |
| 60 | { |
| 61 | minidumpType = MiniDumpWithFullMemory; |
| 62 | } |
| 63 | else if ((strcmp(*argv, "-d" ) == 0) || (strcmp(*argv, "--diag" ) == 0)) |
| 64 | { |
| 65 | g_diagnostics = true; |
| 66 | } |
| 67 | else { |
| 68 | pid = atoll(*argv); |
| 69 | } |
| 70 | argv++; |
| 71 | } |
| 72 | } |
| 73 | if (pid != 0) |
| 74 | { |
| 75 | ReleaseHolder<DumpDataTarget> dataTarget = new DumpDataTarget(pid); |
| 76 | ReleaseHolder<CrashInfo> crashInfo = new CrashInfo(pid, dataTarget, false); |
| 77 | |
| 78 | // The initialize the data target's ReadVirtual support (opens /proc/$pid/mem) |
| 79 | if (dataTarget->Initialize(crashInfo)) |
| 80 | { |
| 81 | if (!CreateDumpCommon(dumpPathTemplate, minidumpType, crashInfo)) |
| 82 | { |
| 83 | exitCode = -1; |
| 84 | } |
| 85 | } |
| 86 | else |
| 87 | { |
| 88 | exitCode = -1; |
| 89 | } |
| 90 | } |
| 91 | else |
| 92 | { |
| 93 | // if no pid or invalid command line option |
| 94 | fprintf(stderr, "%s" , g_help); |
| 95 | exitCode = -1; |
| 96 | } |
| 97 | PAL_TerminateEx(exitCode); |
| 98 | return exitCode; |
| 99 | } |
| 100 | |