windows: remove .NET test infrastructure and CRT probe function

The C# test suite and ghostty_crt_workaround_active() probe were
unnecessary overhead. The DllMain workaround is harmless to keep
(CRT init is ref-counted) and comments document when to remove it.
test_dll_init.c remains as a standalone C reproducer.
This commit is contained in:
Alessandro De Blasis
2026-03-26 11:33:11 +01:00
committed by Mitchell Hashimoto
parent f764b16465
commit 6afc174a4f
3 changed files with 0 additions and 136 deletions

View File

@@ -64,14 +64,6 @@ pub const DllMain = if (builtin.os.tag == .windows and
}
}.handler else void;
// Probe export: returns 1 when the DllMain CRT workaround above is
// compiled in. The C# test suite checks for this symbol to detect when
// the workaround becomes redundant (when Zig fixes MSVC DLL CRT init).
// Remove this along with the DllMain block above.
pub export fn ghostty_crt_workaround_active() callconv(.c) c_int {
return if (builtin.os.tag == .windows and builtin.abi == .msvc) 1 else 0;
}
// Some comptime assertions that our C API depends on.
comptime {
// We allow tests to reference this file because we unit test

View File

@@ -1,30 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MSTest" Version="4.0.2" />
</ItemGroup>
<ItemGroup>
<Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
</ItemGroup>
<!--
Copy ghostty.dll from the Zig build output so P/Invoke can find it.
Build libghostty first: zig build -Dapp-runtime=none -Demit-exe=false
-->
<Target Name="CopyGhosttyDll" AfterTargets="Build"
Condition="Exists('$(MSBuildThisFileDirectory)..\..\zig-out\lib\ghostty.dll')">
<Copy SourceFiles="$(MSBuildThisFileDirectory)..\..\zig-out\lib\ghostty.dll"
DestinationFolder="$(OutputPath)"
SkipUnchangedFiles="true" />
</Target>
</Project>

View File

@@ -1,98 +0,0 @@
using System.Runtime.InteropServices;
[assembly: System.Runtime.CompilerServices.DisableRuntimeMarshalling]
namespace Ghostty.Tests;
/// <summary>
/// Tests that validate libghostty DLL initialization on Windows.
///
/// Ghostty's main_c.zig declares a DllMain that calls __vcrt_initialize
/// and __acrt_initialize because Zig's _DllMainCRTStartup does not
/// initialize the MSVC C runtime for DLL targets. Without this, any C
/// library function (setlocale, glslang, oniguruma) crashes.
///
/// See the probe test at the bottom for workaround tracking.
/// </summary>
[TestClass]
public partial class LibghosttyInitTests
{
private const string LibName = "ghostty";
[StructLayout(LayoutKind.Sequential)]
private struct GhosttyInfo
{
public int BuildMode;
public nint Version;
public nuint VersionLen;
}
[LibraryImport(LibName, EntryPoint = "ghostty_info")]
private static partial GhosttyInfo GhosttyInfoNative();
[LibraryImport(LibName, EntryPoint = "ghostty_crt_workaround_active")]
private static partial int GhosttyWorkaroundActive();
[TestMethod]
public void GhosttyInfo_Works()
{
// Baseline: ghostty_info uses only compile-time constants and
// does not depend on CRT state. This should always work.
var info = GhosttyInfoNative();
Assert.IsGreaterThan((nuint)0, info.VersionLen);
Assert.AreNotEqual(nint.Zero, info.Version);
}
// NOTE: ghostty_init is validated by the C reproducer (test_dll_init.c)
// rather than a C# test because ghostty_init initializes global state
// (glslang, oniguruma, allocators) that crashes during test host
// teardown when the DLL is unloaded. The C reproducer handles this by
// exiting without FreeLibrary. The DLL unload ordering issue is
// separate from the CRT init fix.
/// <summary>
/// PROBE TEST: Detects when our DllMain CRT workaround in main_c.zig
/// is removed, which should happen when Zig fixes _DllMainCRTStartup
/// for MSVC DLL targets.
///
/// HOW IT WORKS:
/// ghostty_crt_workaround_active() returns 1 when the workaround is
/// compiled in (Windows MSVC), 0 on other platforms. This test
/// asserts that it returns 1. When it returns 0, the workaround was
/// removed.
///
/// WHEN THIS TEST FAILS:
/// Someone removed the DllMain workaround from main_c.zig.
/// This is the expected outcome when Zig fixes the issue.
///
/// Step 1: Run test_dll_init.c (the C reproducer) WITHOUT the
/// DllMain workaround. If ghostty_init returns 0, Zig
/// fixed it. Delete the DllMain block in main_c.zig,
/// ghostty_crt_workaround_active(), and this probe test.
///
/// Step 2: If ghostty_init still crashes without the workaround,
/// restore the DllMain block in main_c.zig.
///
/// Step 3: To unblock CI while investigating, skip this test:
/// dotnet test --filter "FullyQualifiedName!=Ghostty.Tests.LibghosttyInitTests.DllMainWorkaround_IsStillActive"
///
/// UPSTREAM TRACKING (as of 2026-03-26):
/// No Zig issue tracks this exact gap.
/// Closest: Codeberg ziglang/zig #30936 (reimplement crt0 code).
/// Related GitHub issues: 7065, 11285, 19672 (link-time, not runtime).
/// </summary>
[TestMethod]
public void DllMainWorkaround_IsStillActive()
{
var active = GhosttyWorkaroundActive();
Assert.AreEqual(1, active,
"ghostty_crt_workaround_active() returned 0. " +
"The DllMain CRT workaround in main_c.zig was removed or disabled. " +
"Run test_dll_init.c without the workaround to check if Zig fixed " +
"the issue. If ghostty_init works, delete the DllMain and this test. " +
"If it crashes, restore the DllMain. " +
"To skip this test: dotnet test --filter " +
"\"FullyQualifiedName!=Ghostty.Tests.LibghosttyInitTests.DllMainWorkaround_IsStillActive\"");
}
}