shui8023 commented on issue #3302:
URL: https://github.com/apache/brpc/issues/3302#issuecomment-4487415571

   ## 问题
   
   在 ASan 构建(`-fsanitize=address`)下,启用 LSan(`detect_leaks=1`,ASan 默认)的 brpc 
进程在退出阶段稳定崩溃:
   
   ```
   Tracer caught signal 11: addr=0x... pc=0x... sp=0x...
   ==XXX==LeakSanitizer has encountered a fatal error.
   ==XXX==HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)
   ```
   
   崩溃发生在 LSan tracer 子进程内的 `__lsan::ProcessThread` → `ScanRangeForPointers` 
路径——tracer raw deref 到一个 PROT_NONE guard page 时 SIGSEGV,由于 tracer 与父进程 
`clone(CLONE_VM)` 共享地址空间,整个 brpc 进程被 kernel 同步杀死。
   
   ## 根因(最终确认)
   
   brpc `task_group.cpp` 在 `BUTIL_USE_ASAN_MAIN_STACK` 启用时把 worker pthread 
真栈注册到 `_main_stack->storage`,**两个字段中 `storage.bottom` 的填值与 brpc 自身约定的语义相反**:
   
   ```cpp
   // brpc/src/bthread/task_group.cpp:325-329 (BUG)
   #ifdef BUTIL_USE_ASAN_MAIN_STACK
       stk->storage.bottom = stack_addr;          // ← BUG
       stk->storage.stacksize = stack_size;
   #endif
   ```
   
   - `stack_addr` 来自 `pthread_attr_getstack`,**POSIX 语义是 stack 的最低地址**(栈底 / 
lowest addressable byte)
   - 但 brpc 自己的 `StackStorage::bottom` 在协程栈代码里被定义为 **stack 的最高地址**(栈顶):
   
   ```cpp
   // brpc/src/bthread/stack.cpp:128 (协程栈,作为参考约定)
   s->bottom = (char*)mem + memsize;   // 高端地址 = 栈顶
   ```
   
   - `StartSwitchFiber` 依赖这个约定计算传给 ASan 的 stack range:
   
   ```cpp
   // brpc/src/bthread/stack_inl.h:64
   void* asan_stack_bottom = (char*)storage.bottom - storage.stacksize;  // 高端 
- size = 低端
   __sanitizer_start_switch_fiber(saved, asan_stack_bottom, storage.stacksize);
   ```
   
   这个公式对协程栈正确(`storage.bottom` 是高端),但对 main_stack **整体错位 stack_size**(默认 8 
MB),把 ASan 视角下的 stack range 推到 worker pthread 真栈**之前 8 MB** 
的虚拟地址范围内——那是别的线程的栈片段、协程栈群、和大量 PROT_NONE guard page 所在区域。
   
   LSan StopTheWorld 通过 `GetThreadRangesLocked` 拿到 
`AsanThread::stack_bottom_/stack_top_`(被 fiber switcher 错位写入),命中 `sp 不在 stack 
range` 分支后扫整段 8 MB,撞到中间 PROT_NONE guard 页时 SIGSEGV。


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to