This is an archive of the discontinued LLVM Phabricator instance.

Dump current PrettyStackTrace on SIGINFO (Ctrl-T)
ClosedPublic

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

Details

Reviewers
jfb
Summary

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

Repository
rL LLVM

Event Timeline

jordan_rose created this revision.Jun 24 2019, 7:48 PM
jfb added inline comments.Jun 24 2019, 9:15 PM
lib/Support/PrettyStackTrace.cpp
51

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.

52

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

lib/Support/Unix/Signals.inc
231

Period at end of sentence

296–297

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

lib/Support/Windows/Signals.inc
560

wai?

jordan_rose marked an inline comment as done.Jun 25 2019, 8:43 AM
jordan_rose added inline comments.
lib/Support/PrettyStackTrace.cpp
51

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.

lib/Support/Windows/Signals.inc
560

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.
include/llvm/Support/PrettyStackTrace.h
38

I don't understand what ShouldEnable means.

lib/Support/PrettyStackTrace.cpp
88

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
include/llvm/Support/PrettyStackTrace.h
38

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.
include/llvm/Support/PrettyStackTrace.h
38

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

I have build problem with clang.
can you help me fix it?

In file included from external/llvm/lib/Support/Signals.cpp:220:
external/llvm/lib/Support/Unix/Signals.inc:388:23: error: no matching constructor for initialization of 'SaveAndRestore<int>'

SaveAndRestore<int> SaveErrnoDuringASignalHandler(errno);
                    ^                             ~~~~~

external/llvm/lib/Support/../../include/llvm/Support/SaveAndRestore.h:21:30: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'volatile int' to 'const llvm::SaveAndRestore<int>' for 1st argument
template <typename T> struct SaveAndRestore {

^

external/llvm/lib/Support/../../include/llvm/Support/SaveAndRestore.h:22:3: note: candidate constructor not viable: 1st argument ('volatile int') would lose volatile qualifier

SaveAndRestore(T &X) : X(X), OldValue(X) {}
^

external/llvm/lib/Support/../../include/llvm/Support/SaveAndRestore.h:23:3: note: candidate constructor not viable: requires 2 arguments, but 1 was provided

SaveAndRestore(T &X, const T &NewValue) : X(X), OldValue(X) {
^