3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-08-11 00:11:48 +00:00
z3/src/api
Copilot ba7b12c18c
Fix .NET API memory leak: NativeContext finalizer, delegate lifetime, GC memory pressure (#10090)
Creating and disposing `Context` instances causes unbounded native
memory growth (~12 GB for 100k contexts) because `NativeContext` had no
finalizer — if `Dispose()` was never called, the native Z3 context
leaked permanently. Additionally, both `Context` and `NativeContext` had
delegate lifetime and thread-safety issues in their disposal paths.

## `NativeContext.cs`

- **Add missing finalizer** `~NativeContext() { Dispose(); }` — the root
cause of permanent leaks when callers don't explicitly dispose
- **Atomic disposal** via `Interlocked.Exchange(ref m_ctx, IntPtr.Zero)`
— prevents double-free when `Dispose()` is called concurrently (e.g.
user code + finalizer race)
- **Delegate lifetime** — capture `errHandler` locally +
`GC.KeepAlive(errHandler)` after `Z3_del_context`; the GC could
otherwise collect the error handler callback before the native
destructor finishes
- **Remove dead code** — `GC.SuppressFinalize` in `InitContext()` and
`GC.ReRegisterForFinalize` in `Dispose()` were both no-ops (no finalizer
existed); the latter would have caused infinite finalization with the
new finalizer
- **GC memory pressure** — `GC.AddMemoryPressure(8MB)` on init /
`GC.RemoveMemoryPressure(8MB)` on dispose, guarded by
`m_memPressureAdded` flag, so the GC schedules finalizers promptly when
contexts accumulate

## `Context.cs`

- **Thread-safe disposal** — capture `ctx` and `errHandler` inside the
existing `lock(this)` block; previously both were read outside the lock,
allowing two concurrent callers to both capture the same non-zero `ctx`
and double-free it
- **Delegate lifetime** — same `errHandler` + `GC.KeepAlive` pattern as
`NativeContext`
- **`GC.SuppressFinalize` placement** — moved inside the `if (m_ctx !=
IntPtr.Zero)` block, before cleanup, per .NET best practice
- **GC memory pressure** — same add/remove pattern, conditioned on
`!is_external` via `m_memPressureAdded` flag

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-11 21:15:36 -07:00
..
c++ Fixes necessary to compile z3 included in clang-tidy via FetchContents. (#9768) 2026-06-08 19:44:01 -07:00
dll
dotnet Fix .NET API memory leak: NativeContext finalizer, delegate lifetime, GC memory pressure (#10090) 2026-07-11 21:15:36 -07:00
go Go bindings: enable concurrent dec_ref for GC-driven finalizers (#10002) 2026-06-29 13:14:41 -06:00
java fix build warnings 2026-06-22 18:20:23 -07:00
js Bump markdown-it from 14.1.0 to 14.2.0 in /src/api/js (#9881) 2026-06-16 11:34:20 -06:00
julia fix issues 1-10: add missing API bindings across Go, Julia, TypeScript, OCaml, and Java (#9432) 2026-05-04 09:29:47 -07:00
mcp
ml Expose Seq.mk_re_diff in ocaml bindings (#9584) 2026-05-21 10:29:08 -07:00
python Fix Pyodide build job failure by restoring wasm side-module linking (#9916) 2026-06-20 18:15:32 -06:00
api_algebraic.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_arith.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_array.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_ast.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_ast_map.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_ast_map.h
api_ast_vector.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_ast_vector.h Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_bv.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_config_params.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_context.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_context.h Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_datalog.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_datalog.h Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_datatype.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_finite_set.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_fpa.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_goal.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_goal.h
api_log.cpp
api_model.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_model.h
api_numeral.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_opt.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_params.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_parsers.cpp
api_pb.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_polynomial.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_polynomial.h
api_qe.cpp
api_quant.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_rcf.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_seq.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_solver.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_solver.h
api_special_relations.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_stats.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_stats.h
api_tactic.cpp Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
api_tactic.h
api_util.h Remove unnecessary semicolons (Attempt 2) (#10020) 2026-07-02 12:47:29 -07:00
CMakeLists.txt Fixes necessary to compile z3 included in clang-tidy via FetchContents. (#9768) 2026-06-08 19:44:01 -07:00
z3.h
z3_algebraic.h
z3_api.h Fix documentation for Z3_solver_to_dimacs_string (#9053) 2026-03-20 10:18:13 -07:00
z3_ast_containers.h
z3_fixedpoint.h
z3_fpa.h
z3_logger.h
z3_macros.h
z3_optimization.h
z3_polynomial.h
z3_private.h
z3_rcf.h
z3_replayer.cpp Fix clang warnings about casting away const. (#9933) 2026-06-23 19:57:46 -06:00
z3_replayer.h
z3_spacer.h
z3_v1.h