Skip to content

Commit

Permalink
libbpf-tools/sigsnoop: Allow to trace a signal list
Browse files Browse the repository at this point in the history
tools/killsnoop supports a signal list(47d7263),
it's reasonable to support the same feature in libbpf-tools/sigsnoop.

Signed-off-by: Dantezy <[email protected]>
  • Loading branch information
ZhangYet committed Jul 19, 2024
1 parent 47d7263 commit c9c0bab
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
25 changes: 18 additions & 7 deletions libbpf-tools/sigsnoop.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define MAX_ENTRIES 10240

const volatile pid_t filtered_pid = 0;
const volatile int target_signal = 0;
const volatile int target_signals = 0;
const volatile bool failed_only = false;

struct {
Expand All @@ -23,16 +23,28 @@ struct {
__uint(value_size, sizeof(__u32));
} events SEC(".maps");

static __always_inline
bool is_target_signal(int sig)
{
if (target_signals == 0)
return true;

if ((target_signals & (1 << (sig - 1))) == 0)
return false;

return true;
}

static int probe_entry(pid_t tpid, int sig)
{
struct event event = {};
__u64 pid_tgid;
__u32 pid, tid;

if (target_signal && sig != target_signal)
return 0;
if (!is_target_signal(sig))
return 0;

pid_tgid = bpf_get_current_pid_tgid();
pid_tgid = bpf_get_current_pid_tgid();
pid = pid_tgid >> 32;
tid = (__u32)pid_tgid;
if (filtered_pid && pid != filtered_pid)
Expand Down Expand Up @@ -124,9 +136,8 @@ int sig_trace(struct trace_event_raw_signal_generate *ctx)

if (failed_only && ret == 0)
return 0;

if (target_signal && sig != target_signal)
return 0;
if (!is_target_signal(sig))
return 0;

pid_tgid = bpf_get_current_pid_tgid();
pid = pid_tgid >> 32;
Expand Down
61 changes: 33 additions & 28 deletions libbpf-tools/sigsnoop.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
static volatile sig_atomic_t exiting = 0;

static pid_t target_pid = 0;
static int target_signal = 0;
static int target_signals = 0;
static bool failed_only = false;
static bool kill_only = false;
static bool signal_name = false;
Expand Down Expand Up @@ -69,33 +69,34 @@ const char *argp_program_version = "sigsnoop 0.1";
const char *argp_program_bug_address =
"https://github.com/iovisor/bcc/tree/master/libbpf-tools";
const char argp_program_doc[] =
"Trace standard and real-time signals.\n"
"\n"
"USAGE: sigsnoop [-h] [-x] [-k] [-n] [-p PID] [-s SIGNAL]\n"
"\n"
"EXAMPLES:\n"
" sigsnoop # trace signals system-wide\n"
" sigsnoop -k # trace signals issued by kill syscall only\n"
" sigsnoop -x # trace failed signals only\n"
" sigsnoop -p 1216 # only trace PID 1216\n"
" sigsnoop -s 9 # only trace signal 9\n";
"Trace standard and real-time signals.\n"
"\n"
"USAGE: sigsnoop [-h] [-x] [-k] [-n] [-p PID] [-s SIGNAL]\n"
"\n"
"EXAMPLES:\n"
" sigsnoop # trace signals system-wide\n"
" sigsnoop -k # trace signals issued by kill syscall only\n"
" sigsnoop -x # trace failed signals only\n"
" sigsnoop -p 1216 # only trace PID 1216\n"
" sigsnoop -s 1,9,15 # trace signal 1, 9, 15\n";

static const struct argp_option opts[] = {
{ "failed", 'x', NULL, 0, "Trace failed signals only.", 0 },
{ "kill", 'k', NULL, 0, "Trace signals issued by kill syscall only.", 0 },
{ "pid", 'p', "PID", 0, "Process ID to trace", 0 },
{ "signal", 's', "SIGNAL", 0, "Signal to trace.", 0 },
{ "name", 'n', NULL, 0, "Output signal name instead of signal number.", 0 },
{ "verbose", 'v', NULL, 0, "Verbose debug output", 0 },
{ NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help", 0 },
{},
{"failed", 'x', NULL, 0, "Trace failed signals only.", 0},
{"kill", 'k', NULL, 0, "Trace signals issued by kill syscall only.", 0},
{"pid", 'p', "PID", 0, "Process ID to trace", 0},
{"signal", 's', "SIGNAL", 0, "Signals to trace.", 0},
{"name", 'n', NULL, 0, "Output signal name instead of signal number.", 0},
{"verbose", 'v', NULL, 0, "Verbose debug output", 0},
{NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help", 0},
{},
};

static error_t parse_arg(int key, char *arg, struct argp_state *state)
{
long pid, sig;
char* token;

switch (key) {
switch (key) {
case 'p':
errno = 0;
pid = strtol(arg, NULL, 10);
Expand All @@ -107,13 +108,17 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state)
break;
case 's':
errno = 0;
sig = strtol(arg, NULL, 10);
if (errno || sig <= 0) {
warn("Invalid SIGNAL: %s\n", arg);
argp_usage(state);
}
target_signal = sig;
break;
token = strtok(arg, ",");
while (token) {
sig = strtol(token, NULL, 10);
if (errno || sig <= 0 || sig > 31) {
warn("Inavlid SIGNAL: %s\n", token);
argp_usage(state);
}
target_signals |= (1 << (sig - 1));
token = strtok(NULL, ",");
}
break;
case 'n':
signal_name = true;
break;
Expand Down Expand Up @@ -204,7 +209,7 @@ int main(int argc, char **argv)
}

obj->rodata->filtered_pid = target_pid;
obj->rodata->target_signal = target_signal;
obj->rodata->target_signals = target_signals;
obj->rodata->failed_only = failed_only;

if (kill_only) {
Expand Down

0 comments on commit c9c0bab

Please sign in to comment.