Skip to content

Commit 9c88787

Browse files
author
Mike McLaughlin
committed
Add special diagnostic info memory region
Contains the exception record address for Native AOT crashes.
1 parent 9885d95 commit 9c88787

File tree

8 files changed

+93
-19
lines changed

8 files changed

+93
-19
lines changed

src/coreclr/debug/createdump/crashinfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ CrashInfo::GatherCrashInfo(DumpType dumpType)
194194
{
195195
return false;
196196
}
197+
// Add the special (fake) memory region for the special diagnostics info
198+
MemoryRegion special(PF_R, SpecialDiagInfoAddress, SpecialDiagInfoAddress + PAGE_SIZE);
199+
m_memoryRegions.insert(special);
197200
#ifdef __APPLE__
198201
InitializeOtherMappings();
199202
#endif

src/coreclr/debug/createdump/createdump.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ typedef struct
137137
#include "crashreportwriter.h"
138138
#include "dumpwriter.h"
139139
#include "runtimeinfo.h"
140+
#include "specialdiaginfo.h"
140141
#endif
141142

142143
#ifndef MAX_LONGPATH

src/coreclr/debug/createdump/dumpwriter.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,27 @@ DumpWriter::OpenDump(const char* dumpFileName)
3232
return true;
3333
}
3434

35+
bool
36+
DumpWriter::WriteDiagInfo(int size)
37+
{
38+
// Write the diagnostics info header
39+
SpecialDiagInfoHeader header = {
40+
{SPECIAL_DIAGINFO_SIGNATURE},
41+
SPECIAL_DIAGINFO_VERSION,
42+
m_crashInfo.ExceptionRecord()
43+
};
44+
if (!WriteData(&header, sizeof(header))) {
45+
return false;
46+
}
47+
int alignment = size - sizeof(header);
48+
assert(alignment < sizeof(m_tempBuffer));
49+
memset(m_tempBuffer, 0, alignment);
50+
if (!WriteData(m_tempBuffer, alignment)) {
51+
return false;
52+
}
53+
return true;
54+
}
55+
3556
// Write all of the given buffer, handling short writes and EINTR. Return true iff successful.
3657
bool
3758
DumpWriter::WriteData(int fd, const void* buffer, size_t length)

src/coreclr/debug/createdump/dumpwriterelf.cpp

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -176,28 +176,37 @@ DumpWriter::WriteDump()
176176
size_t size = memoryRegion.Size();
177177
total += size;
178178

179-
while (size > 0)
179+
if (address == SpecialDiagInfoAddress)
180180
{
181-
size_t bytesToRead = std::min(size, sizeof(m_tempBuffer));
182-
size_t read = 0;
183-
184-
if (!m_crashInfo.ReadProcessMemory((void*)address, m_tempBuffer, bytesToRead, &read)) {
185-
printf_error("Error reading memory at %" PRIA PRIx64 " size %08zx FAILED %s (%d)\n", address, bytesToRead, strerror(g_readProcessMemoryErrno), g_readProcessMemoryErrno);
181+
if (!WriteDiagInfo(size)) {
186182
return false;
187183
}
188-
189-
// This can happen if the target process dies before createdump is finished
190-
if (read == 0) {
191-
printf_error("Error reading memory at %" PRIA PRIx64 " size %08zx returned 0 bytes read: %s (%d)\n", address, bytesToRead, strerror(g_readProcessMemoryErrno), g_readProcessMemoryErrno);
192-
return false;
193-
}
194-
195-
if (!WriteData(m_tempBuffer, read)) {
196-
return false;
184+
}
185+
else
186+
{
187+
while (size > 0)
188+
{
189+
size_t bytesToRead = std::min(size, sizeof(m_tempBuffer));
190+
size_t read = 0;
191+
192+
if (!m_crashInfo.ReadProcessMemory((void*)address, m_tempBuffer, bytesToRead, &read)) {
193+
printf_error("Error reading memory at %" PRIA PRIx64 " size %08zx FAILED %s (%d)\n", address, bytesToRead, strerror(g_readProcessMemoryErrno), g_readProcessMemoryErrno);
194+
return false;
195+
}
196+
197+
// This can happen if the target process dies before createdump is finished
198+
if (read == 0) {
199+
printf_error("Error reading memory at %" PRIA PRIx64 " size %08zx returned 0 bytes read: %s (%d)\n", address, bytesToRead, strerror(g_readProcessMemoryErrno), g_readProcessMemoryErrno);
200+
return false;
201+
}
202+
203+
if (!WriteData(m_tempBuffer, read)) {
204+
return false;
205+
}
206+
207+
address += read;
208+
size -= read;
197209
}
198-
199-
address += read;
200-
size -= read;
201210
}
202211
}
203212

src/coreclr/debug/createdump/dumpwriterelf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class DumpWriter
5656
static bool WriteData(int fd, const void* buffer, size_t length);
5757

5858
private:
59+
bool WriteDiagInfo(int size);
5960
bool WriteProcessInfo();
6061
bool WriteAuxv();
6162
size_t GetNTFileInfoSize(size_t* alignmentBytes = nullptr);

src/coreclr/debug/createdump/dumpwritermacho.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,13 @@ DumpWriter::WriteSegments()
229229
(segment.initprot & VM_PROT_EXECUTE) ? 'x' : '-',
230230
segment.initprot);
231231

232-
if (address == SpecialThreadInfoAddress)
232+
if (address == SpecialDiagInfoAddress)
233+
{
234+
if (!WriteDiagInfo(size)) {
235+
return false;
236+
}
237+
}
238+
else if (address == SpecialThreadInfoAddress)
233239
{
234240
// Write the header
235241
SpecialThreadInfoHeader header = {

src/coreclr/debug/createdump/dumpwritermacho.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class DumpWriter
4242
static bool WriteData(int fd, const void* buffer, size_t length);
4343

4444
private:
45+
bool WriteDiagInfo(int size);
4546
void BuildSegmentLoadCommands();
4647
void BuildThreadLoadCommands();
4748
bool WriteHeader(uint64_t* pFileOffset);
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
4+
// ******************************************************************************
5+
// WARNING!!!: This code is also used by SOS in the diagnostics repo. Should be
6+
// updated in a backwards and forwards compatible way.
7+
// See: https://github.com/dotnet/diagnostics/blob/main/src/SOS/inc/specialdiaginfo.h
8+
// ******************************************************************************
9+
10+
// This is a special memory region added to ELF and MachO dumps that contains extra diagnostics
11+
// information like the exception record for a crash for a NativeAOT app. The exception record
12+
// contains the pointer to the JSON formatted crash info.
13+
14+
#define SPECIAL_DIAGINFO_SIGNATURE "DIAGINFOHEADER"
15+
#define SPECIAL_DIAGINFO_VERSION 1
16+
17+
#ifdef __APPLE__
18+
const uint64_t SpecialDiagInfoAddress = 0x7fffffff10000000;
19+
#else
20+
#if TARGET_64BIT
21+
const uint64_t SpecialDiagInfoAddress = 0x00007ffffff10000;
22+
#else
23+
const uint64_t SpecialDiagInfoAddress = 0x7fff1000;
24+
#endif
25+
#endif
26+
27+
struct SpecialDiagInfoHeader
28+
{
29+
char Signature[16];
30+
int Version;
31+
uint64_t ExceptionRecordAddress;
32+
};

0 commit comments

Comments
 (0)