Skip to content

Avoid deadlocks after fork#303

Open
danth wants to merge 5 commits into
eclipse-score:mainfrom
etas-contrib:avoid-deadlocks-after-fork
Open

Avoid deadlocks after fork#303
danth wants to merge 5 commits into
eclipse-score:mainfrom
etas-contrib:avoid-deadlocks-after-fork

Conversation

@danth

@danth danth commented Jul 9, 2026

Copy link
Copy Markdown
Member

Fork only copies the current thread, so from that point on we could deadlock if we access anything that was locked by another thread at the time of the fork.

As such we should play it safe and use only basic functions. This means assertions rather than logs for fatal errors, and no logging at all on the happy path.

@danth

This comment was marked as outdated.

@danth
danth force-pushed the avoid-deadlocks-after-fork branch from bcb913a to 2a70190 Compare July 10, 2026 08:09
@danth
danth requested a deployment to workflow-approval July 10, 2026 08:09 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 10, 2026 08:09 — with GitHub Actions Waiting
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown

License Check Results

🚀 The license check job ran with the Bazel command:

bazel run --lockfile_mode=error //:license-check

Status: ⚠️ Needs Review

Click to expand output
[License Check Output]
Extracting Bazel installation...
Starting local Bazel server (8.6.0) and connecting to it...
INFO: Invocation ID: 26e2548c-92a5-46c9-8637-66c9db433dde
Computing main repo mapping: 
Computing main repo mapping: 
Loading: 
Loading: 0 packages loaded
Loading: 0 packages loaded
Loading: 0 packages loaded
    currently loading: 
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)
Analyzing: target //:license-check (1 packages loaded, 0 targets configured)

Analyzing: target //:license-check (44 packages loaded, 10 targets configured)

Analyzing: target //:license-check (141 packages loaded, 539 targets configured)

Analyzing: target //:license-check (155 packages loaded, 5498 targets configured)

Analyzing: target //:license-check (161 packages loaded, 5547 targets configured)

Analyzing: target //:license-check (161 packages loaded, 5547 targets configured)

Analyzing: target //:license-check (164 packages loaded, 7434 targets configured)

Analyzing: target //:license-check (164 packages loaded, 7434 targets configured)

Analyzing: target //:license-check (164 packages loaded, 7434 targets configured)

Analyzing: target //:license-check (168 packages loaded, 10283 targets configured)

Analyzing: target //:license-check (168 packages loaded, 10283 targets configured)

Analyzing: target //:license-check (168 packages loaded, 10283 targets configured)

Analyzing: target //:license-check (168 packages loaded, 10283 targets configured)

Analyzing: target //:license-check (168 packages loaded, 10283 targets configured)

INFO: Analyzed target //:license-check (169 packages loaded, 10409 targets configured).
[13 / 16] Generating Dash formatted dependency file ...; 0s disk-cache, processwrapper-sandbox ... (2 actions, 1 running)
[15 / 16] Building license.check.license_check.jar (); 0s disk-cache, multiplex-worker
INFO: Found 1 target...
Target //:license.check.license_check up-to-date:
  bazel-bin/license.check.license_check
  bazel-bin/license.check.license_check.jar
INFO: Elapsed time: 25.056s, Critical Path: 1.95s
INFO: 16 processes: 12 internal, 3 processwrapper-sandbox, 1 worker.
INFO: Build completed successfully, 16 total actions
INFO: Running command line: bazel-bin/license.check.license_check ./formatted.txt <args omitted>
usage: org.eclipse.dash.licenses.cli.Main [-batch <int>] [-cd <url>]
       [-confidence <int>] [-ef <url>] [-excludeSources <sources>] [-help] [-lic
       <url>] [-project <shortname>] [-repo <url>] [-review] [-summary <file>]
       [-timeout <seconds>] [-token <token>]

@github-actions

Copy link
Copy Markdown

The created documentation from the pull request is available at: docu-html

@danth
danth force-pushed the avoid-deadlocks-after-fork branch from 2a70190 to 9cc08d6 Compare July 10, 2026 08:22
@danth
danth requested a deployment to workflow-approval July 10, 2026 08:22 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 10, 2026 08:22 — with GitHub Actions Waiting
@danth
danth force-pushed the avoid-deadlocks-after-fork branch from 9cc08d6 to 67c0d0f Compare July 14, 2026 09:57
@danth
danth requested a deployment to workflow-approval July 14, 2026 09:57 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 14, 2026 09:57 — with GitHub Actions Waiting
@danth
danth force-pushed the avoid-deadlocks-after-fork branch from 67c0d0f to 9c28979 Compare July 14, 2026 10:05
@danth
danth requested a deployment to workflow-approval July 14, 2026 10:05 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 14, 2026 10:05 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 14, 2026 10:37 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 14, 2026 10:37 — with GitHub Actions Waiting
@danth
danth force-pushed the avoid-deadlocks-after-fork branch from e249b48 to 4121230 Compare July 15, 2026 10:33
@danth
danth requested a deployment to workflow-approval July 15, 2026 10:33 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 15, 2026 10:33 — with GitHub Actions Waiting
};

const auto result = ::setrlimit(resource, &limit);
SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have the same async signal safe issue with the assert message, as the string concatenation may cause heap allocation which is not async signal safe

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could remove the extra info and just use strerror as the message

@danth danth Jul 16, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: strerror is not async signal safe either, there is strerrordesc_np but it's not standard

};

const auto result = ::setrlimit(resource, &limit);
SCORE_LANGUAGE_FUTURECPP_ASSERT_PRD_MESSAGE(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bazel assort macros terminate the process using std::abort(). Is this safe to terminate the process this way btw. fork() and execve()?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

abort is async signal safe in POSIX, not sure if std::abort is doing anything extra?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think here it is not so much about the signal safety, but other considerations what is being cleaned up: https://www.unixguide.net/unix/programming/1.1.3.shtml

Not sure though exactly what is the difference btw. _exit and std::abort, but If I remember correctly using _exit() is the recommended way to terminate a process btw. fork and execve in case of error

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more info- std::abort and abort are one and the same. abort does no more cleanup than _exit. The main difference is that abort sends SIGABRT which triggers a core dump whereas _exit ends the process normally

@paulquiring

paulquiring commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

One thing we need to consider:

fork
// only AS safe functions are allowed  
excev

the assert handler implementation as is looks quite okay for all non AS safe use cases. So we might want write an own function which does AS safe prints with write(STDERR_FILENO, msg, msg_len), msg is a fixed string to avoid allocations (e.g long string + std::string("something")). Our own function does sysexit() after the print.

@danth
danth force-pushed the avoid-deadlocks-after-fork branch from 4121230 to 6adb4b7 Compare July 16, 2026 08:14
@danth
danth requested a deployment to workflow-approval July 16, 2026 08:14 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 16, 2026 08:14 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 17, 2026 09:01 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 17, 2026 09:01 — with GitHub Actions Waiting
The executable could be incorrectly seen as missing if it is on a filesystem which has not been mounted yet. `execve` already fails if the executable does not exist so there is no need to check in advance.
@danth
danth requested a deployment to workflow-approval July 17, 2026 09:37 — with GitHub Actions Waiting
@danth
danth requested a deployment to workflow-approval July 17, 2026 09:37 — with GitHub Actions Waiting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

4 participants