Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@garazdawi
Copy link
Contributor

The primary reason that we do this is to make writing to standard_error as synchronous as possible. When using the fd driver the write was done on an async thread, which meant that there was no simple way to get an acknowledgement when the write had completed. Now that we use a NIF we can much more easily get a check when the write is done so that we know when io:format(standard_error, ...) has returned we have also written to that fd.

@garazdawi garazdawi added team:VM Assigned to OTP team VM enhancement labels Nov 26, 2024
@garazdawi garazdawi added this to the OTP-28.0 milestone Nov 26, 2024
@garazdawi garazdawi self-assigned this Nov 26, 2024
@github-actions
Copy link
Contributor

github-actions bot commented Nov 26, 2024

CT Test Results

    4 files    200 suites   1h 51m 51s ⏱️
3 044 tests 2 755 ✅ 287 💤 2 ❌
4 009 runs  3 649 ✅ 358 💤 2 ❌

For more details on these failures, see this check.

Results for commit ba6446b.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@garazdawi garazdawi force-pushed the lukas/kernel/blocking-stderr branch from dd4251d to ba6446b Compare November 27, 2024 09:05
@garazdawi garazdawi added the testing currently being tested, tag is used by OTP internal CI label Dec 10, 2024
frazze-jobb
frazze-jobb previously approved these changes Dec 11, 2024
@garazdawi garazdawi force-pushed the lukas/kernel/blocking-stderr branch from ba6446b to d79b98a Compare December 17, 2024 08:52
standard_error is started before the on_load handlers in init
are run, so prim_tty will not be completely loaded when running
in embedded mode. So we call it during init of prim_tty instead.
The primary reason that we do this is to make writing to standard_error
as synchronous as possible. When using the fd driver the write was
done on an async thread, which meant that there was no simple way
to get an acknowledgement when the write had completed. Now that we
use a NIF we can much more easily get a check when the write is done
so that we know when io:format(standard_error, ...) has returned we
have also written to that fd.
@garazdawi garazdawi merged commit edfc0df into erlang:master Dec 17, 2024
24 checks passed
NelsonVides added a commit to NelsonVides/otp that referenced this pull request Oct 16, 2025
Fix a race condition where the standard_error process could call
prim_tty:init/1 before being registered, causing a crash when prim_tty's
writer and reader processes attempt to derive their own registered names
from the parent process.

The issue was introduced in commit
ead7424 (PR erlang#9116), which changed
prim_tty's reader and writer processes to dynamically derive their
registered names from their parent process name (e.g., 'standard_error'
-> 'standard_error_reader', 'standard_error_writer'). This was done
to support multiple TTY instances (stdout and stderr) with
distinct process names.

However, the standard_error:start/0 function had a race condition:
1. spawn(fun server/0) - creates process, starts executing immediately
2. register(?NAME, Id) - parent registers the spawned process
3. server() calls prim_tty:init() - may execute before step 2

When prim_tty:init/1 spawns writer/reader processes, they call
set_name(Parent, Postfix) which does: erlang:process_info(Parent,
registered_name)

If this executes before the parent completes registration, it returns []
instead of {registered_name, standard_error}, causing a pattern match
failure: "no match of right hand side value: []" at prim_tty.erl:674.

The fix moves the register/2 call into the spawned process itself,
ensuring it completes before prim_tty:init/1 is called. This eliminates
the race condition entirely.

Closes erlang#10174
frazze-jobb pushed a commit to NelsonVides/otp that referenced this pull request Oct 23, 2025
Fix a race condition where the standard_error process could call
prim_tty:init/1 before being registered, causing a crash when prim_tty's
writer and reader processes attempt to derive their own registered names
from the parent process.

The issue was introduced in commit
ead7424 (PR erlang#9116), which changed
prim_tty's reader and writer processes to dynamically derive their
registered names from their parent process name (e.g., 'standard_error'
-> 'standard_error_reader', 'standard_error_writer'). This was done
to support multiple TTY instances (stdout and stderr) with
distinct process names.

However, the standard_error:start/0 function had a race condition:
1. spawn(fun server/0) - creates process, starts executing immediately
2. register(?NAME, Id) - parent registers the spawned process
3. server() calls prim_tty:init() - may execute before step 2

When prim_tty:init/1 spawns writer/reader processes, they call
set_name(Parent, Postfix) which does: erlang:process_info(Parent,
registered_name)

If this executes before the parent completes registration, it returns []
instead of {registered_name, standard_error}, causing a pattern match
failure: "no match of right hand side value: []" at prim_tty.erl:674.

The fix moves the register/2 call into the spawned process itself,
ensuring it completes before prim_tty:init/1 is called. This eliminates
the race condition entirely.

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

Labels

enhancement team:VM Assigned to OTP team VM testing currently being tested, tag is used by OTP internal CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants