Skip to content

Commit 37b2daa

Browse files
authored
Disable core dumps in host tests that intentionally crash (#116725)
For tests that intentionally crash, we were already clearing out `DOTNET_DbgEnableMiniDump`/`COMPlus_DbgEnableMiniDump`, but OS core dumps were still enabled. - In tests that are explicitly throwing an unhandled exception, call into OS APIs to disable dumps for the current process - When launching a command that should have dumps disabled, call `ulimit -c 0` before the command (for cases where the test doesn't have control over the process) For Unix, this avoids creating any dumps for intentional crashes. On Windows, we still have two created for `Muxer_NonAssemblyWithExeExtension` and `UnhandledException_BreadcrumbThreadDoesNotFinish`.
1 parent c585026 commit 37b2daa

File tree

19 files changed

+134
-32
lines changed

19 files changed

+134
-32
lines changed

src/installer/tests/Assets/Projects/AppWithCustomEntryPoints/AppWithCustomEntryPoints.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@
55
<OutputType>Exe</OutputType>
66
</PropertyGroup>
77

8+
<ItemGroup>
9+
<Compile Include="..\CoreDump.cs" />
10+
</ItemGroup>
11+
812
</Project>

src/installer/tests/Assets/Projects/AppWithCustomEntryPoints/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ public static int ThrowException(IntPtr arg, int size)
5353
{
5454
functionPointerCallCount++;
5555
PrintFunctionPointerCallLog(nameof(ThrowException), arg, size);
56+
57+
// Disable core dumps - test is intentionally crashing
58+
Utilities.CoreDump.Disable();
5659
throw new InvalidOperationException(nameof(ThrowException));
5760
}
5861

src/installer/tests/Assets/Projects/Component/Component.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public static int ThrowException(IntPtr arg, int size)
4747
{
4848
componentCallCount++;
4949
PrintComponentCallLog(nameof(ThrowException), arg, size);
50+
51+
// Disable core dumps - test is intentionally crashing
52+
Utilities.CoreDump.Disable();
5053
throw new InvalidOperationException(nameof(ThrowException));
5154
}
5255

src/installer/tests/Assets/Projects/Component/Component.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@
55
<EnableDynamicLoading>true</EnableDynamicLoading>
66
</PropertyGroup>
77

8+
<ItemGroup>
9+
<Compile Include="..\CoreDump.cs" />
10+
</ItemGroup>
11+
812
</Project>
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
using System;
6+
using System.Runtime.InteropServices;
7+
8+
namespace Utilities
9+
{
10+
public static partial class CoreDump
11+
{
12+
public static void Disable()
13+
{
14+
string? envValue = Environment.GetEnvironmentVariable("DOTNET_DbgEnableMiniDump");
15+
if (envValue is not null && envValue != "0")
16+
throw new InvalidOperationException("DOTNET_DbgEnableMiniDump is set and not 0. Ensure it is unset or set to 0 to disable dumps.");
17+
18+
envValue = Environment.GetEnvironmentVariable("COMPlus_DbgEnableMiniDump");
19+
if (envValue is not null && envValue != "0")
20+
throw new InvalidOperationException("COMPlus_DbgEnableMiniDump is set and not 0. Ensure it is unset or set to 0 to disable dumps.");
21+
22+
if (OperatingSystem.IsLinux())
23+
{
24+
if (prctl(PR_SET_DUMPABLE, 0) != 0)
25+
{
26+
throw new InvalidOperationException($"Failed to disable core dump. Error: {Marshal.GetLastPInvokeError()}.");
27+
}
28+
}
29+
else if (OperatingSystem.IsMacOS())
30+
{
31+
RLimit rlimit = new() { rlim_cur = 0, rlim_max = 0 };
32+
if (setrlimit(RLIMIT_CORE, rlimit) != 0)
33+
{
34+
throw new InvalidOperationException($"Failed to disable core dump. Error: {Marshal.GetLastPInvokeError()}.");
35+
}
36+
}
37+
}
38+
39+
[StructLayout(LayoutKind.Sequential)]
40+
private struct RLimit
41+
{
42+
// These are rlim_t. All macOS platforms we use this on currently define it as unsigned 64-bit
43+
public ulong rlim_cur; // Soft limit
44+
public ulong rlim_max; // Hard limit
45+
}
46+
47+
// Max core file size
48+
private const int RLIMIT_CORE = 4;
49+
50+
[DllImport("libc", SetLastError = true)]
51+
private static extern int setrlimit(int resource, in RLimit rlim);
52+
53+
// "dumpable" attribute of the calling process
54+
private const int PR_SET_DUMPABLE = 4;
55+
56+
[DllImport("libc", SetLastError = true)]
57+
private static extern int prctl(int option, int arg2);
58+
}
59+
}

src/installer/tests/Assets/Projects/HelloWorld/HelloWorld.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@
1212
</PropertyGroup>
1313
</Target>
1414

15+
<ItemGroup>
16+
<Compile Include="..\CoreDump.cs" />
17+
</ItemGroup>
18+
1519
</Project>

src/installer/tests/Assets/Projects/HelloWorld/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ public static void Main(string[] args)
5050
}
5151
break;
5252
case "throw_exception":
53+
// Disable core dumps - test is intentionally crashing
54+
Utilities.CoreDump.Disable();
5355
throw new Exception("Goodbye World!");
5456
default:
5557
break;

src/installer/tests/Assets/Projects/HelloWorld/SelfContained.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,9 @@
1212
<_SupportedArchitecture Condition="'$(TargetArchitecture)' == 'x64' or '$(TargetArchitecture)' == 'x86' or '$(TargetArchitecture)' == 'arm' or '$(TargetArchitecture)' == 'arm64'">true</_SupportedArchitecture>
1313
<RuntimeIdentifier Condition="'$(_SupportedPlatform)' == 'true' and '$(_SupportedArchitecture)' == 'true'">$(TargetRid)</RuntimeIdentifier>
1414
</PropertyGroup>
15+
16+
<ItemGroup>
17+
<Compile Include="..\CoreDump.cs" />
18+
</ItemGroup>
19+
1520
</Project>

src/installer/tests/HostActivation.Tests/Breadcrumbs.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public void UnhandledException_BreadcrumbThreadDoesNotFinish()
3737
TestContext.BuiltDotNet.Exec(sharedTestState.App.AppDll, "throw_exception")
3838
.EnvironmentVariable(Constants.Breadcrumbs.EnvironmentVariable, sharedTestState.BreadcrumbLocation)
3939
.EnableTracingAndCaptureOutputs()
40-
.Execute(expectedToFail: true)
40+
.DisableDumps() // Expected to throw an exception
41+
.Execute()
4142
.Should().Fail()
4243
.And.HaveStdErrContaining("Unhandled exception.")
4344
.And.HaveStdErrContaining("System.Exception: Goodbye World")

src/installer/tests/HostActivation.Tests/DependencyResolution/AdditionalDeps.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void DepsFile(bool dependencyExists)
9999

100100
CommandResult result = SharedState.DotNetWithNetCoreApp.Exec(Constants.AdditionalDeps.CommandLineArgument, additionalDepsFile, app.AppDll)
101101
.EnableTracingAndCaptureOutputs()
102-
.Execute(expectedToFail: !dependencyExists);
102+
.Execute();
103103

104104
result.Should().HaveUsedAdditionalDeps(additionalDepsFile);
105105
if (dependencyExists)
@@ -126,7 +126,7 @@ public void InvalidJson()
126126

127127
SharedState.DotNetWithNetCoreApp.Exec(Constants.AdditionalDeps.CommandLineArgument, invalidDepsFile, SharedState.FrameworkReferenceApp.AppDll)
128128
.EnableTracingAndCaptureOutputs()
129-
.Execute(expectedToFail: true)
129+
.Execute()
130130
.Should().Fail()
131131
.And.HaveUsedAdditionalDeps(invalidDepsFile)
132132
.And.HaveStdErrContaining($"Error initializing the dependency resolver: An error occurred while parsing: {invalidDepsFile}");

0 commit comments

Comments
 (0)