You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Windows/crashpad: breadcrumbs and scope changes block the calling thread with no upper bound (WaitNamedPipe(NMPWAIT_WAIT_FOREVER)) while crashpad_handler is busy #2182
every scope change (sentry_set_extra, sentry_set_tag, ...): crashpad_backend_flush_scope → CrashpadClient::WriteAttachment
When the pipe is busy, SendPayloadToCrashHandlerServer (util/win/registration_protocol_win.cc:163-169 on getsentry/crashpad master) retries ERROR_PIPE_BUSY with WaitNamedPipe(pipe_name, NMPWAIT_WAIT_FOREVER). The wait has no upper bound.
The pipe is busy more often than the design intends:
The server has kPipeInstances = 2 (util/win/exception_handler_server.h:146).
HandleWriteAttachment and HandleAppendAttachment acknowledge before disk I/O. The comment there says the purpose is to keep the client from blocking on slow disk I/O.
But the disk write then runs on the same pipe service thread. The instance is only disconnected and reconnected after the write finishes.
So when two writes are in flight, the third caller waits for the handler's disk. The trigger can be a burst of breadcrumbs, a slow disk, an antivirus scan, or a handler that gets no CPU.
SDKs call these functions from the app's main thread; in Unity, every log line becomes a breadcrumb. The result is an app hang of unbounded length. In production we see it as AppHang events (sentry-native's own detector) with the main thread in WaitNamedPipeW, from sentry.dll, lasting 5 s and more. We had 4 events from 3 users in one release.
Repro
Open both instances of \\.\pipe\crashpad_<pid>_* from another process (CreateFile twice, write nothing).
Call sentry_add_breadcrumb or sentry_set_extra. It blocks until the instances are released. We measured 12-13 s for a 14 s hold, and the app-hang detector reports it.
Suggestions
Bound the wait: use a finite WaitNamedPipe timeout, then drop or defer the write.
Or queue attachment writes to a background thread inside the client.
Workaround
We moved IScopeObserver calls to our own background thread. The main-thread write now takes about 0.02 ms in the same repro, and the hang report still carries the full scope and breadcrumbs.
Activity
linear-code commentedon Oct 8, 2026
NATIVE-235
jpnurmi commentedon Oct 9, 2026
Thanks for the report! We'll take a look.
ref(win): Expose RegisterHandlers for handler reinstallation
fix(win): Buffer attachment updates until a report is built
fix(win): buffer attachment updates (#174)
fix(crashpad): buffer attachment updates (#2190)