Conversation
…ath argument When fs_watch() is called with a non-null path, the else branch incorrectly calls trace_file_init() instead of mountsnoop_init(). This is a copy-paste error from file_watch(). The correct behavior is to initialize mountsnoop for filesystem event monitoring. Signed-off-by: JoeSergen <jxq142857@163.com>
…eanup Calling this->~ClassName() from constructor catch blocks is fragile and violates C++ best practices. In RingBuffer's Normal constructor, type was set after the first try block, causing the destructor to run the BPF cleanup path on uninitialized data. Changes: - ring-buffer.cpp: replace this->~RingBuffer() with explicit munmap/close in BPF constructor; move type=RING_BUF_TYPE_NORMAL before try block and replace destructor calls with SAFE_DELETE in Normal constructor - bpf-manager.cpp: replace this->~BPFManager() with SAFE_DELETE - data-map.cpp: replace this->~DataMap() with SAFE_DELETE in reverse init order Signed-off-by: JoeSergen <jxq142857@163.com>
|
你好,这是对 libdkapture#114 fix: replace manual destructor calls in constructors with ex 的评审。 本轮为 DKapture 两仓(libdkapture / dkapture-bpf)全部以 fix 开头 open PR 的批量评审,共 17 个;汇总表如下,本 PR 加粗。逐项详评见分隔线下方。
本 PR 评审详情作者: JoeSergen | 规模: +28/-7 | 文件: 4 总体结论: 用显式清理替换构造函数 catch 中的 this->~ClassName() 方向正确。逐一核对:所有涉及的裸指针成员均有 NSDMI(so/bpf-manager.h:20-22、so/data-map.h:34-39、so/ring-buffer.h:18-33 匿名联合内 shm_ctl/spinlock/mirror_shm = nullptr),catch 中对尚未构造的成员执行 SAFE_DELETE 安全。RingBuffer Normal 构造把 type=RING_BUF_TYPE_NORMAL 提前到 try 之前(so/ring-buffer.cpp:136),修复了真实崩溃路径:旧代码首个 try 抛异常时析构按默认 type==RING_BUF_TYPE_BPF 走 BPF 分支,对刚分配的 spinlock/shm_ctl 不做 delete。BPFManager 旧代码在 SpinLock 构造抛出时以 bpf_ref_cnt==nullptr 进入析构并执行 --(*bpf_ref_cnt)(so/bpf-manager.cpp:226-250),是必然的空指针解引用,新写法消除了该 UB。 主要问题:
次要建议:
亮点:
commit message: 两个 commit 均有 Signed-off-by、动机与变更列表清晰;仓库既有 fix(scope): 与 fix: 混用风格,"fix:" 无作用域可接受;但 commit 1(fs_watch)与本 PR 主题无关,见主要问题。 已有讨论: 无(issue 评论与行级评论均为空)。 |
Summary
Replace
this->~ClassName()calls in constructor catch blocks with explicit member cleanup. 5 call sites across 3 files.Root Cause
The Pattern (all 3 constructors)
Calling a destructor from a constructor is fragile: if the destructor is later modified to use members that haven't been initialized yet, undefined behavior follows.
The Concrete Crash Bug (RingBuffer Normal constructor)
In the Normal constructor,
type = RING_BUF_TYPE_NORMALwas set after the first try block. The destructor dispatches ontype:Before this fix:
If
new SharedMemory()succeeds butnew SpinLock()fails,comsumer_indexpoints to a valid shared-memory address.(ulong)comsumer_index > 0evaluates to TRUE, andmunmap()is called on a kernel pointer → SIGSEGV.Changes
1. ring-buffer.cpp — BPF constructor
err_outlabelReplaced
this->~RingBuffer()with explicit cleanup using properMAP_FAILEDchecks (instead of fragile(ulong)ptr > 0):err_out: if (producer_index && producer_index != MAP_FAILED) { munmap(...); } if (comsumer_index && comsumer_index != MAP_FAILED) { munmap(...); } if (epoll_fd >= 0) { close(epoll_fd); } throw exc;2. ring-buffer.cpp — Normal constructor
type = RING_BUF_TYPE_NORMAL;before the first try block (fixes the crash)SAFE_DELETEon heap-allocated members only3. bpf-manager.cpp
4. data-map.cpp
Non-heap Members
These members are pointer assignments into shared memory — they point to fields inside heap-allocated objects, not independently allocated memory. They are NOT freed by cleanup:
bpf_ref_cnt→&m_shm->bpf_ref_cntcomsumer_index→&shm_ctl->rdiproducer_index→&shm_ctl->wrim_entrys→m_rb->buf()m_idx→&m_shm->data_map_idxVerification
SAFE_DELETEis the project's established pattern (include/com.h:432)Closes #113