From 292d135b08c038bfab2874d7a8e2226fe741360e Mon Sep 17 00:00:00 2001 From: Ryan Goulden Date: Mon, 9 Apr 2018 15:12:04 -0700 Subject: [PATCH] Allow partial dup_stdout_on_close, add comments --- core/lib/globals_shared.h | 6 ++++-- core/unix/injector.c | 1 + core/unix/os.c | 24 +++++++++++++++++++----- core/unix/signal_private.h | 3 +++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/lib/globals_shared.h b/core/lib/globals_shared.h index 09352c039a7..776ac2af849 100644 --- a/core/lib/globals_shared.h +++ b/core/lib/globals_shared.h @@ -120,12 +120,14 @@ # define X86_64 #endif -/* DR_API EXPORT VERBATIM */ #include /* for USHRT_MAX */ #ifdef UNIX -# include /* Fix for case 5341. */ # include #endif +/* DR_API EXPORT VERBATIM */ +#ifdef UNIX +# include /* Fix for case 5341. And for pid_t (non-glibc) */ +#endif #ifdef WINDOWS /* allow nameless struct/union */ # pragma warning(disable: 4201) diff --git a/core/unix/injector.c b/core/unix/injector.c index ef9101203b6..dca36d80ce1 100644 --- a/core/unix/injector.c +++ b/core/unix/injector.c @@ -153,6 +153,7 @@ typedef struct _dr_inject_info_t { static bool inject_ptrace(dr_inject_info_t *info, const char *library_path); +/* "enum __ptrace_request request" is used by glibc, but musl uses "int". */ static long our_ptrace(int request, pid_t pid, void *addr, void *data); #endif diff --git a/core/unix/os.c b/core/unix/os.c index 93628ffeace..9ec59ac6a4c 100644 --- a/core/unix/os.c +++ b/core/unix/os.c @@ -6168,6 +6168,22 @@ cleanup_after_vfork_execve(dcontext_t *dcontext) HEAPACCT(ACCT_THREAD_MGT)); } +static void +set_stdfile_fileno(stdfile_t **stdfile, file_t file_no) { +#ifdef STDFILE_FILENO + (*stdfile)->STDFILE_FILENO = file_no; +#else + /* this occurs on musl libc */ + #warning stdfile_t is opaque; DynamoRIO will skip setting fds of libc FILEs. + /* only called by handle_close_pre(), so this warning is specific to that. */ + SYSLOG_INTERNAL_WARNING_ONCE( + "DynamoRIO cannot set the file descriptors of private libc FILEs on this " + "platform. Client usage of stdio.h stdin, stdout, or stderr may no longer " + "work as expected, because the app is closing the UNIX fds backing these." + ); +#endif +} + /* returns whether to execute syscall */ static bool handle_close_pre(dcontext_t *dcontext) @@ -6191,7 +6207,6 @@ handle_close_pre(dcontext_t *dcontext) /* Xref PR 258731 - duplicate STDOUT/STDERR when app closes them so we (or * a client) can continue to use them for logging. */ -#ifdef STDFILE_FILENO if (DYNAMO_OPTION(dup_stdout_on_close) && fd == STDOUT) { our_stdout = fd_priv_dup(fd); if (our_stdout < 0) /* no private fd available */ @@ -6205,7 +6220,7 @@ handle_close_pre(dcontext_t *dcontext) if (privmod_stdout != NULL && IF_CLIENT_INTERFACE_ELSE(INTERNAL_OPTION(private_loader), false)) { /* update the privately loaded libc's stdout _fileno. */ - (*privmod_stdout)->STDFILE_FILENO = our_stdout; + set_stdfile_fileno(privmod_stdout, our_stdout); } } if (DYNAMO_OPTION(dup_stderr_on_close) && fd == STDERR) { @@ -6221,7 +6236,7 @@ handle_close_pre(dcontext_t *dcontext) if (privmod_stderr != NULL && IF_CLIENT_INTERFACE_ELSE(INTERNAL_OPTION(private_loader), false)) { /* update the privately loaded libc's stderr _fileno. */ - (*privmod_stderr)->STDFILE_FILENO = our_stderr; + set_stdfile_fileno(privmod_stderr, our_stderr); } } if (DYNAMO_OPTION(dup_stdin_on_close) && fd == STDIN) { @@ -6237,10 +6252,9 @@ handle_close_pre(dcontext_t *dcontext) if (privmod_stdin != NULL && IF_CLIENT_INTERFACE_ELSE(INTERNAL_OPTION(private_loader), false)) { /* update the privately loaded libc's stdout _fileno. */ - (*privmod_stdin)->STDFILE_FILENO = our_stdin; + set_stdfile_fileno(privmod_stdin, our_stdin); } } -#endif return true; } diff --git a/core/unix/signal_private.h b/core/unix/signal_private.h index ec43c6e9d7e..9afb27f03b1 100644 --- a/core/unix/signal_private.h +++ b/core/unix/signal_private.h @@ -534,6 +534,9 @@ libc_sigismember(const sigset_t *set, int _sig) /* sigset_t is just a uint32 */ return TEST(1UL << sig, *set); #else + /* "set->__val" would be cleaner, but is glibc specific (e.g. musl libc + * uses __bits as the field name on sigset_t). + */ uint bits_per = 8*sizeof(ulong); return TEST(1UL << (sig % bits_per), ((const ulong *)set)[sig / bits_per]); #endif