if (flags == newflags)
return;
- fcntl(fd, F_SETFD, newflags); /* never fails */
+ if (fcntl(fd, F_SETFD, newflags)) /* never fails */
+ perror_msg_and_die("fcntl(%d, F_SETFD, %#x)", fd, newflags);
}
static void
* may create bogus empty FILE.<nonexistant_pid>, and then die.
*/
static void
-newoutf(struct tcb *tcp)
+after_successful_attach(struct tcb *tcp, const unsigned int flags)
{
+ tcp->flags |= TCB_ATTACHED | TCB_STARTUP | flags;
tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
if (followfork >= 2) {
char name[PATH_MAX];
xsprintf(name, "%s.%u", outfname, tcp->pid);
tcp->outf = strace_fopen(name);
}
+
+#ifdef ENABLE_STACKTRACE
+ if (stack_trace_enabled)
+ unwind_tcb_init(tcp);
+#endif
}
static void
#if SUPPORTED_PERSONALITIES > 1
tcp->currpers = current_personality;
#endif
-
-#ifdef ENABLE_STACKTRACE
- if (stack_trace_enabled)
- unwind_tcb_init(tcp);
-#endif
-
nprocs++;
debug_msg("new tcb for pid %d, active tcbs:%d",
tcp->pid, nprocs);
free_tcb_priv_data(tcp);
#ifdef ENABLE_STACKTRACE
- if (stack_trace_enabled) {
+ if (stack_trace_enabled)
unwind_tcb_fin(tcp);
- }
#endif
- mmap_cache_delete(tcp, __func__);
+ if (tcp->mmap_cache)
+ tcp->mmap_cache->free_fn(tcp, __func__);
nprocs--;
debug_msg("dropped tcb for pid %d, %d remain", tcp->pid, nprocs);
return;
}
- tcp->flags |= TCB_ATTACHED | TCB_GRABBED | TCB_STARTUP |
- post_attach_sigstop;
- newoutf(tcp);
+ after_successful_attach(tcp, TCB_GRABBED | post_attach_sigstop);
debug_msg("attach to pid %d (main) succeeded", tcp->pid);
static const char task_path[] = "/proc/%d/task";
ptrace_attach_cmd, tid);
continue;
}
- debug_msg("attach to pid %d succeeded", tid);
- struct tcb *tid_tcp = alloctcb(tid);
- tid_tcp->flags |= TCB_ATTACHED | TCB_GRABBED |
- TCB_STARTUP | post_attach_sigstop;
- newoutf(tid_tcp);
+ after_successful_attach(alloctcb(tid),
+ TCB_GRABBED | post_attach_sigstop);
+ debug_msg("attach to pid %d succeeded", tid);
}
closedir(dir);
kill(pid, SIGCONT);
}
tcp = alloctcb(pid);
- tcp->flags |= TCB_ATTACHED | TCB_STARTUP
- | TCB_SKIP_DETACH_ON_FIRST_EXEC
- | (NOMMU_SYSTEM ? 0 : (TCB_HIDE_LOG | post_attach_sigstop));
- newoutf(tcp);
+ after_successful_attach(tcp, TCB_SKIP_DETACH_ON_FIRST_EXEC
+ | (NOMMU_SYSTEM ? 0
+ : (TCB_HIDE_LOG
+ | post_attach_sigstop)));
} else {
/* With -D, we are *child* here, the tracee is our parent. */
strace_child = strace_tracer_pid;
strace_tracer_pid = getpid();
tcp = alloctcb(strace_child);
tcp->flags |= TCB_SKIP_DETACH_ON_FIRST_EXEC | TCB_HIDE_LOG;
- /* attaching will be done later, by startup_attach */
- /* note: we don't do newoutf(tcp) here either! */
+ /*
+ * Attaching will be done later, by startup_attach.
+ * Note: we don't do after_successful_attach() here either!
+ */
/* NOMMU BUG! -D mode is active, we (child) return,
* and we will scribble over parent's stack!
#ifdef ENABLE_STACKTRACE
"k"
#endif
- "a:Ab:cCdDe:E:fFhiI:o:O:p:P:qrs:S:tTu:vVwxyz")) != EOF) {
+ "a:Ab:cCdDe:E:fFhiI:o:O:p:P:qrs:S:tTu:vVwxX:yz")) != EOF) {
switch (c) {
case 'a':
acolumn = string_to_uint(optarg);
case 'x':
xflag++;
break;
+ case 'X':
+ if (!strcmp(optarg, "raw"))
+ xlat_verbosity = XLAT_STYLE_RAW;
+ else if (!strcmp(optarg, "abbrev"))
+ xlat_verbosity = XLAT_STYLE_ABBREV;
+ else if (!strcmp(optarg, "verbose"))
+ xlat_verbosity = XLAT_STYLE_VERBOSE;
+ else
+ error_opt_arg(c, optarg);
+ break;
case 'y':
show_fd_path++;
break;
set_sighandler(SIGCHLD, SIG_DFL, ¶ms_for_tracee.child_sa);
#ifdef ENABLE_STACKTRACE
- if (stack_trace_enabled) {
- unsigned int tcbi;
-
+ if (stack_trace_enabled)
unwind_init();
- for (tcbi = 0; tcbi < tcbtabsize; ++tcbi) {
- unwind_tcb_init(tcbtab[tcbi]);
- }
- }
#endif
/* See if they want to run as another user. */
if (followfork) {
/* We assume it's a fork/vfork/clone child */
struct tcb *tcp = alloctcb(pid);
- tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
- newoutf(tcp);
+ after_successful_attach(tcp, post_attach_sigstop);
if (!qflag)
error_msg("Process %d attached", pid);
return tcp;