brpc icon indicating copy to clipboard operation
brpc copied to clipboard

uretprobe会触发brpc服务SIGILL

Open hsueh-yh opened this issue 2 years ago • 0 comments

Describe the bug (描述bug) 用bcc工具funclatency观察服务里某个函数的耗时时,发现会触发服务SIGILL信号,导致服务异常退出,且稳定复现。 该工具观察函数耗时是通过uprobe/uretprobe来实现的,其中uretprobe会修改栈上的函数返回地址,所以怀疑跟bthread用户态切换栈有关。

Go服务也存在类似问题issue,是因为Go服务会对栈进行扩缩容等操作导致栈内存移动,但是bthread的栈内存应该不会有扩缩容等移动栈内存的操作。

To Reproduce (复现方法) 参照funclatency_example观察brpc服务的用户态函数耗时就可以触发。或者使用其他依赖uretprobe的工具。

Expected behavior (期望行为) 期望brpc服务可以正常使用uretprobe/kretprobe

Versions (各种版本) OS: centos7 Compiler: gcc7.3 brpc: protobuf:

Additional context/screenshots (更多上下文/截图) 服务报SIGILL的现场: image

进程的内存分布 (cat /proc/pid/maps | grep uprobes) uprobes的内存块首地址,也就是uprobes桩函数的首地址,是 0x00007fffffffe000,非法指令的地址正好是它的后一字节! image

现场描述:

  1. 服务执行到0x00007fffffffe001地址时遇到非法指令,该地址应该是压在栈上的函数返回地址,且是被uretprobe修改过的。
  2. 正常uprobes会在进入函数时,就把函数返回地址修改为uprobes内存块的首地址0x00007fffffffe000,而且通过gdb观察栈内存,在进入函数时也确实修改对了。
  3. 函数执行完后,开始执行返回地址对应的指令,这时返回地址变成了0x00007fffffffe001(往后移了1字节)

所以问题应该出在函数处理过程中,在函数处理过程中,栈上的函数返回地址又被修改了。 这期间可能存在bthread调度,因为函数内部可能会创建bthread,或者调用bthread::Mutex锁间接触发切换。

求助社区大佬有没有遇到类似问题的,或者有什么解决思路?感谢!

hsueh-yh avatar Dec 28 '23 10:12 hsueh-yh