This is an archive of the discontinued LLVM Phabricator instance.

[Support] Emulate SIGPIPE handling in raw_fd_ostream write for Windows
ClosedPublic

Authored by andrewng on Jan 20 2023, 8:19 AM.

Diff Detail

Event Timeline

andrewng created this revision.Jan 20 2023, 8:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 20 2023, 8:19 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
andrewng requested review of this revision.Jan 20 2023, 8:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 20 2023, 8:19 AM
MaskRay accepted this revision.Jan 31 2023, 9:38 AM

I don't know much about Windows. Best to wait for @mstorsjo

llvm/lib/Support/Windows/Signals.inc
210

ATOMIC_VAR_INIT is deprecated. Just use nullptr?

This revision is now accepted and ready to land.Jan 31 2023, 9:38 AM

I think this looks fine, but I'm not really familiar with this area of the code. Do @aganea or @thakis or @hans want to comment on it? Otherwise I think it's probably fine...

Also, while I kinda see what this does in a code level, can you describe what this changes from a user point of view - does some usecase behave differently?

Half relatedly - I remember seeing some other discussion (I don’t have a reference handy right now) about changes to sigpipe handling; right now, if doing e.g. clang -E | less, you get a rather ugly crash for the clang process, if exiting less before the end of the clang output. (I remember seeing wishes to not treat this like a regular crash.)

Sorry for the spam. Test coverage would be welcome too :-) The following should exercise the crash: RUN: llvm-readobj --help | head -c1

Thanks for spotting this.

Sorry for the spam. Test coverage would be welcome too :-) The following should exercise the crash: RUN: llvm-readobj --help | head -c1

Yes, I did consider adding something like this as a simple test but it does kind of assume that llvm-readobj --help is using raw_ostream. But if you think it has value then I'll add it.

andrewng added a comment.EditedFeb 2 2023, 2:56 AM

Also, while I kinda see what this does in a code level, can you describe what this changes from a user point of view - does some usecase behave differently?

Half relatedly - I remember seeing some other discussion (I don’t have a reference handy right now) about changes to sigpipe handling; right now, if doing e.g. clang -E | less, you get a rather ugly crash for the clang process, if exiting less before the end of the clang output. (I remember seeing wishes to not treat this like a regular crash.)

Yes, this patch addresses the issue you've described which is also mentioned in issue https://github.com/llvm/llvm-project/issues/48672 (although there it is clang --help).

andrewng updated this revision to Diff 494302.Feb 2 2023, 7:21 AM

Updated for review suggestions.

Sorry for the spam. Test coverage would be welcome too :-) The following should exercise the crash: RUN: llvm-readobj --help | head -c1

Yes, I did consider adding something like this as a simple test but it does kind of assume that llvm-readobj --help is using raw_ostream. But if you think it has value then I'll add it.

I tried adding this "simple" test but unfortunately it doesn't reproduce the issue in lit. I think it has something to do with how lit handles the piping. Would it be OK without a test?

andrewng marked an inline comment as done.Feb 2 2023, 7:22 AM

Also, while I kinda see what this does in a code level, can you describe what this changes from a user point of view - does some usecase behave differently?

Half relatedly - I remember seeing some other discussion (I don’t have a reference handy right now) about changes to sigpipe handling; right now, if doing e.g. clang -E | less, you get a rather ugly crash for the clang process, if exiting less before the end of the clang output. (I remember seeing wishes to not treat this like a regular crash.)

Yes, this patch addresses the issue you've described which is also mentioned in issue https://github.com/llvm/llvm-project/issues/48672 (although there it is clang --help).

Oh, sorry that I entirely missed the link in the review description. Then the purpose of the patch is much clearer!

This patch does indeed fix the issue for clang --help, but doesn't make any difference for clang -E. Do you happen to know how hard it would be to fix the same issue for clang -E too? (I've noticed that clang -E | less did show errors in clang 15.0 on unix too, but not in 14.0 and not in current git main.)

