Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

retsnoop: handle idle threads properly #71

Merged
merged 1 commit into from
Aug 28, 2024
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
2 changes: 1 addition & 1 deletion src/fnargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ int prepare_ctx_args_specs(int probe_id, const struct inj_probe_info *inj)
{
struct ctx_args_info *ctx_args;
char desc[256];
int i, err;
int i, err = -EINVAL;

snprintf_inj_probe(desc, sizeof(desc), inj);

Expand Down
52 changes: 27 additions & 25 deletions src/logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,27 @@ static void free_sessions(void)
hashmap__clear(&sessions_hash);
}

static void purge_session(struct ctx *ctx, int pid)
static void purge_session(struct ctx *ctx, int sess_id)
{
struct session *sess;

if (hashmap__delete(&sessions_hash, (long)pid, NULL, &sess))
if (hashmap__delete(&sessions_hash, (long)sess_id, NULL, &sess))
free_session(sess);
}

static int handle_session_start(struct ctx *ctx, const struct rec_session_start *r)
{
struct session *sess;

purge_session(ctx, r->pid);
purge_session(ctx, r->sess_id);

sess = calloc(1, sizeof(*sess));
if (!sess || hashmap__add(&sessions_hash, (long)r->pid, sess)) {
fprintf(stderr, "Failed to allocate memory for session PID %d!\n", r->pid);
if (!sess || hashmap__add(&sessions_hash, (long)r->sess_id, sess)) {
elog("Failed to allocate memory for session %d (PID %d)!\n", r->sess_id, r->pid);
return -ENOMEM;
}

sess->sess_id = r->sess_id;
sess->pid = r->pid;
sess->tgid = r->tgid;
sess->start_ts = r->start_ts;
Expand All @@ -96,7 +97,7 @@ static int handle_session_start(struct ctx *ctx, const struct rec_session_start
static int handle_lbr_stack(struct ctx *dctx, struct session *sess, const struct rec_lbr_stack *r)
{
if (sess->lbrs) {
fprintf(stderr, "BUG: PID %d session data contains LBR data already!\n", r->pid);
elog("BUG: SESSION %d data contains LBR data already!\n", r->sess_id);
return -EINVAL;
}

Expand All @@ -105,7 +106,7 @@ static int handle_lbr_stack(struct ctx *dctx, struct session *sess, const struct
if (sess->lbrs_sz > 0) {
sess->lbrs = malloc(sess->lbrs_sz);
if (!sess->lbrs) {
fprintf(stderr, "SESSION PID %d: failed to allocate LBR memory: %d\n", r->pid, -ENOMEM);
elog("SESSION %d: failed to allocate LBR memory: %d\n", r->sess_id, -ENOMEM);
return -ENOMEM;
}
memcpy(sess->lbrs, r->lbrs, sess->lbrs_sz);
Expand Down Expand Up @@ -669,7 +670,7 @@ static struct func_args_item *find_fnargs_item(const struct session *sess, int s
}

static void prepare_trace_items(struct ctx *ctx, struct stack_items_cache *cache,
int pid, int last_seq_id)
int sess_id, int last_seq_id)
{
const struct mass_attacher_func_info *finfo;
const struct inj_probe_info *inj;
Expand All @@ -680,7 +681,7 @@ static void prepare_trace_items(struct ctx *ctx, struct stack_items_cache *cache
int i, d, prev_seq_id = -1, orig_seq_id;
int args_idx = 0, ctx_idx = 0;

if (!hashmap__find(&sessions_hash, (long)pid, &sess))
if (!hashmap__find(&sessions_hash, (long)sess_id, &sess))
return;

cache->cnt = 0;
Expand Down Expand Up @@ -1260,9 +1261,10 @@ static int handle_session_end(struct ctx *dctx, struct session *sess,
goto out_purge;

if (env.debug) {
printf("GOT %s STACK (depth %u):\n", s->is_err ? "ERROR" : "SUCCESS", s->max_depth);
printf("SESSION %d GOT %s STACK (depth %u):\n",
sess->sess_id, s->is_err ? "ERROR" : "SUCCESS", s->max_depth);
printf("DEPTH %d MAX DEPTH %d SAVED DEPTH %d MAX SAVED DEPTH %d\n",
s->depth, s->max_depth, s->saved_depth, s->saved_max_depth);
s->depth, s->max_depth, s->saved_depth, s->saved_max_depth);
}

ts_to_str(ktime_to_ts(sess->start_ts), ts1, sizeof(ts1));
Expand All @@ -1279,7 +1281,7 @@ static int handle_session_end(struct ctx *dctx, struct session *sess,
* call stack trace (depth == 0)
*/
if (env.emit_func_trace && s->depth == 0) {
prepare_trace_items(dctx, &stack_items1, sess->pid, r->last_seq_id);
prepare_trace_items(dctx, &stack_items1, sess->sess_id, r->last_seq_id);
print_trace_items(dctx, &stack_items1);
}

Expand Down Expand Up @@ -1336,7 +1338,7 @@ static int handle_session_end(struct ctx *dctx, struct session *sess,
printf("\n\n");

out_purge:
purge_session(dctx, r->pid);
purge_session(dctx, r->sess_id);

return ret;
}
Expand All @@ -1361,8 +1363,8 @@ int handle_event(void *ctx, void *data, size_t data_sz)
case REC_FUNC_TRACE_EXIT: {
const struct rec_func_trace_entry *r = data;

if (!hashmap__find(&sessions_hash, (long)r->pid, &sess)) {
fprintf(stderr, "BUG: PID %d session data not found (%s)!\n", r->pid,
if (!hashmap__find(&sessions_hash, (long)r->sess_id, &sess)) {
fprintf(stderr, "BUG: Session %d data not found (%s)!\n", r->sess_id,
r->type == REC_FUNC_TRACE_ENTRY ? "FUNC_TRACE_ENTRY" : "FUNC_TRACE_EXIT");
return -EINVAL;
}
Expand All @@ -1371,44 +1373,44 @@ int handle_event(void *ctx, void *data, size_t data_sz)
case REC_FNARGS_CAPTURE: {
struct rec_fnargs_capture *r = data;

if (!hashmap__find(&sessions_hash, (long)r->pid, &sess)) {
fprintf(stderr, "BUG: PID %d session data not found (FUNC_ARGS_CAPTURE)!\n", r->pid);
if (!hashmap__find(&sessions_hash, (long)r->sess_id, &sess)) {
fprintf(stderr, "BUG: SESSION %d session data not found (FUNC_ARGS_CAPTURE)!\n", r->sess_id);
return -EINVAL;
}
return handle_fnargs_capture(ctx, sess, r);
}
case REC_LBR_STACK: {
const struct rec_lbr_stack *r = data;

if (!hashmap__find(&sessions_hash, (long)r->pid, &sess)) {
fprintf(stderr, "BUG: PID %d session data not found (LBR_STACK)!\n", r->pid);
if (!hashmap__find(&sessions_hash, (long)r->sess_id, &sess)) {
fprintf(stderr, "BUG: SESSION %d session data not found (LBR_STACK)!\n", r->sess_id);
return -EINVAL;
}
return handle_lbr_stack(ctx, sess, r);
}
case REC_INJ_PROBE: {
const struct rec_inj_probe *r = data;

if (!hashmap__find(&sessions_hash, (long)r->pid, &sess)) {
fprintf(stderr, "BUG: PID %d session data not found (INJ_PROBE)!\n", r->pid);
if (!hashmap__find(&sessions_hash, (long)r->sess_id, &sess)) {
fprintf(stderr, "BUG: SESSION %d session data not found (INJ_PROBE)!\n", r->sess_id);
return -EINVAL;
}
return handle_inj_probe(ctx, sess, r);
}
case REC_CTXARGS_CAPTURE: {
const struct rec_ctxargs_capture *r = data;

if (!hashmap__find(&sessions_hash, (long)r->pid, &sess)) {
fprintf(stderr, "BUG: PID %d session data not found (CTX_CAPTURE)!\n", r->pid);
if (!hashmap__find(&sessions_hash, (long)r->sess_id, &sess)) {
fprintf(stderr, "BUG: SESSION %d session data not found (CTX_CAPTURE)!\n", r->sess_id);
return -EINVAL;
}
return handle_ctx_capture(ctx, sess, r);
}
case REC_SESSION_END: {
const struct rec_session_end *r = data;

if (!hashmap__find(&sessions_hash, (long)r->pid, &sess)) {
fprintf(stderr, "BUG: PID %d session data not found (SESSION_END)!\n", r->pid);
if (!hashmap__find(&sessions_hash, (long)r->sess_id, &sess)) {
fprintf(stderr, "BUG: SESSION %d session data not found (SESSION_END)!\n", r->sess_id);
return -EINVAL;
}
return handle_session_end(ctx, sess, r);
Expand Down
1 change: 1 addition & 0 deletions src/logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct trace_item {
};

struct session {
int sess_id;
int pid;
int tgid;
uint64_t start_ts;
Expand Down
Loading