-
Notifications
You must be signed in to change notification settings - Fork 4k
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
fix coredump stack uncomplete when usercode throw exceptions #2256
Conversation
bdbd539
to
1d7bfd4
Compare
LGTM |
这个 fix 只对 gcc 生效吗?其他编译器是否有试过 |
那就是说低版本的编译器,堆栈是完整的,只有高版本编译器有这个问题吗? |
应该是取决于编译器是否认为这个析构函数是noexcept的,如果编译器认为它是noexcept的,那么堆栈就会回溯到这个析构函数结束的地方,堆栈就不完整。 因为我是百度的同学,我们厂内只提供了 GCC82 GCC10 GCC12 CLANG10 CLANG14 |
哦哦 显式指定noexcept(false),就可以抹平编译器之间的差异 |
@smbzhang 欢迎加入开发者群,一起探讨 brpc 相关的问题。 |
我已经在群里了同学, 『里贝里晃倒梅西』 |
@smbzhang 服务端支持progressive reader的话,好像会走这个分支。 brpc/src/brpc/input_messenger.cpp Lines 317 to 322 in 72ed304
这时候这个fix会生效吗? |
我没用过服务端progressive功能,只用过客户端读取http chunked消息的功能。所以这块不太熟悉没法给你构造一个demo。 不过我看brpc逻辑是把消息放到另外的bthread中处理去了,传递的msg也是原生指针。没有通过析构last_msg来处理http消息(调起callmethod),所以这种情况应该不属于我这个case,整个新的bthread调用栈上没有通过析构函数调起Echo函数,也就不会出现栈缺失了 |
brpc/src/brpc/input_messenger.cpp Lines 283 to 285 in 72ed304
一次OnNewMessages解出多个协议包,只有最后一个包才通过InputMessageClosure的析构函数调起Echo函数,其他包都是通过 QueueMessage起协程调起Echo函数。 我验证了一下,如你所说, 学习了,感谢 @smbzhang |
求一个开发者群号 |
What problem does this PR solve?
高版本编译器编译的brpc,用户异常抛到brpc框架内部导致core栈不完整
Issue Number:
程序内部core但是core栈不完整 #1997
运行一段时间,就会core在brpc内部 #1437
crash #985
Problem Summary:
高版本GCC编译器(如GCC12)对于析构函数默认是noexcept的(也有人说是因为C++标准的问题 比如C++11之后才默认noexcept,但是GCC12下我使用C++11和C++17都是默认noexcept的), 低版本的GCC82默认就是noexcept(false)的。
所以当你使用了高版本GCC编译程序的时候,业务代码抛出异常,在进行栈回溯之前会先沿着调用栈寻找处理异常的代码块(专业名词是Landing pad),如果找到Landing pad,那么就会进行栈回溯到Landing pad进行异常处理。找不到Landing pad就会原地调用std::terminate终止程序,这个时候你的core栈就是完整的,不会回溯陷入brpc框架。
从我的测试看,Landing pad 一种是真正的 try catch 块,另一种就是整个调用链上有noexcept属性的函数结束的代码段地址(汇编代码就是一块Unwind_Resume代码块),brpc整个调用链上没有try catch 非 bthread::ExitException 异常的Landing pad。 所以我hook了__gxx_personality_v0函数,找出了具有noexcept属性的函数
修改这个析构函数为noexcept(false)之后,__gxx_personality_v0就在brpc框架内找不到Landing pad代码块了,于是就会在抛异常的地方终止,堆栈也就完整了
What is changed and the side effects?
Changed:
Side effects:
Performance effects(性能影响):
Breaking backward compatibility(向后兼容性):
Check List: