Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/design/coreclr/botr/xplat-minidump-generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Environment variables supported:
- `DOTNET_DbgEnableMiniDump`: if set to "1", enables this core dump generation. The default is NOT to generate a dump.
- `DOTNET_DbgMiniDumpType`: See below. Default is "2" MiniDumpWithPrivateReadWriteMemory.
- `DOTNET_DbgMiniDumpName`: if set, use as the template to create the dump path and file name. See "Dump name formatting" for how the dump name can be formatted. The default is _/tmp/coredump.%p_.
- `DOTNET_DbgCreateDumpToolPath`: if set, specifies the full path to the createdump tool. This allows you to use a custom or external createdump binary instead of the one that ships with the runtime. The path must point to an existing regular file. This is useful in scenarios where createdump is not shipped with the runtime and you need to "bring your own" dump generation tool.
- `DOTNET_CreateDumpDiagnostics`: if set to "1", enables the _createdump_ utilities diagnostic messages (TRACE macro).
- `DOTNET_CreateDumpVerboseDiagnostics`: if set to "1", enables the _createdump_ utilities verbose diagnostic messages (TRACE_VERBOSE macro).
- `DOTNET_CreateDumpLogToFile`: if set, it is the path of the file to write the _createdump_ diagnostic messages.
Expand Down Expand Up @@ -115,6 +116,18 @@ As of .NET 5.0, the following subset of the core pattern (see [core](https://man
%h Hostname return by gethostname().
%t Time of dump, expressed as seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC).

**Using a custom createdump tool**

In scenarios where the runtime does not ship with the createdump tool, you can specify a custom path using the `DOTNET_DbgCreateDumpToolPath` environment variable:

```bash
export DOTNET_DbgEnableMiniDump=1
export DOTNET_DbgCreateDumpToolPath=/path/to/custom/createdump
./myapp
```

This allows you to "bring your own" dump generation tool. The specified path must point to an existing executable file.

# Testing #

The test plan is to modify the SOS tests in the (still) private debuggertests repo to trigger and use the core minidumps generated. Debugging managed core dumps on Linux is not supported by _mdbg_ at this time until we have a ELF core dump reader so only the SOS tests (which use _lldb_ on Linux) will be modified.
67 changes: 43 additions & 24 deletions src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,35 +597,54 @@ PalCreateDumpInitialize()
}

// Build the createdump program path for the command line
Dl_info info;
if (dladdr((void*)&PalCreateDumpInitialize, &info) == 0)
char* program = nullptr;

// Check if user provided a custom path to createdump tool
if (RhConfig::Environment::TryGetStringValue("DbgCreateDumpToolPath", &program))
{
return false;
}
const char* DumpGeneratorName = "createdump";
int programLen = strlen(info.dli_fname) + strlen(DumpGeneratorName) + 1;
char* program = (char*)malloc(programLen);
if (program == nullptr)
{
return false;
}
strncpy(program, info.dli_fname, programLen);
char *last = strrchr(program, '/');
if (last != nullptr)
{
*(last + 1) = '\0';
// Validate that the specified path exists and is a regular file
struct stat fileData;
if (stat(program, &fileData) == -1 || !S_ISREG(fileData.st_mode))
{
fprintf(stderr, "DOTNET_DbgCreateDumpToolPath is set but the specified createdump binary does not exist or is not a regular file: %s\n", program);
free(program);
return true;
}
}
else
{
program[0] = '\0';
}
strncat(program, DumpGeneratorName, programLen);
// Default behavior: derive path from current library location
Dl_info info;
if (dladdr((void*)&PalCreateDumpInitialize, &info) == 0)
{
return false;
}
const char* DumpGeneratorName = "createdump";
int programLen = strlen(info.dli_fname) + strlen(DumpGeneratorName) + 1;
program = (char*)malloc(programLen);
if (program == nullptr)
{
return false;
}
strncpy(program, info.dli_fname, programLen);
char *last = strrchr(program, '/');
if (last != nullptr)
{
*(last + 1) = '\0';
}
else
{
program[0] = '\0';
}
strncat(program, DumpGeneratorName, programLen);

struct stat fileData;
if (stat(program, &fileData) == -1 || !S_ISREG(fileData.st_mode))
{
fprintf(stderr, "DOTNET_DbgEnableMiniDump is set and the createdump binary does not exist: %s\n", program);
return true;
struct stat fileData;
if (stat(program, &fileData) == -1 || !S_ISREG(fileData.st_mode))
{
fprintf(stderr, "DOTNET_DbgEnableMiniDump is set and the createdump binary does not exist: %s\n", program);
free(program);
return true;
}
}
g_szCreateDumpPath = program;

Expand Down
Loading