Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions cmd/stbtrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import argparse
import json
import os
import signal
import sys
base_dir = os.path.dirname(__file__) + "/../"
if not os.path.exists(base_dir + "lib/iterative_template.py"):
Expand Down Expand Up @@ -129,16 +130,35 @@
node != 'title':
template.addSingleton(node, data[node])


#
# bcc detaches the probes from an atexit callback, which runs once the
# interpreter has started shutting down and with signal delivery still
# enabled. An interrupt that lands inside the detach aborts it and prints
# the callback's traceback to stderr, even though the trace itself finished
# and its datapoints are complete. Ignore the interrupt as soon as the
# first one is taken, so the detach always runs to completion.
#
def ignore_interrupt():
signal.signal(signal.SIGINT, signal.SIG_IGN)


def exit_on_interrupt(signum, frame):
ignore_interrupt()
exit(0)


# Perform template substitutions and execute or output the resulting script
script = template.render()
if args.bcc:
print(script, end='')
exit(0)
else:
signal.signal(signal.SIGINT, exit_on_interrupt)
try:
exec(script)
except KeyboardInterrupt:
exit(0)
except Exception as e:
print(e)
exit(1)
finally:
ignore_interrupt()
5 changes: 4 additions & 1 deletion lib/bcchelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,12 @@ def __init__(self, b, mode=DEFAULT_PRINT_MODE):
#
# Try to run atexit handlers if we are killed by a signal. BCC
# registers handlers to detach kprobes, and if these aren't run the
# probes are leaked.
# probes are leaked. Ignore the signal before exiting, so that a
# later one cannot land inside the detach and leave its traceback
# on stderr.
#
def _handler(signum, frame):
signal.signal(signal.SIGTERM, signal.SIG_IGN)
exit(1)
signal.signal(signal.SIGTERM, _handler)

Expand Down
Loading