Skip to content

shared lock - part of #188 - #189

Closed
doomedraven wants to merge 1 commit into
kevoreilly:capemonfrom
doomedraven:shared_dumping_lock
Closed

doomedraven wants to merge 1 commit into
kevoreilly:capemonfrom
doomedraven:shared_dumping_lock

Conversation

@doomedraven

Copy link
Copy Markdown
Contributor

CAPE/CAPE.h — added extern CRITICAL_SECTION g_dotnet_jit_lock; (the lock defined in hook_clr.c, init'd in DllMain) so CAPE.c can share it.

CAPE/CAPE.c DumpInterestingRegions — wrapped both .NET blocks (the IsDotNetImage image dump and the g_dotnet_jit native-cache dump) in EnterCriticalSection(&g_dotnet_jit_lock) / LeaveCriticalSection. This serializes the teardown scan against the compileMethod hook (still running on JIT worker threads during teardown), so they no longer race on:

  • CapeMetaData scratch fields → dumps can't get cross-written metadata
  • DotNetCacheDumpCount check-then-increment → count stays exact vs. jit_dumps
  • g_dotnet_jit reads vs. concurrent lookup_add

No early returns between Enter/Leave, so the lock can't leak. Lock ordering (g_dotnet_jit_lock → dump/log/heap) matches what hook_clr.c already established, so no AB‑BA deadlock. DotNetCacheDumpCount stays unsigned int — with both writers now under the same CS (grep confirms there are only two), atomics aren't needed.

Left as-is on purpose: the two other lookup_get(&g_dotnet_jit, …) reads at CAPE.c:1094 / 1287 — pure reads of a prepend-only/never-deleted list, safe on x86/x64 without the lock.

**`CAPE/CAPE.h`** — added `extern CRITICAL_SECTION g_dotnet_jit_lock;` (the lock defined in `hook_clr.c`, init'd in `DllMain`) so `CAPE.c` can share it.

**`CAPE/CAPE.c` `DumpInterestingRegions`** — wrapped both .NET blocks (the `IsDotNetImage` image dump and the `g_dotnet_jit` native-cache dump) in `EnterCriticalSection(&g_dotnet_jit_lock)` / `LeaveCriticalSection`. This serializes the teardown scan against the `compileMethod` hook (still running on JIT worker threads during teardown), so they no longer race on:
- `CapeMetaData` scratch fields → dumps can't get cross-written metadata
- `DotNetCacheDumpCount` check-then-increment → count stays exact vs. `jit_dumps`
- `g_dotnet_jit` reads vs. concurrent `lookup_add`

No early returns between Enter/Leave, so the lock can't leak. Lock ordering (`g_dotnet_jit_lock` → dump/log/heap) matches what `hook_clr.c` already established, so no AB‑BA deadlock. `DotNetCacheDumpCount` stays `unsigned int` — with both writers now under the same CS (grep confirms there are only two), atomics aren't needed.

Left as-is on purpose: the two other `lookup_get(&g_dotnet_jit, …)` reads at `CAPE.c:1094` / `1287` — pure reads of a prepend-only/never-deleted list, safe on x86/x64 without the lock.
@doomedraven
doomedraven marked this pull request as draft August 30, 2026 19:31
@kevoreilly

Copy link
Copy Markdown
Owner

It is preferred to use internal lookup functions rather than critical section apis, I have attempted to harden and complete the lookup functions in #190. I will attempt to replace all critical section and TLS apis with the internal lookup functions using thread id as key.

@doomedraven

Copy link
Copy Markdown
Contributor Author

ok, it was also pushed to 188, so i will update it in 188 once i test it tomorrow and 190 is merged

@doomedraven
doomedraven deleted the shared_dumping_lock branch August 31, 2026 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants