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