Skip to content

fix(lsof): start ringbuf consumer before iterator scan - #125

Open
yuKing123-king wants to merge 1 commit into
DKapture:mainfrom
yuKing123-king:fix/lsof-ringbuf-consume-timing
Open

fix(lsof): start ringbuf consumer before iterator scan#125
yuKing123-king wants to merge 1 commit into
DKapture:mainfrom
yuKing123-king:fix/lsof-ringbuf-consume-timing

Conversation

@yuKing123-king

@yuKing123-king yuKing123-king commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

本次修改主要是修复了ringbuffer消耗不及时这个问题

由于起tail和vma占用文件只能最多起大概3000左右个进程,但是在bpf程序中,logs map的最大条目数却是256 * 1024 远远大于进程数,所以体现不出来ringbuffer消耗不及时这个问题。我将logs map的最大条目数从256 * 1024改成2 * 1024后,当启动1500个占用文件的进程后,lsof这个工具就会出现丢统计的情况。如下所示:

一、现象

  1. 下面是起了1500个tail和vma进程占用文件
1
  1. 原lsof只统计到了102个tail进程占用文件,修复后的lsof统计到了1500个tail进程
tail

3.原lsof只统计到了0个vma进程占用文件,修复后的lsof统计到了1500个vma进程
vma

二、作出的修改

  1. 原因

出现统计不及时的原因是先 bpf_iter_create(bpf_link__fd(obj->links.vma_iterator))bpf_iter_create(bpf_link__fd(obj->links.file_iterator)),后 pthread_create(&t1, NULL, ringbuf_worker, NULL),这就导致了先进行统计生产后,再统一进行消费,如果同时有很多进程占用文件,超过 logs map 的最大条目数就会出现统计错误和报错。

  1. 修改

pthread_create(&t1, NULL, ringbuf_worker, NULL) 放在 bpf_iter_create(bpf_link__fd(obj->links.vma_iterator))bpf_iter_create(bpf_link__fd(obj->links.file_iterator)) 之前启动这个线程,就可以边生产边消费。同时我将 void *ringbuf_worker(void *) 这个的退出条件,从 if (err == 0 && iter_fd == -1) 换成使用 scan_done 这个更明确的状态变更。

@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

线程泄漏

在第299行通过 pthread_create(&t1, NULL, ringbuf_worker, NULL) 启动了第一个 worker 线程用于在扫描期间消费 ring buffer。但在第329行又调用了 pthread_create(&t1, NULL, ringbuf_worker, NULL) 创建第二个线程,直接覆盖了 t1 中保存的第一个线程 ID。第一个线程从未被 pthread_join 回收,导致线程资源泄漏,且第一个线程变为不可 join 状态。应在创建第二个线程前先 join 第一个线程,或移除第二次 pthread_create 复用同一个线程。

pthread_create(&t1, NULL, ringbuf_worker, NULL);
Worker 过早退出

第328行将 scan_done 设为 true 后,第329行创建的第二个 worker 线程从启动起就看到 scan_done == true。在 ringbuf_worker 中,当 ring_buffer__poll 返回 0(100ms 超时无数据)且 scan_done 为 true 时会 break 退出。这意味着在 follow_trace_pipe() 期间,只要 ring buffer 出现短暂无数据的间隙(100ms 内无事件),第二个 worker 就会提前退出,导致后续 trace 数据丢失。应在创建第二个 worker 前将 scan_done 重置为 false,或使用 exit_flag 作为退出信号。

scan_done = true;
pthread_create(&t1, NULL, ringbuf_worker, NULL);

Signed-off-by: Wang Yu <wangyu6@uniontech.com>
@yuKing123-king
yuKing123-king force-pushed the fix/lsof-ringbuf-consume-timing branch from ba47f8c to 0c8163f Compare August 17, 2026 06:27
@yuKing123-king

Copy link
Copy Markdown
Contributor Author

/review 检视一下当前提交的PR,代码有无安全风险,和其他错误的地方

@github-actions

Copy link
Copy Markdown

Preparing review...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant