flm serve crashes with glibc heap corruption (double free / unaligned tcache) under concurrent request bursts — Linux / XDNA2, v0.9.43
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.9k
- Forks
- 152
- Avg merge
- 4h 14m
- Merged PRs (30d)
- 11
Description
Environment
| FLM version | v0.9.43 (flm --version → FLM v0.9.43; /api/version → {"version":"0.9.43"}) — latest release |
| OS | Ubuntu 24.04, glibc 2.39 (GLIBC 2.39-0ubuntu8.7) |
| CPU/NPU | AMD Ryzen AI MAX+ 395 "Strix Halo", NPU aie2p (6×8), single /dev/accel/accel0 |
| NPU firmware | 1.1.2.65 |
| XDNA driver | amdxdna 2.23.0_20260413 (XRT 2.23.0) |
| Model | qwen3-it:4b (Qwen3-4B-Instruct-2507-NPU2, Q4_1, 32k ctx) |
| Launch flags | flm serve qwen3-it:4b --pmode turbo --ctx-len 32768 --prefill-chunk-len 8192 --port 52625 |
| Linked libs | libxrt_coreutil.so.2, libboost_program_options.so.1.83.0, libgomp.so.1 (OpenMP) |
Symptom
flm serve (running as a long-lived server) aborts intermittently with glibc heap-corruption diagnostics on stderr, immediately after the model-list banner, then the supervisor restarts it (each restart reloads the NPU model). Observed signatures:
double free or corruption (out)
corrupted size vs. prev_size while consolidating
malloc(): unaligned tcache chunk detected
[FLM] Using custom model list path: .../share/flm/model_list.json
The abort is a SIGABRT from glibc's allocator, not an OOM (no exit code 137, memory was not exhausted) and not a config/port error. It occurred repeatedly during a burst of ~10 concurrent clients hitting the server in a short window, then stopped once traffic serialized (the current process has since been stable for 8+ hours under light load).
Trigger (best hypothesis)
- Concurrent-request bursts. The crashes clustered when ~10 independent clients issued
/v1/chat/completionsrequests near-simultaneously. Under steady/serialized traffic we have not reproduced it. --ctx-len 32768appears within limits (the model advertises 32k; community reports run--ctx-len 32000fine), so context length alone does not look like the cause.--prefill-chunk-len 8192(2× the 4096 default) and--pmode turboare the most aggressive settings in play and are plausible contributors to the timing window, but we have not isolated a single flag.- Probable code area: the v0.9.41 changelog ("fixes redundant tool schema injection in cached conversations") and v0.9.43 ("makes cached conversations more reliable by preserving complete message histories") indicate the cached-conversation / message-history subsystem was under active change around this build. A double-free /
corrupted size vs prev_size/ unaligned-tcache signature is consistent with a string/vector reallocation race in that path when multiple requests are in flight through the server's request queue while OpenMP worker threads are active.
What would help
- Whether the internal request queue (
npu_request_queue_,max_connections_insrc/server/server.hpp) fully serializes access to the conversation/KV-cache structures, or whether connection-accept / cache-reuse can run concurrently with an in-flight generation. - Whether building/running under a hardened allocator (e.g.
MALLOC_CHECK_=3, or a jemalloc/tcmalloc preload) reproduces or pinpoints the corruption site. - Any known concurrency fix landing after v0.9.43.
Reproduction (approximate)
flm serve qwen3-it:4b --pmode turbo --ctx-len 32768 --prefill-chunk-len 8192 --port 52625- Fire ~10 concurrent
/v1/chat/completionsrequests (multi-turn / with prior message history) in a tight window, repeat under sustained load. - Observe intermittent
double free or corruption/unaligned tcacheaborts on the server.
(We could not do controlled flag-isolation on our host because it has a single NPU that a live production tier is consuming — isolating would require a maintenance window or a second NPU box.)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/server/server.hpp, especially npu_request_queue_ and max_connections_, and inspect how conversation and KV-cache structures are accessed during concurrent requests. Reproduce the burst of about 10 /v1/chat/completions clients with prior message history, then try MALLOC_CHECK_=3 or an allocator preload. Done means the corruption site is identified and the server no longer aborts under the reported burst.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, linux
- Domain
- ai-infra-agents, backend-api-design
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100