fix(run-queue): catch exceptions from parse_args and handle_event - #154
Open
yuKing123-king wants to merge 1 commit into
Open
yuKing123-king wants to merge 1 commit into
yuKing123-king wants to merge 1 commit into
Conversation
Signed-off-by: Wang Yu <wangyu6@uniontech.com>
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
修复的 Bug
run-queue的main()和handle_event()中存在未被捕获的 C++ 异常,导致进程被std::terminate静默 abort,无任何错误提示:parse_args()内部通过std::stoull解析参数,非法输入会抛std::invalid_argument/std::out_of_range;parse_range里的字符串拼接("..." + range_str)和long_opt2short_opt里的sopts += ...会抛std::bad_alloc。这些异常逃逸出main()→std::terminate。handle_event()在 ringbuf worker 线程中被ring_buffer__poll同步回调,其中runqueques[log->cpu]和push_back会抛std::bad_alloc。该异常在子线程中抛出,main()的 try/catch 无法捕获 → 同样std::terminate。对常驻观测工具而言,失败时应至少打印原因而非静默 abort。
改了哪些地方
main()中仅包裹parse_args(argc, args)一句:handle_event()中仅包裹 map/vector 操作:不涉及 BPF 加载、map 操作、ringbuf 创建等其余语句。
为什么这样修复
只包会抛异常的语句:经核实
build/observe/run-queue.skel.h,run_queue_bpf::open_and_load/attach/detach/destroy都是 C 接口,失败返回 NULL 或错误码,不抛 C++ 异常;bpf_get_map_fd、ring_buffer__new、bpf_iter_create、read、pthread_create同理。这些已有goto cleanup错误处理,无需也不应被 try/catch 包裹,避免吞掉它们的返回值检查逻辑。真正会抛 C++ 异常的只有parse_args(std::stoull+ 字符串拼接)和handle_event(map/vector 分配),故只包这两处。parse_args用catch (const std::exception &e):std::stoull抛invalid_argument/out_of_range,字符串拼接抛bad_alloc,三者都是std::exception派生类,e.what()能给出具体原因(如"Invalid number format: abc"),一条 catch 覆盖全部,最小改动。catch 后goto cleanup复用既有清理路径(free(buf)、rb判空释放),不增新代码。handle_event必须单独包,且只 catchstd::bad_alloc:它在 worker 线程里由ring_buffer__poll同步回调,不在main的 try 作用域内,main的 catch 根本捕获不到;不单独包的话 worker 线程 OOM 仍std::terminate。map/vector 对 PODBpfData的拷贝不抛异常,唯一现实风险是内存分配失败,故精确 catchbad_alloc,不吞其它异常。return -1符合 libbpf 回调契约(返回负值→ring_buffer__poll停止并返回错误→worker 线程err < 0 && err != -EINTR分支pr_error后退出循环),避免线程空转。验证方式