Skip to content

Windows: a Rust/C++/COBOL program's last output is lost when it does not end in a newline #860

Description

@debugmcpdev

What happens

On Windows, if the last thing a Rust, C/C++ or COBOL program prints does not end in a newline, that text never reaches get_output (or the output resource).

#include <cstdio>
int main() {
    std::printf("first line\n");
    std::printf("result: 42");   // no newline
    return 0;
}

start_debugging on this file answers stopped, exit code 0; get_output returns first line\n and nothing else. result: 42 is gone. Same on main at f3cbde3 and with #859 applied.

Why

On Windows the debuggee inherits CodeLLDB's stdio pipes, and the proxy forwards what it reads from them as output (#223). GenericAdapterManager.consumeStream splits that stream into lines with a LineBuffer and forwards complete lines only; the trailing fragment is flushed on the stream's end/close. CodeLLDB outlives its debuggee and keeps the pipes open until the session is torn down, so the fragment is flushed during teardown — after exited/terminated have been forwarded and the session has stopped listening.

rdbg -c is not affected: its pipes close with the program, and the flush happens before the exit is forwarded.

The comment on consumeStream explains why the flush is tied to the stream's own end/close and not to process exit (a secret split across two chunks must not be logged in halves, #151). That reasoning is about the sanitized log path and about the adapter process's exit; it does not cover the case here, where the debuggee has ended but the adapter has not.

Possible fix

For an adapter that outlives its debuggee (forwardStdio.adapterOutlivesDebuggee, #859), flush the forwarder's partial line when the exit-time drain settles — the adapter has reported the exit and the pipes have gone quiet, so the fragment is the program's last word, not half of a line still being written. The flush has to happen before exited is forwarded, and should go through the same forwarding path as a complete line.

Reproduce

Windows, create_debug_session {language: "cpp"}, start_debugging on the file above (the adapter compiles it), then get_output {sessionId, since: 0}.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions