Page MenuHomePhabricator

Dump current PrettyStackTrace on SIGINFO (Ctrl-T)

Authored by jordan_rose on Jun 24 2019, 7:48 PM.



Support SIGINFO (and SIGUSR1 for POSIX purposes) to tell what long-running jobs are doing, as inspired by BSD tools (including on macOS), by dumping the current PrettyStackTrace.

This adds a new kind of signal handler for non-fatal "info" signals, similar to the "interrupt" handler that already exists for SIGINT (Ctrl-C). It then uses that handler to update a "generation count" managed by the PrettyStackTrace infrastructure, which is then checked whenever a PrettyStackTraceEntry is pushed or popped on each thread. If the generation has changed—i.e. if the user has pressed Ctrl-T—the stack trace is dumped, though unfortunately it can't include the deepest entry because that one is currently being constructed/destructed.

Out of scope:

  • Multiple SIGINFO callbacks. I don't know how interesting this is anyway, given that they're still bound by what a signal handler can do.
  • Windows support. Windows console programs don't seem to have a SIGINFO equivalent anyway, so when someone figures out the right thing, they can add equivalent support.
  • Choosing whether to include SIGUSR1. I did this just because it was mentioned when I was looking up things about SIGINFO, but SIGINFO is the one I care about, so if people tell me they're not sure about SIGUSR1 I'll just remove it.
  • Figuring out how to print the actual current PrettyStackTrace, instead of the parent one, despite the construction/destruction problem. The simplest answer I can think of requires changing all of the PrettyStackTraceEntry instances in existence, which probably isn't going to fly for something that's ultimately a convenience feature. Someone else can figure it out.

Diff Detail


Event Timeline

jordan_rose created this revision.Jun 24 2019, 7:48 PM
jfb added inline comments.Jun 24 2019, 9:15 PM

Why not use seq_cst everywhere? It's not in any critical path, the the small extra cost isn't relevant. I'm also not sure that you really need volatile here: AddSignalHandler also synchronizes so a sufficiently smart optimizer won't be able to prove that anything can be aggregated.


Technically, in C++11, you need to initialize std::atomic with ATOMIC_VAR_INIT.


Period at end of sentence


I'd rather have enum class SignalKind { IsKill, IsInfo }; instead of a bool parameter.



jordan_rose marked an inline comment as done.Jun 25 2019, 8:43 AM
jordan_rose added inline comments.

The store could be seq_cst, but I wanted the load to be unsychronized because I never want people thinking that PrettyStackTraces are expensive. It's also not AddSignalHandler we're doing here, but a bare setting of the signal function, which is the classic use for volatile.


Copying my justification about "there doesn't seem to be a SIGINFO equivalent on Windows" seemed…not great, since it might dissuade people from correcting Past Me. I can add it if you think it's an improvement, though.

jordan_rose retitled this revision from [WIP} Dump current PrettyStackTrace on SIGINFO (Ctrl-T) to Dump current PrettyStackTrace on SIGINFO (Ctrl-T).
jordan_rose edited the summary of this revision. (Show Details)

Made it a per-thread opt-in, leaving the potential for it to be useful in multi-threaded programs. (It's off by default.) Also added a SaveAndRestore of errno for SIGINFO handlers, though this one doesn't need it.

jfb accepted this revision.Jul 10 2019, 12:45 PM
jfb added inline comments.

I don't understand what ShouldEnable means.


Can you remove the function name from the comment while you're here?

This revision is now accepted and ready to land.Jul 10 2019, 12:45 PM
jordan_rose added inline comments.Jul 11 2019, 9:18 AM

This allows you to turn it back off if you want. Got a better name for the parameter?

jordan_rose marked an inline comment as done.Jul 11 2019, 9:25 AM
jordan_rose added inline comments.

I changed the summary comment to "Enables (or disables)". That's probably good enough.