Skip to content

Commit 782245c

Browse files
committed
SymbolizerProcess should hold on to the read end of the stdin pipe so we don't get SIGPIPE
1 parent 5bf0fa0 commit 782245c

File tree

4 files changed

+22
-3
lines changed

4 files changed

+22
-3
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,14 @@ bool internal_spawn(const char* argv[], const char* envp[], pid_t* pid,
285285
fd_t fd_stdin, fd_t fd_stdout) {
286286
// NOTE: Caller ensures that fd_stdin and fd_stdout are not 0, 1, or 2, since
287287
// this can break communication.
288+
//
289+
// NOTE: Caller is responsible for closing fd_stdin after the process has
290+
// died.
288291

289292
int res;
290293
auto fd_closer = at_scope_exit([&] {
291-
internal_close(fd_stdin);
294+
// NOTE: We intentionally do not close fd_stdin since this can
295+
// cause us to receive a fatal SIGPIPE if the process dies.
292296
internal_close(fd_stdout);
293297
});
294298

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class SymbolizerProcess {
8383
const char *SendCommand(const char *command);
8484

8585
protected:
86-
~SymbolizerProcess() {}
86+
~SymbolizerProcess();
8787

8888
/// The maximum number of arguments required to invoke a tool process.
8989
static const unsigned kArgVMax = 16;
@@ -114,6 +114,10 @@ class SymbolizerProcess {
114114
fd_t input_fd_;
115115
fd_t output_fd_;
116116

117+
// We hold on to the child's stdin fd (the read end of the pipe)
118+
// so that when we write to it, we don't get a SIGPIPE
119+
fd_t child_stdin_fd_;
120+
117121
InternalMmapVector<char> buffer_;
118122

119123
static const uptr kMaxTimesRestarted = 5;

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,10 +476,11 @@ const char *LLVMSymbolizer::FormatAndSendCommand(const char *command_prefix,
476476
return symbolizer_process_->SendCommand(buffer_);
477477
}
478478

479-
SymbolizerProcess::SymbolizerProcess(const char *path, bool use_posix_spawn)
479+
SymbolizerProcess::SymbolizerProcess(const char* path, bool use_posix_spawn)
480480
: path_(path),
481481
input_fd_(kInvalidFd),
482482
output_fd_(kInvalidFd),
483+
child_stdin_fd_(kInvalidFd),
483484
times_restarted_(0),
484485
failed_to_start_(false),
485486
reported_invalid_path_(false),
@@ -488,6 +489,11 @@ SymbolizerProcess::SymbolizerProcess(const char *path, bool use_posix_spawn)
488489
CHECK_NE(path_[0], '\0');
489490
}
490491

492+
SymbolizerProcess::~SymbolizerProcess() {
493+
if (child_stdin_fd_ != kInvalidFd)
494+
CloseFile(child_stdin_fd_);
495+
}
496+
491497
static bool IsSameModule(const char *path) {
492498
if (const char *ProcessName = GetProcessName()) {
493499
if (const char *SymbolizerName = StripModuleName(path)) {
@@ -533,6 +539,8 @@ bool SymbolizerProcess::Restart() {
533539
CloseFile(input_fd_);
534540
if (output_fd_ != kInvalidFd)
535541
CloseFile(output_fd_);
542+
if (child_stdin_fd_ != kInvalidFd)
543+
CloseFile(output_fd_);
536544
return StartSymbolizerSubprocess();
537545
}
538546

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() {
192192
input_fd_ = infd[0];
193193
output_fd_ = outfd[1];
194194

195+
// We intentionally hold on to the read-end so that we don't get a SIGPIPE
196+
child_stdin_fd_ = outfd[0];
197+
195198
CHECK_GT(pid, 0);
196199

197200
// Check that symbolizer subprocess started successfully.

0 commit comments

Comments
 (0)