From: Josh Stone Date: Tue, 2 Oct 2012 18:23:48 +0000 (-0700) Subject: stapdyn: Fork output from stdout/stderr X-Git-Tag: release-2.0~48 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=f1ae3f0464ee48c9bc51be5d640fddf888e23227;p=systemtap.git stapdyn: Fork output from stdout/stderr We're still using the target's stdio (PR14491), but we're now using separate FILE handles to do it, so we're not affected by the target closing its own stdout early. * runtime/dyninst/io.c (_stp_out, _stp_err): Private FILE handles. (_stp_clone_file): Clone a FILE handle, also setting FD_CLOEXEC. (_stp_warn, _stp_error, _stp_softerror, _stp_dbug): Use _stp_err. * runtime/dyninst/print.c )_stp_print_flush): Use _stp_err and _stp_out. * runtime/dyninst/runtime.h (stp_dyninst_ctor): Clone stderr and stdout. (stp_dyninst_dtor): Close _stp_err and _stp_out. --- diff --git a/runtime/dyninst/io.c b/runtime/dyninst/io.c index e464e6421..70ec9b786 100644 --- a/runtime/dyninst/io.c +++ b/runtime/dyninst/io.c @@ -14,7 +14,28 @@ #define WARN_STRING "WARNING: " #define ERR_STRING "ERROR: " -// XXX for now, all IO is going in-process to stdout/err +// XXX for now, all IO is going in-process to stdout/stderr via +// _stp_out/_stp_err; see runtime/dyninst/runtime.h for initialization. + +static FILE* _stp_out = NULL; +static FILE* _stp_err = NULL; + + +/* Clone a FILE* for private use. On error, fallback to the original. */ +static FILE* _stp_clone_file(FILE* file) +{ + int fd = dup(fileno(file)); + if (fd != -1) { + fcntl(fd, F_SETFD, FD_CLOEXEC); + FILE* newfile = fdopen(fd, "wb"); + if (newfile) + return newfile; + + close(fd); + } + return file; +} + /** Prints warning. * This function sends a warning message immediately to staprun. It @@ -27,9 +48,9 @@ static void _stp_warn (const char *fmt, ...) { va_list args; va_start(args, fmt); - fprintf(stderr, WARN_STRING); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); + fprintf(_stp_err, WARN_STRING); + vfprintf(_stp_err, fmt, args); + fprintf(_stp_err, "\n"); va_end(args); } @@ -48,9 +69,9 @@ static void _stp_error (const char *fmt, ...) { va_list args; va_start(args, fmt); - fprintf(stderr, ERR_STRING); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); + fprintf(_stp_err, ERR_STRING); + vfprintf(_stp_err, fmt, args); + fprintf(_stp_err, "\n"); va_end(args); // FIXME: need to exit here... // _stp_exit(); @@ -70,9 +91,9 @@ static void _stp_softerror (const char *fmt, ...) { va_list args; va_start(args, fmt); - fprintf(stderr, ERR_STRING); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); + fprintf(_stp_err, ERR_STRING); + vfprintf(_stp_err, fmt, args); + fprintf(_stp_err, "\n"); va_end(args); } @@ -81,9 +102,9 @@ static void _stp_dbug (const char *func, int line, const char *fmt, ...) { va_list args; va_start(args, fmt); - fprintf(stderr, "%s:%d: ", func, line); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); + fprintf(_stp_err, "%s:%d: ", func, line); + vfprintf(_stp_err, fmt, args); + fprintf(_stp_err, "\n"); va_end(args); } diff --git a/runtime/dyninst/print.c b/runtime/dyninst/print.c index 8c0e59886..eade758f6 100644 --- a/runtime/dyninst/print.c +++ b/runtime/dyninst/print.c @@ -24,10 +24,10 @@ static void _stp_print_kernel_info(char *vstr, int ctx, int num_probes) static inline void _stp_print_flush(void) { - fflush(stderr); + fflush(_stp_err); if (_stp_print_buf_used) { - fwrite(_stp_print_buf, _stp_print_buf_used, 1, stdout); - fflush(stdout); + fwrite(_stp_print_buf, _stp_print_buf_used, 1, _stp_out); + fflush(_stp_out); _stp_print_buf_used = 0; } } diff --git a/runtime/dyninst/runtime.h b/runtime/dyninst/runtime.h index d5c814462..c9589fb06 100644 --- a/runtime/dyninst/runtime.h +++ b/runtime/dyninst/runtime.h @@ -165,6 +165,13 @@ static void stp_dyninst_ctor(void) if (_stp_mem_fd != -1) { fcntl(_stp_mem_fd, F_SETFD, FD_CLOEXEC); } + + /* XXX We don't really want to be using the target's stdio. (PR14491) + * But while we are, clone our own FILE handles so we're not affected by + * the target's actions, liking closing stdout early. + */ + _stp_out = _stp_clone_file(stdout); + _stp_err = _stp_clone_file(stderr); } int stp_dyninst_session_init(void) @@ -197,6 +204,16 @@ static void stp_dyninst_dtor(void) if (_stp_mem_fd != -1) { close (_stp_mem_fd); } + + if (_stp_out && _stp_out != stdout) { + fclose(_stp_out); + _stp_out = stdout; + } + + if (_stp_err && _stp_err != stderr) { + fclose(_stp_err); + _stp_err = stderr; + } } #endif /* _STAPDYN_RUNTIME_H_ */