Skip to content

record_linux: parecord exit is not handled — no error reason, state stays record, stop while paused may leave it running #638

Closed

Description

@dpalic

Package version

record 7.1.2, record_linux 2.1.3

Environment

  • OS: Linux (Ubuntu 24.04, PulseAudio)
  • OS: Linux (Ubuntu 22.04, PulseAudio)

not tested yet, but will do later during fixing

  • OS: Linux (Ubuntu 26.04, PulseAudio)

Describe the bug

CapturePipeline starts parecord but never looks at how it ends:

  1. No reason when it fails.
    • stderr is drained into nothing and the exit code is never read (capture_pipeline.dart:98-106).
    • If parecord cannot connect (unknown device, no sound server), it exits with code 1 and prints the reason,
      for example Stream error: No such entity.
    • startStream() still succeeds, and the stream simply ends with 0 bytes. The caller cannot tell a failed start
      from a normal stop.
  2. The state stays record. When parecord ends on its own (failed start, crash, device gone), isRecording()
    stays true and onStateChanged() emits no stop. Only stop() resets the state (linux_recorder.dart:72-82).
  3. Stop while paused.
    • pause() freezes parecord with SIGSTOP (capture_pipeline.dart:72).
    • stop() then sends SIGTERM and drops the process (:81-82), without SIGCONT.
    • A stopped process does not act on SIGTERM until it is continued, so parecord can stay alive and keep the
      microphone open.
    • In general, stop() does not wait for the exit and has no SIGKILL fallback.

RecordConfig(encoder: AudioEncoder.pcm16bits, sampleRate: 16000, numChannels: 1)

To Reproduce

Steps to reproduce the behavior:

  1. startStream() with device: InputDevice(id: 'no-such-source', label: 'x').
  2. The stream ends at once with 0 bytes and no error event; isRecording() returns true.
  3. Start a stream, pause(), stop(); then pgrep -a parecord (item 3).

Expected behavior

  • An unrequested exit of parecord (non-zero code or signal) puts an error on the stream before done, with the
    exit code and the last stderr lines. A requested stop() still ends with done only.
  • The state goes back to stop when parecord ends.
  • stop() ends parecord for sure: continue it if it is paused, wait for the exit, and kill it if it does not end.

Additional context

I would like to send a PR with tests for this.

Activity

  1. llfbandit commented on Nov 5, 2026

    @llfbandit
    Owner

    Thanks for the report.

    This is already fixed in feature/route_change. I added a report on why parecord or ffmpeg exited.
    This will be included in incoming version 2.2.0.

    Closing

  2. dpalic commented on Nov 5, 2026

    @dpalic
    Author

    i did not see the #638 to be the similar issue.
    So I started already the fixing :(
    But anyway i have a some more cornercases found and would like to report them. So hope you will accept my PR based on your 2.2.0 patch too. this is also related to #640, so kindly asking you to wait for my PR, which hopefully fixes my isues fully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions