#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
{
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);
}
{
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();
{
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);
}
{
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);
}
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)
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_ */