This is an automated email from the ASF dual-hosted git repository. guangmingchen pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brpc.git
The following commit(s) were added to refs/heads/master by this push: new f44f803a Fix asan switch fiber with error stack info (#2931) f44f803a is described below commit f44f803a9624ea4730a54c3424ebe2eb70b7b212 Author: Bright Chen <chenguangmin...@foxmail.com> AuthorDate: Wed Apr 2 20:27:41 2025 +0800 Fix asan switch fiber with error stack info (#2931) * Fix __sanitizer_start_switch_fiber with error stack info * Enable detect_stack_use_after_return in UT * Fix reuse thread stack with asan --- .github/actions/init-ut-make-config/action.yml | 2 +- .github/workflows/ci-linux.yml | 8 ++++---- docs/cn/sanitizers.md | 2 +- src/bthread/stack_inl.h | 12 +++++------- src/bthread/task_group.cpp | 3 +-- test/brpc_load_balancer_unittest.cpp | 7 +++++-- test/bthread_cond_unittest.cpp | 2 ++ test/run_tests.sh | 2 +- test/security_unittest.cc | 2 +- 9 files changed, 21 insertions(+), 19 deletions(-) diff --git a/.github/actions/init-ut-make-config/action.yml b/.github/actions/init-ut-make-config/action.yml index 983ef302..b4c57486 100644 --- a/.github/actions/init-ut-make-config/action.yml +++ b/.github/actions/init-ut-make-config/action.yml @@ -5,7 +5,7 @@ inputs: runs: using: "composite" steps: - - run: sudo apt-get update && sudo apt-get install -y clang-12 lldb-12 lld-12 libgtest-dev cmake gdb libstdc++6-11-dbg && cd /usr/src/gtest && export CC=clang-12 && export CXX=clang++-12 && sudo cmake . && sudo make -j ${{env.proc_num}} && sudo mv lib/libgtest* /usr/lib/ + - run: sudo apt-get update && sudo apt-get install -y clang-12 lldb-12 lld-12 libgtest-dev cmake gdb libstdc++6-11-dbg && cd /usr/src/gtest && export CC=clang-12 && export CXX=clang++-12 && sudo cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 . && sudo make -j ${{env.proc_num}} && sudo mv lib/libgtest* /usr/lib/ shell: bash - run: sudo git clone https://github.com/libunwind/libunwind.git && cd libunwind && sudo git checkout tags/v1.8.1 && sudo mkdir -p /libunwind && sudo autoreconf -i && sudo CC=clang-12 CXX=clang++-12 ./configure --prefix=/libunwind && sudo make -j ${{env.proc_num}} && sudo make install shell: bash diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 64dedb6d..965ffb20 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -36,7 +36,7 @@ jobs: export CC=gcc && export CXX=g++ mkdir build cd build - cmake .. + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. - name: compile run: | cd build @@ -76,7 +76,7 @@ jobs: export CC=gcc && export CXX=g++ mkdir build cd build - cmake -DWITH_MESALINK=OFF -DWITH_GLOG=ON -DWITH_THRIFT=ON -DWITH_RDMA=ON -DWITH_DEBUG_BTHREAD_SCHE_SAFETY=ON -DWITH_DEBUG_LOCK=ON -DWITH_BTHREAD_TRACER=ON -DWITH_ASAN=ON .. + cmake -DWITH_MESALINK=OFF -DWITH_GLOG=ON -DWITH_THRIFT=ON -DWITH_RDMA=ON -DWITH_DEBUG_BTHREAD_SCHE_SAFETY=ON -DWITH_DEBUG_LOCK=ON -DWITH_BTHREAD_TRACER=ON -DWITH_ASAN=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. - name: compile run: | cd build @@ -110,7 +110,7 @@ jobs: export CC=clang && export CXX=clang++ mkdir build cd build - cmake .. + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. - name: compile run: | cd build @@ -150,7 +150,7 @@ jobs: export CC=clang && export CXX=clang++ mkdir build cd build - cmake -DWITH_MESALINK=OFF -DWITH_GLOG=ON -DWITH_THRIFT=ON -DWITH_RDMA=ON -DWITH_DEBUG_BTHREAD_SCHE_SAFETY=ON -DWITH_DEBUG_LOCK=ON -DWITH_BTHREAD_TRACER=ON -DWITH_ASAN=ON .. + cmake -DWITH_MESALINK=OFF -DWITH_GLOG=ON -DWITH_THRIFT=ON -DWITH_RDMA=ON -DWITH_DEBUG_BTHREAD_SCHE_SAFETY=ON -DWITH_DEBUG_LOCK=ON -DWITH_BTHREAD_TRACER=ON -DWITH_ASAN=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. - name: compile run: | cd build diff --git a/docs/cn/sanitizers.md b/docs/cn/sanitizers.md index e902e101..30135269 100644 --- a/docs/cn/sanitizers.md +++ b/docs/cn/sanitizers.md @@ -6,7 +6,7 @@ ASan提供了[对协程的支持](https://reviews.llvm.org/D20913)。 在bthread创建、切换、销毁时,让ASan知道当前bthread的栈信息,主要用于维护[fake stack](https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn)。 -bRPC中启用ASan的方法:给config_brpc.sh增加`--with-glog`选项、给cmake增加`-DWITH_GLOG=ON`选项或者给bazel增加`--define with_asan=true`选项。 +bRPC中启用ASan的方法:给config_brpc.sh增加`--with-asan`选项、给cmake增加`-DWITH_ASAN=ON`选项或者给bazel增加`--define with_asan=true`选项。 另外需要注意的是,ASan没法检测非ASan分配内存或者对象池复用内存。所以我们封装了两个宏,让ASan知道内存块是否能被使用。在非ASan环境下,这两个宏什么也不做,没有开销。 diff --git a/src/bthread/stack_inl.h b/src/bthread/stack_inl.h index d765dfd0..faa5de07 100644 --- a/src/bthread/stack_inl.h +++ b/src/bthread/stack_inl.h @@ -70,10 +70,8 @@ BUTIL_FORCE_INLINE void FinishSwitchFiber(void* fake_stack_save) { class ScopedASanFiberSwitcher { public: - ScopedASanFiberSwitcher(StackStorage& storage, bool ending) { - // If bthread will be quit here, pass NULL as `fake_stack_save', - // so that ASan knows it can destroy the fake stack. - StartSwitchFiber(ending ? NULL : &_fake_stack, storage); + ScopedASanFiberSwitcher(StackStorage& next_storage) { + StartSwitchFiber(&_fake_stack, next_storage); } ~ScopedASanFiberSwitcher() { @@ -92,8 +90,8 @@ private: #define BTHREAD_ASAN_UNPOISON_MEMORY_REGION(storage) \ ::bthread::internal::ASanUnpoisonMemoryRegion(storage) -#define BTHREAD_SCOPED_ASAN_FIBER_SWITCHER(storage, ending) \ - ::bthread::internal::ScopedASanFiberSwitcher switcher(storage, ending) +#define BTHREAD_SCOPED_ASAN_FIBER_SWITCHER(storage) \ + ::bthread::internal::ScopedASanFiberSwitcher switcher(storage) } // namespace internal #else @@ -101,7 +99,7 @@ private: // If ASan are used, the annotations should be no-ops. #define BTHREAD_ASAN_POISON_MEMORY_REGION(storage) ((void)(storage)) #define BTHREAD_ASAN_UNPOISON_MEMORY_REGION(storage) ((void)(storage)) -#define BTHREAD_SCOPED_ASAN_FIBER_SWITCHER(storage, ending) ((void)(storage), (void)(ending)) +#define BTHREAD_SCOPED_ASAN_FIBER_SWITCHER(storage) ((void)(storage)) #endif // BUTIL_USE_ASAN diff --git a/src/bthread/task_group.cpp b/src/bthread/task_group.cpp index 0c924ac3..a2f8cc81 100644 --- a/src/bthread/task_group.cpp +++ b/src/bthread/task_group.cpp @@ -716,8 +716,7 @@ void TaskGroup::sched_to(TaskGroup** pg, TaskMeta* next_meta, bool cur_ending) { g->_control->_task_tracer.set_status(TASK_STATUS_JUMPING, next_meta); #endif // BRPC_BTHREAD_TRACER { - BTHREAD_SCOPED_ASAN_FIBER_SWITCHER( - cur_meta->stack->storage, cur_ending); + BTHREAD_SCOPED_ASAN_FIBER_SWITCHER(next_meta->stack->storage); jump_stack(cur_meta->stack, next_meta->stack); } // probably went to another group, need to assign g again. diff --git a/test/brpc_load_balancer_unittest.cpp b/test/brpc_load_balancer_unittest.cpp index a0a62c27..eac8d347 100644 --- a/test/brpc_load_balancer_unittest.cpp +++ b/test/brpc_load_balancer_unittest.cpp @@ -24,6 +24,7 @@ #include <gtest/gtest.h> #include "bthread/bthread.h" #include "gperftools_helper.h" +#include "butil/compiler_specific.h" #include "butil/containers/doubly_buffered_data.h" #include "brpc/describable.h" #include "brpc/socket.h" @@ -1155,6 +1156,7 @@ TEST_F(LoadBalancerTest, revived_from_all_failed_sanity) { } } +#ifndef BUTIL_USE_ASAN class EchoServiceImpl : public test::EchoService { public: EchoServiceImpl() @@ -1251,14 +1253,14 @@ TEST_F(LoadBalancerTest, revived_from_all_failed_intergrated) { } butil::EndPoint point(butil::IP_ANY, 7777); - brpc::Server server; EchoServiceImpl service; + brpc::Server server; ASSERT_EQ(0, server.AddService(&service, brpc::SERVER_DOESNT_OWN_SERVICE)); ASSERT_EQ(0, server.Start(point, NULL)); butil::EndPoint point2(butil::IP_ANY, 7778); - brpc::Server server2; EchoServiceImpl service2; + brpc::Server server2; ASSERT_EQ(0, server2.AddService(&service2, brpc::SERVER_DOESNT_OWN_SERVICE)); ASSERT_EQ(0, server2.Start(point2, NULL)); @@ -1287,6 +1289,7 @@ TEST_F(LoadBalancerTest, revived_from_all_failed_intergrated) { bthread_usleep(500000 /* sleep longer than timeout of channel */); ASSERT_EQ(0, num_failed.load(butil::memory_order_relaxed)); } +#endif // BUTIL_USE_ASAN TEST_F(LoadBalancerTest, la_selection_too_long) { brpc::GlobalInitializeOrDie(); diff --git a/test/bthread_cond_unittest.cpp b/test/bthread_cond_unittest.cpp index 035ff333..b1b7af0c 100644 --- a/test/bthread_cond_unittest.cpp +++ b/test/bthread_cond_unittest.cpp @@ -445,6 +445,7 @@ static void launch_many_bthreads() { } TEST(CondTest, too_many_bthreads_from_pthread) { + bthread_setconcurrency(16); launch_many_bthreads(); } @@ -454,6 +455,7 @@ static void* run_launch_many_bthreads(void*) { } TEST(CondTest, too_many_bthreads_from_bthread) { + bthread_setconcurrency(16); bthread_t th; ASSERT_EQ(0, bthread_start_urgent(&th, NULL, run_launch_many_bthreads, NULL)); bthread_join(th, NULL); diff --git a/test/run_tests.sh b/test/run_tests.sh index 2e174777..510a2c70 100755 --- a/test/run_tests.sh +++ b/test/run_tests.sh @@ -26,7 +26,7 @@ test_bins="test_butil test_bvar bthread*unittest brpc*unittest" for test_bin in $test_bins; do test_num=$((test_num + 1)) >&2 echo "[runtest] $test_bin" - ASAN_OPTIONS="detect_leaks=0" ./$test_bin + ASAN_OPTIONS="detect_leaks=0:detect_stack_use_after_return=1" ./$test_bin # If ASan abort without detailed call stack of new/delete, # try to disable fast_unwind_on_malloc, which would be a performance killer. # ASAN_OPTIONS="fast_unwind_on_malloc=0:detect_leaks=0" ./$test_bin diff --git a/test/security_unittest.cc b/test/security_unittest.cc index 5121775d..739b6c74 100644 --- a/test/security_unittest.cc +++ b/test/security_unittest.cc @@ -24,7 +24,7 @@ #endif #include "butil/compiler_specific.h" -#ifdef BUTIL_USE_ASAN +#ifndef BUTIL_USE_ASAN using std::nothrow; using std::numeric_limits; --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org For additional commands, e-mail: dev-h...@brpc.apache.org