ROCm / ROCm/FastFlowLM

flm serve crashes with glibc heap corruption (double free / unaligned tcache) under concurrent request bursts — Linux / XDNA2, v0.9.43

Open
#608 3 comments 0 reactions 0 assignees View on GitHub

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 --versionFLM 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/completions requests near-simultaneously. Under steady/serialized traffic we have not reproduced it.
  • --ctx-len 32768 appears within limits (the model advertises 32k; community reports run --ctx-len 32000 fine), so context length alone does not look like the cause.
  • --prefill-chunk-len 8192 (2× the 4096 default) and --pmode turbo are 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

  1. Whether the internal request queue (npu_request_queue_, max_connections_ in src/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.
  2. Whether building/running under a hardened allocator (e.g. MALLOC_CHECK_=3, or a jemalloc/tcmalloc preload) reproduces or pinpoints the corruption site.
  3. Any known concurrency fix landing after v0.9.43.

Reproduction (approximate)

  1. flm serve qwen3-it:4b --pmode turbo --ctx-len 32768 --prefill-chunk-len 8192 --port 52625
  2. Fire ~10 concurrent /v1/chat/completions requests (multi-turn / with prior message history) in a tight window, repeat under sustained load.
  3. Observe intermittent double free or corruption / unaligned tcache aborts 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.