I did a bit more digging on the unix side, and https://github.com/llvm/llvm-project/issues/59037 and https://reviews.llvm.org/D138244 fixed the issue for clang -E on the unix side. Is there something that we could do about the default handler here, not specific to raw_ostream?

I tried adding this "simple" test but unfortunately it doesn't reproduce the issue in lit. I think it has something to do with how lit handles the piping. Would it be OK without a test?

These kinds of things are usually kinda tricky to test reliably, so FWIW, I'd be ok with landing this without a testcase for it.

andrewng updated this revision to Diff 494604.Feb 3 2023, 6:05 AM
andrewng edited the summary of this revision. (Show Details)

I did a bit more digging on the unix side, and https://github.com/llvm/llvm-project/issues/59037 and https://reviews.llvm.org/D138244 fixed the issue for clang -E on the unix side. Is there something that we could do about the default handler here, not specific to raw_ostream?

This patch now also fixes the clang -E related issue on Windows. Was more complicated than expected...

mstorsjo accepted this revision.Feb 8 2023, 5:21 AM

I did a bit more digging on the unix side, and https://github.com/llvm/llvm-project/issues/59037 and https://reviews.llvm.org/D138244 fixed the issue for clang -E on the unix side. Is there something that we could do about the default handler here, not specific to raw_ostream?

This patch now also fixes the clang -E related issue on Windows. Was more complicated than expected...

Thanks - this now seems to work great! Sorry for adding the extra detour, but it was much appreciated!

llvm/lib/Support/Windows/Signals.inc
831

Do you have any reference for/comment about what 0xE0000000 is here?

andrewng added inline comments.Feb 8 2023, 7:57 AM
llvm/lib/Support/Windows/Signals.inc
831

The constant is used in CrashRecoveryContext::HandleExit() to raise an exception on Windows. I'll add a comment.

aganea added inline comments.Feb 8 2023, 8:52 AM
llvm/lib/Support/Windows/Signals.inc
831

That is not super-well documented in the Windows APIs. The 0xE prefix is the recommended way to throw user exceptions, it's actually a NTSTATUS code, with bit 29 set (that is, customer) and bits 30, 31 set (that is, STATUS_SEVERITY_ERROR): https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/87fba13e-bf06-450e-83b1-9241dc81e781
This prefix code is also used for C++ exceptions in the MSVC ABI.

andrewng updated this revision to Diff 495867.Feb 8 2023, 8:52 AM

Updated to add comment regarding the strange looking use of 0xE0000000.

mstorsjo accepted this revision.Feb 8 2023, 1:05 PM

Updated to add comment regarding the strange looking use of 0xE0000000.

Thanks, LGTM!

llvm/lib/Support/Windows/Signals.inc
831

Thanks @aganea - perhaps we should explain this as reference in CrashRecoveryContext::HandleExit()? (Within this particular case, it's IMO enough to just reference CrashRecoveryContext::HandleExit().)

Herald added a project: Restricted Project. · View Herald TranscriptFeb 9 2023, 2:39 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
erichkeane added inline comments.
llvm/lib/Support/Windows/Signals.inc
834

This patch seems to cause a self-build Werror regression. The mask here is large enough to cause the RHS of this to be unsigned, so the comparison hits -Wsign-compare. See the example here https://godbolt.org/z/fa5q889jh

aganea added inline comments.Feb 24 2023, 12:05 PM
llvm/lib/Support/Windows/Signals.inc
834
erichkeane added inline comments.Feb 24 2023, 12:07 PM
llvm/lib/Support/Windows/Signals.inc
834

Wonderful, thanks! Looks like our build system didn't get to that yet.

mstorsjo added inline comments.Feb 26 2023, 2:51 PM
llvm/lib/Support/Windows/Signals.inc
834

Thanks @aganea for the fix! This has been backported to 16.x, so I filed a request to backport your warning fix too, see https://github.com/llvm/llvm-project/issues/61012.