Skip to content
Open
Show file tree
Hide file tree
Changes from all 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`: **(NativeAOT only)** if set, specifies the directory path where the createdump tool is located. The runtime will look for the createdump binary in this directory. This is useful in scenarios where createdump is not shipped with the runtime and you need to "bring your own" dump generation tool. This environment variable is only supported in NativeAOT applications and ignored otherwise.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be documented int the official docs: t https://learn.microsoft.com/en-us/dotnet/core/diagnostics/collect-dumps-crash

(We may want to do delete the env variable documentation here and just link to the official docs.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The official docs should mention that this works in .NET 11+ only

- `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 (NativeAOT only)**

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

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

The runtime will look for the `createdump` binary in the specified directory. This allows you to "bring your own" dump generation tool. Note that this environment variable is only supported in NativeAOT applications and ignored otherwise.

# 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.
62 changes: 45 additions & 17 deletions src/coreclr/nativeaot/Runtime/unix/PalCreateDump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,29 +604,57 @@ PalCreateDumpInitialize()
}

// Build the createdump program path for the command line
Dl_info info;
if (dladdr((void*)&PalCreateDumpInitialize, &info) == 0)
{
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)
char* dumpToolPath = nullptr;
char* program = nullptr;

// Check if user provided a custom path to createdump tool directory
if (RhConfig::Environment::TryGetStringValue("DbgCreateDumpToolPath", &dumpToolPath))
{
*(last + 1) = '\0';
// Use the provided directory path and concatenate with "createdump"
size_t dumpToolPathLen = strlen(dumpToolPath);
bool needsSlash = dumpToolPathLen > 0 && dumpToolPath[dumpToolPathLen - 1] != '/';
int programLen = dumpToolPathLen + (needsSlash ? 1 : 0) + strlen(DumpGeneratorName) + 1;
program = (char*)malloc(programLen);
if (program == nullptr)
{
free(dumpToolPath);
return false;
}
strncpy(program, dumpToolPath, programLen);
if (needsSlash)
{
strncat(program, "/", programLen);
}
strncat(program, DumpGeneratorName, programLen);
free(dumpToolPath);
}
else
{
program[0] = '\0';
// Default behavior: derive path from current library location
Dl_info info;
if (dladdr((void*)&PalCreateDumpInitialize, &info) == 0)
{
return false;
}
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);
}
strncat(program, DumpGeneratorName, programLen);

g_szCreateDumpPath = program;

Expand Down