Skip to content

Commit f9529fd

Browse files
author
Mike McLaughlin
authored
Add runtime module address to SpecialDiagInfo block in createdump (#95816)
* Add runtime module address to SpecialDiagInfo block in createdump Fix missing DotNetRuntimeDebugHeader export: Add ILC options: --export-dynamic-symbol - Add dynamic export symbol to export file. Used to add DotNetRuntimeDebugHeader export. --export-unmanaged-entrypoints - controls whether the exported method definitions are exported Change Native AOT build integration to always pass an export file to ILC and linker. * Bump the Native AOT data contract sizes
1 parent f1d5cea commit f9529fd

File tree

10 files changed

+94
-22
lines changed

10 files changed

+94
-22
lines changed

src/coreclr/debug/createdump/crashinfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ typedef HINSTANCE (PALAPI_NOEXPORT *PFN_REGISTER_MODULE)(LPCSTR); /* u
99
// This is for the PAL_VirtualUnwindOutOfProc read memory adapter.
1010
CrashInfo* g_crashInfo;
1111

12+
// This is the NativeAOT DotNetRuntimeDebugHeader signature
13+
uint8_t g_debugHeaderCookie[4] = { 0x44, 0x4E, 0x44, 0x48 };
14+
1215
static bool ModuleInfoCompare(const ModuleInfo* lhs, const ModuleInfo* rhs) { return lhs->BaseAddress() < rhs->BaseAddress(); }
1316

1417
CrashInfo::CrashInfo(const CreateDumpOptions& options) :
@@ -30,6 +33,7 @@ CrashInfo::CrashInfo(const CreateDumpOptions& options) :
3033
m_enumMemoryPagesAdded(0)
3134
{
3235
g_crashInfo = this;
36+
m_runtimeBaseAddress = 0;
3337
#ifdef __APPLE__
3438
m_task = 0;
3539
#else

src/coreclr/debug/createdump/crashinfomac.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include "createdump.h"
55

6+
extern uint8_t g_debugHeaderCookie[4];
7+
68
int g_readProcessMemoryResult = KERN_SUCCESS;
79

810
bool
@@ -263,6 +265,24 @@ void CrashInfo::VisitModule(MachOModule& module)
263265
}
264266
}
265267
}
268+
else if (m_appModel == AppModelType::NativeAOT)
269+
{
270+
uint64_t symbolOffset;
271+
if (module.TryLookupSymbol("DotNetRuntimeDebugHeader", &symbolOffset))
272+
{
273+
m_coreclrPath = GetDirectory(module.Name());
274+
m_runtimeBaseAddress = module.BaseAddress();
275+
276+
uint8_t cookie[sizeof(g_debugHeaderCookie)];
277+
if (ReadMemory((void*)(module.BaseAddress() + symbolOffset), cookie, sizeof(cookie)))
278+
{
279+
if (memcmp(cookie, g_debugHeaderCookie, sizeof(g_debugHeaderCookie)) == 0)
280+
{
281+
TRACE("Found valid NativeAOT runtime module\n");
282+
}
283+
}
284+
}
285+
}
266286
}
267287
// VisitSegment is called for each segment of the module
268288
module.EnumerateSegments();

src/coreclr/debug/createdump/crashinfounix.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#endif
99

1010
extern CrashInfo* g_crashInfo;
11+
extern uint8_t g_debugHeaderCookie[4];
1112

1213
int g_readProcessMemoryErrno = 0;
1314

@@ -383,6 +384,27 @@ CrashInfo::VisitModule(uint64_t baseAddress, std::string& moduleName)
383384
}
384385
}
385386
}
387+
else if (m_appModel == AppModelType::NativeAOT)
388+
{
389+
if (PopulateForSymbolLookup(baseAddress))
390+
{
391+
uint64_t symbolOffset;
392+
if (TryLookupSymbol("DotNetRuntimeDebugHeader", &symbolOffset))
393+
{
394+
m_coreclrPath = GetDirectory(moduleName);
395+
m_runtimeBaseAddress = baseAddress;
396+
397+
uint8_t cookie[sizeof(g_debugHeaderCookie)];
398+
if (ReadMemory((void*)(baseAddress + symbolOffset), cookie, sizeof(cookie)))
399+
{
400+
if (memcmp(cookie, g_debugHeaderCookie, sizeof(g_debugHeaderCookie)) == 0)
401+
{
402+
TRACE("Found valid NativeAOT runtime module\n");
403+
}
404+
}
405+
}
406+
}
407+
}
386408
}
387409
EnumerateProgramHeaders(baseAddress);
388410
}

src/coreclr/debug/createdump/dumpwriter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ DumpWriter::WriteDiagInfo(size_t size)
3939
SpecialDiagInfoHeader header = {
4040
{SPECIAL_DIAGINFO_SIGNATURE},
4141
SPECIAL_DIAGINFO_VERSION,
42-
m_crashInfo.ExceptionRecord()
42+
m_crashInfo.ExceptionRecord(),
43+
m_crashInfo.RuntimeBaseAddress()
4344
};
4445
if (!WriteData(&header, sizeof(header))) {
4546
return false;

src/coreclr/debug/createdump/specialdiaginfo.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// ******************************************************************************
99

1010
// 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.
11+
// information like the exception record address for a NativeAOT app crash or the runtime module
12+
// base address. The exception record contains the pointer to the JSON formatted crash info.
1313

1414
#define SPECIAL_DIAGINFO_SIGNATURE "DIAGINFOHEADER"
15-
#define SPECIAL_DIAGINFO_VERSION 1
15+
#define SPECIAL_DIAGINFO_VERSION 2
1616

1717
#ifdef __APPLE__
1818
const uint64_t SpecialDiagInfoAddress = 0x7fffffff10000000;
@@ -31,4 +31,5 @@ struct SpecialDiagInfoHeader
3131
char Signature[16];
3232
int32_t Version;
3333
uint64_t ExceptionRecordAddress;
34+
uint64_t RuntimeBaseAddress;
3435
};

src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ The .NET Foundation licenses this file to you under the MIT license.
8181
<NativeObject>$(NativeIntermediateOutputPath)$(TargetName)$(NativeObjectExt)</NativeObject>
8282
<NativeBinary>$(NativeOutputPath)$(TargetName)$(NativeBinaryExt)</NativeBinary>
8383
<IlcExportUnmanagedEntrypoints Condition="'$(IlcExportUnmanagedEntrypoints)' == '' and '$(NativeLib)' == 'Shared'">true</IlcExportUnmanagedEntrypoints>
84-
<ExportsFile Condition="$(IlcExportUnmanagedEntrypoints) == 'true' and $(ExportsFile) == ''">$(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt)</ExportsFile>
84+
<ExportsFile Condition="$(ExportsFile) == ''">$(NativeIntermediateOutputPath)$(TargetName)$(ExportsFileExt)</ExportsFile>
8585

8686
<IlcCompileOutput>$(NativeObject)</IlcCompileOutput>
8787

@@ -240,7 +240,10 @@ The .NET Foundation licenses this file to you under the MIT license.
240240
<IlcArg Include="@(TrimmerRootDescriptor->'--descriptor:%(FullPath)')" />
241241
<IlcArg Condition="'$(NativeLib)' != ''" Include="--nativelib" />
242242
<IlcArg Condition="'$(CustomNativeMain)' == 'true'" Include="--splitinit" />
243-
<IlcArg Condition="$(ExportsFile) != ''" Include="--exportsfile:$(ExportsFile)" />
243+
<IlcArg Condition="'$(ExportsFile)' != ''" Include="--exportsfile:$(ExportsFile)" />
244+
<IlcArg Condition="'$(_targetOS)' == 'win' and '$(DebuggerSupport)' != 'false'" Include="--export-dynamic-symbol:DotNetRuntimeDebugHeader,DATA" />
245+
<IlcArg Condition="'$(_targetOS)' != 'win' and '$(DebuggerSupport)' != 'false'" Include="--export-dynamic-symbol:DotNetRuntimeDebugHeader" />
246+
<IlcArg Condition="'$(IlcExportUnmanagedEntrypoints)' == 'true'" Include="--export-unmanaged-entrypoints" />
244247
<IlcArg Include="@(AutoInitializedAssemblies->'--initassembly:%(Identity)')" />
245248
<IlcArg Include="@(DirectPInvoke->'--directpinvoke:%(Identity)')" />
246249
<IlcArg Include="@(DirectPInvokeList->'--directpinvokelist:%(Identity)')" />
@@ -329,12 +332,11 @@ The .NET Foundation licenses this file to you under the MIT license.
329332
<CustomLinkerArg Include="-o &quot;$(NativeBinary)&quot;" Condition="'$(_targetOS)' != 'win'" />
330333
<CustomLinkerArg Include="/OUT:&quot;$(NativeBinary)&quot;" Condition="'$(_targetOS)' == 'win'" />
331334
<CustomLinkerArg Include="/DEF:&quot;$(ExportsFile)&quot;" Condition="'$(_targetOS)' == 'win' and $(ExportsFile) != ''" />
332-
<CustomLinkerArg Include="/EXPORT:DotNetRuntimeDebugHeader,DATA" Condition="'$(_targetOS)' == 'win' and '$(DebuggerSupport)' != 'false'" />
333335
<CustomLinkerArg Include="/LIBPATH:&quot;%(AdditionalNativeLibraryDirectories.Identity)&quot;" Condition="'$(_targetOS)' == 'win' and '@(AdditionalNativeLibraryDirectories->Count())' &gt; 0" />
334336
<CustomLinkerArg Include="-exported_symbols_list &quot;$(ExportsFile)&quot;" Condition="'$(_IsApplePlatform)' == 'true' and '$(ExportsFile)' != ''" />
335337
<CustomLinkerArg Include="-exported_symbols_list /dev/null" Condition="'$(OutputType)' == 'exe' and '$(_IsApplePlatform)' == 'true' and '$(ExportsFile)' == ''" />
336-
<CustomLinkerArg Include="-Wl,--version-script=$(ExportsFile)" Condition="'$(_targetOS)' != 'win' and '$(_IsApplePlatform)' != 'true' and $(ExportsFile) != ''" />
337-
<CustomLinkerArg Include="-Wl,--export-dynamic" Condition="'$(_targetOS)' != 'win' and '$(_IsApplePlatform)' != 'true' and '$(IlcExportUnmanagedEntrypoints)' == 'true' and '$(NativeLib)' == ''" />
338+
<CustomLinkerArg Include="-Wl,--version-script=$(ExportsFile)" Condition="'$(_targetOS)' != 'win' and '$(_IsApplePlatform)' != 'true' and '$(ExportsFile)' != ''" />
339+
<CustomLinkerArg Include="-Wl,--export-dynamic" Condition="'$(_targetOS)' != 'win' and '$(_IsApplePlatform)' != 'true' and '$(ExportsFile)' != ''" />
338340
<CustomLinkerArg Include="@(LinkerArg)" />
339341
</ItemGroup>
340342
<ItemGroup Condition="'$(_targetOS)' != 'win' and '$(_IsApplePlatform)' != 'true'">

src/coreclr/nativeaot/Runtime/DebugHeader.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ struct GlobalValueEntry
3636

3737
// This size should be one bigger than the number of entries since a null entry
3838
// signifies the end of the array.
39-
static constexpr size_t DebugTypeEntriesArraySize = 96;
39+
static constexpr size_t DebugTypeEntriesArraySize = 100;
4040
static DebugTypeEntry s_DebugEntries[DebugTypeEntriesArraySize];
4141

4242
// This size should be one bigger than the number of entries since a null entry
4343
// signifies the end of the array.
44-
static constexpr size_t GlobalEntriesArraySize = 6;
44+
static constexpr size_t GlobalEntriesArraySize = 8;
4545
static GlobalValueEntry s_GlobalEntries[GlobalEntriesArraySize];
4646

4747
// This structure is part of a in-memory serialization format that is used by diagnostic tools to
@@ -108,14 +108,18 @@ struct DotNetRuntimeDebugHeader
108108
};
109109

110110
extern "C" struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader;
111+
112+
#ifdef HOST_UNIX
113+
__attribute__ ((visibility ("default")))
114+
#endif
111115
struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {};
112116

113117
#define MAKE_DEBUG_ENTRY(TypeName, FieldName, Value) \
114118
do \
115119
{ \
116120
s_DebugEntries[currentDebugPos] = { #TypeName, #FieldName, Value, 0 }; \
117121
++currentDebugPos; \
118-
ASSERT(currentDebugPos <= DebugTypeEntriesArraySize); \
122+
ASSERT(currentDebugPos < DebugTypeEntriesArraySize); \
119123
} while(0)
120124

121125
#define MAKE_DEBUG_FIELD_ENTRY(TypeName, FieldName) MAKE_DEBUG_ENTRY(TypeName, FieldName, offsetof(TypeName, FieldName))
@@ -129,7 +133,7 @@ struct DotNetRuntimeDebugHeader DotNetRuntimeDebugHeader = {};
129133
{ \
130134
s_GlobalEntries[currentGlobalPos] = { #Name, Name }; \
131135
++currentGlobalPos; \
132-
ASSERT(currentGlobalPos <= GlobalEntriesArraySize); \
136+
ASSERT(currentGlobalPos < GlobalEntriesArraySize); \
133137
} while(0) \
134138

135139
extern "C" void PopulateDebugHeaders()

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExportsFileWriter.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ namespace ILCompiler
1212
{
1313
public class ExportsFileWriter
1414
{
15-
private string _exportsFile;
16-
private List<EcmaMethod> _methods;
17-
private TypeSystemContext _context;
15+
private readonly string _exportsFile;
16+
private readonly IEnumerable<string> _exportSymbols;
17+
private readonly List<EcmaMethod> _methods;
18+
private readonly TypeSystemContext _context;
1819

19-
public ExportsFileWriter(TypeSystemContext context, string exportsFile)
20+
public ExportsFileWriter(TypeSystemContext context, string exportsFile, IEnumerable<string> exportSymbols)
2021
{
2122
_exportsFile = exportsFile;
23+
_exportSymbols = exportSymbols;
2224
_context = context;
2325
_methods = new List<EcmaMethod>();
2426
}
@@ -34,18 +36,24 @@ public void EmitExportedMethods()
3436
if (_context.Target.IsWindows)
3537
{
3638
streamWriter.WriteLine("EXPORTS");
39+
foreach (string symbol in _exportSymbols)
40+
streamWriter.WriteLine($" {symbol.Replace(',', ' ')}");
3741
foreach (var method in _methods)
3842
streamWriter.WriteLine($" {method.GetUnmanagedCallersOnlyExportName()}");
3943
}
4044
else if(_context.Target.IsOSXLike)
4145
{
46+
foreach (string symbol in _exportSymbols)
47+
streamWriter.WriteLine($"_{symbol}");
4248
foreach (var method in _methods)
4349
streamWriter.WriteLine($"_{method.GetUnmanagedCallersOnlyExportName()}");
4450
}
4551
else
4652
{
4753
streamWriter.WriteLine("V1.0 {");
4854
streamWriter.WriteLine(" global: _init; _fini;");
55+
foreach (string symbol in _exportSymbols)
56+
streamWriter.WriteLine($" {symbol};");
4957
foreach (var method in _methods)
5058
streamWriter.WriteLine($" {method.GetUnmanagedCallersOnlyExportName()};");
5159
streamWriter.WriteLine(" local: *;");

src/coreclr/tools/aot/ILCompiler/ILCompilerRootCommand.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ internal sealed class ILCompilerRootCommand : CliRootCommand
3838
public CliOption<bool> SplitExeInitialization { get; } =
3939
new("--splitinit") { Description = "Split initialization of an executable between the library entrypoint and a main entrypoint" };
4040
public CliOption<string> ExportsFile { get; } =
41-
new("--exportsfile") { Description = "File to write exported method definitions" };
41+
new("--exportsfile") { Description = "File to write exported symbol and method definitions" };
42+
public CliOption<bool> ExportUnmanagedEntryPoints { get; } =
43+
new("--export-unmanaged-entrypoints") { Description = "Controls whether the named UnmanagedCallersOnly methods are exported" };
44+
public CliOption<string[]> ExportDynamicSymbols { get; } =
45+
new("--export-dynamic-symbol") { Description = "Add dynamic export symbol to exports file" };
4246
public CliOption<string> DgmlLogFileName { get; } =
4347
new("--dgmllog") { Description = "Save result of dependency analysis as DGML" };
4448
public CliOption<bool> GenerateFullDgmlLog { get; } =
@@ -176,6 +180,8 @@ public ILCompilerRootCommand(string[] args) : base(".NET Native IL Compiler")
176180
Options.Add(NativeLib);
177181
Options.Add(SplitExeInitialization);
178182
Options.Add(ExportsFile);
183+
Options.Add(ExportDynamicSymbols);
184+
Options.Add(ExportUnmanagedEntryPoints);
179185
Options.Add(DgmlLogFileName);
180186
Options.Add(GenerateFullDgmlLog);
181187
Options.Add(ScanDgmlLogFileName);

src/coreclr/tools/aot/ILCompiler/Program.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,15 @@ void RunScanner()
574574
string exportsFile = Get(_command.ExportsFile);
575575
if (exportsFile != null)
576576
{
577-
ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, exportsFile);
578-
foreach (var compilationRoot in compilationRoots)
577+
ExportsFileWriter defFileWriter = new ExportsFileWriter(typeSystemContext, exportsFile, Get(_command.ExportDynamicSymbols));
578+
579+
if (Get(_command.ExportUnmanagedEntryPoints))
579580
{
580-
if (compilationRoot is UnmanagedEntryPointsRootProvider provider)
581-
defFileWriter.AddExportedMethods(provider.ExportedMethods);
581+
foreach (var compilationRoot in compilationRoots)
582+
{
583+
if (compilationRoot is UnmanagedEntryPointsRootProvider provider)
584+
defFileWriter.AddExportedMethods(provider.ExportedMethods);
585+
}
582586
}
583587

584588
defFileWriter.EmitExportedMethods();

0 commit comments

Comments
 (0)