[GH-ISSUE #3279] [Bug] Managed static provider marks every VB/MC++-compiled method with exception handling as malformed (small EH DataSize excludes the header) #1171

Closed
opened 2026-10-15 18:31:43 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @fenton06 on GitHub (Oct 14, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/3279

Before submitting

  • I searched the open and closed issues for a related report (closest: #1801, #938, #1768 — none cover EH-section parsing).
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

dotnet (managed static provider)

Observed behavior

inspect-managed-members reports body.status: "malformed", issue: "Exception section size does not contain whole clauses", empty exception_regions, and normalized_il_sha256: null for methods whose exception-handling table uses the small section format with the historical VB/MC++ DataSize quirk (DataSize counts only the clause bytes, excluding the 4-byte section header). This affects every try/catch/finally method compiled by legacy VB.NET or MC++, and blocks import_managed_reconstruction for those methods since no normalized-IL lock can be computed.

Reproduction (fully synthetic, no proprietary code)

  1. Build a minimal net8.0 program whose Main contains a single try/finally:
using System;

public class Repro
{
    public static void Main()
    {
        try
        {
            Console.WriteLine("try");
        }
        finally
        {
            Console.WriteLine("finally");
        }
    }
}
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>
</Project>

dotnet build -c Release

  1. Roslyn writes the conformant small EH section for Main (DataSize includes the 4-byte header):
01 10 00 00 | 02 00 00 00 0c 0c 00 0b 00 00 00 00

(DataSize = 0x10 = 16 = 4-byte header + 12-byte finally clause) — this layout is accepted today.

  1. Emulate the legacy VB/MC++ layout (produced as-is by VB 2005 / MC++ compilers) by patching the single DataSize byte 0x10 → 0x0c:
01 0c 00 00 | 02 00 00 00 0c 0c 00 0b 00 00 00 00
  1. npx -y rea-agents@6.4.0 inspect-managed-members Repro.dll --format json returns for Main:
"body": {
  "status": "malformed",
  "issue": "Exception section size does not contain whole clauses",
  "exception_regions": [],
  "normalized_il_sha256": null
}

Expected behavior

The CLR accepts both layouts. CoreCLR's COR_ILMETHOD_SECT::DataSize() (src/coreclr/inc/corhlpr.h) documents this exact quirk:

// VB and MC++ shipped with bug where they have not accounted for size of
// COR_ILMETHOD_SECT_EH_XXX in DataSize. To avoid breaking these images, we
// will align the size of EH sections up. ... (VSWhidbey #99031)
return Small.Size(Small.DataSize / sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL));

That is: treat DataSize / clauseSize as the clause count. REA should accept a section where size == count * clauseSize (VB/MC++) or size == count * clauseSize + 4 (conformant), with count = floor(size / clauseSize) and the section spanning 4 + count * clauseSize bytes.

Environment

  • rea-agents 6.4.0 (npm, published 2026-10-11)
  • Fedora 44, x86_64, Node 24
  • Repro DLL: 4,608 bytes, net8.0, single try/finally method
Originally created by @fenton06 on GitHub (Oct 14, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/3279 ### Before submitting - [x] I searched the open and closed issues for a related report (closest: #1801, #938, #1768 — none cover EH-section parsing). - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area dotnet (managed static provider) ### Observed behavior `inspect-managed-members` reports `body.status: "malformed"`, `issue: "Exception section size does not contain whole clauses"`, empty `exception_regions`, and `normalized_il_sha256: null` for methods whose exception-handling table uses the small section format with the historical VB/MC++ DataSize quirk (DataSize counts only the clause bytes, excluding the 4-byte section header). This affects every try/catch/finally method compiled by legacy VB.NET or MC++, and blocks `import_managed_reconstruction` for those methods since no normalized-IL lock can be computed. ### Reproduction (fully synthetic, no proprietary code) 1. Build a minimal net8.0 program whose `Main` contains a single `try`/`finally`: ```csharp using System; public class Repro { public static void Main() { try { Console.WriteLine("try"); } finally { Console.WriteLine("finally"); } } } ``` ```xml <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> </PropertyGroup> </Project> ``` `dotnet build -c Release` 2. Roslyn writes the conformant small EH section for `Main` (`DataSize` includes the 4-byte header): ``` 01 10 00 00 | 02 00 00 00 0c 0c 00 0b 00 00 00 00 ``` (`DataSize = 0x10 = 16 = 4-byte header + 12-byte finally clause`) — this layout is accepted today. 3. Emulate the legacy VB/MC++ layout (produced as-is by VB 2005 / MC++ compilers) by patching the single DataSize byte `0x10` → `0x0c`: ``` 01 0c 00 00 | 02 00 00 00 0c 0c 00 0b 00 00 00 00 ``` 4. `npx -y rea-agents@6.4.0 inspect-managed-members Repro.dll --format json` returns for `Main`: ```json "body": { "status": "malformed", "issue": "Exception section size does not contain whole clauses", "exception_regions": [], "normalized_il_sha256": null } ``` ### Expected behavior The CLR accepts both layouts. CoreCLR's `COR_ILMETHOD_SECT::DataSize()` (`src/coreclr/inc/corhlpr.h`) documents this exact quirk: ```cpp // VB and MC++ shipped with bug where they have not accounted for size of // COR_ILMETHOD_SECT_EH_XXX in DataSize. To avoid breaking these images, we // will align the size of EH sections up. ... (VSWhidbey #99031) return Small.Size(Small.DataSize / sizeof(IMAGE_COR_ILMETHOD_SECT_EH_CLAUSE_SMALL)); ``` That is: treat `DataSize / clauseSize` as the clause count. REA should accept a section where `size == count * clauseSize` (VB/MC++) or `size == count * clauseSize + 4` (conformant), with `count = floor(size / clauseSize)` and the section spanning `4 + count * clauseSize` bytes. ### Environment - rea-agents 6.4.0 (npm, published 2026-10-11) - Fedora 44, x86_64, Node 24 - Repro DLL: 4,608 bytes, net8.0, single try/finally method
bsakaguchi 2026-10-15 18:31:43 +00:00
  • closed this issue
  • added the
    bug
    label
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#1171
No description provided.