Skip to content

Commit 7a7d1c8

Browse files
authored
Support AddressSanitizer (#2890)
* Support AddressSanitizer * Add gperftools helper header
1 parent 5c8bd06 commit 7a7d1c8

62 files changed

Lines changed: 554 additions & 122 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci-linux.yml

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
- uses: ./.github/actions/install-all-dependences
6262
- uses: ./.github/actions/init-make-config
6363
with:
64-
options: --cc=gcc --cxx=g++ --with-thrift --with-glog --with-rdma --with-debug-bthread-sche-safety --with-debug-lock --with-bthread-tracer --werror
64+
options: --cc=gcc --cxx=g++ --with-thrift --with-glog --with-rdma --with-debug-bthread-sche-safety --with-debug-lock --with-bthread-tracer --werror --with-asan
6565
- name: compile
6666
run: |
6767
make -j ${{env.proc_num}}
@@ -76,7 +76,7 @@ jobs:
7676
export CC=gcc && export CXX=g++
7777
mkdir build
7878
cd build
79-
cmake -DWITH_MESALINK=OFF -DWITH_GLOG=ON -DWITH_THRIFT=ON -DWITH_RDMA=ON -DWITH_DEBUG_BTHREAD_SCHE_SAFETY=ON -DWITH_DEBUG_LOCK=ON -WITH_BTHREAD_TRACER=ON ..
79+
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 ..
8080
- name: compile
8181
run: |
8282
cd build
@@ -86,7 +86,7 @@ jobs:
8686
runs-on: ubuntu-22.04
8787
steps:
8888
- uses: actions/checkout@v2
89-
- run: bazel build --verbose_failures --define with_mesalink=false --define with_glog=true --define with_thrift=true --define with_debug_bthread_sche_safety=true --define with_debug_lock=true -- //... -//example/...
89+
- run: bazel build --verbose_failures --define with_mesalink=false --define with_glog=true --define with_thrift=true --define with_debug_bthread_sche_safety=true --define with_debug_lock=true --define with_asan=true -- //... -//example/...
9090

9191
clang-compile-with-make:
9292
runs-on: ubuntu-22.04
@@ -135,7 +135,7 @@ jobs:
135135
- uses: ./.github/actions/install-all-dependences
136136
- uses: ./.github/actions/init-make-config
137137
with:
138-
options: --cc=clang --cxx=clang++ --with-thrift --with-glog --with-rdma --with-debug-bthread-sche-safety --with-debug-lock --with-bthread-tracer --werror
138+
options: --cc=clang --cxx=clang++ --with-thrift --with-glog --with-rdma --with-debug-bthread-sche-safety --with-debug-lock --with-bthread-tracer --werror --with-asan
139139
- name: compile
140140
run: |
141141
make -j ${{env.proc_num}}
@@ -150,7 +150,7 @@ jobs:
150150
export CC=clang && export CXX=clang++
151151
mkdir build
152152
cd build
153-
cmake -DWITH_MESALINK=OFF -DWITH_GLOG=ON -DWITH_THRIFT=ON -DWITH_RDMA=ON -DWITH_DEBUG_BTHREAD_SCHE_SAFETY=ON -DWITH_DEBUG_LOCK=ON -WITH_BTHREAD_TRACER=ON ..
153+
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 ..
154154
- name: compile
155155
run: |
156156
cd build
@@ -160,7 +160,7 @@ jobs:
160160
runs-on: ubuntu-22.04
161161
steps:
162162
- uses: actions/checkout@v2
163-
- run: bazel build --verbose_failures --action_env=CC=clang --define with_mesalink=false --define with_glog=true --define with_thrift=true --define with_debug_bthread_sche_safety=true --define with_debug_lock=true -- //... -//example/...
163+
- run: bazel build --verbose_failures --action_env=CC=clang --define with_mesalink=false --define with_glog=true --define with_thrift=true --define with_debug_bthread_sche_safety=true --define with_debug_lock=true --define with_asan=true -- //... -//example/...
164164

165165
clang-unittest:
166166
runs-on: ubuntu-22.04
@@ -179,3 +179,21 @@ jobs:
179179
run: |
180180
cd test
181181
sh ./run_tests.sh
182+
183+
clang-unittest-asan:
184+
runs-on: ubuntu-22.04
185+
steps:
186+
- uses: actions/checkout@v2
187+
- uses: ./.github/actions/install-essential-dependences
188+
- uses: ./.github/actions/init-ut-make-config
189+
with:
190+
options: --cc=clang-12 --cxx=clang++-12 --with-bthread-tracer --with-asan
191+
- name: compile tests
192+
run: |
193+
cat config.mk
194+
cd test
195+
make NEED_GPERFTOOLS=0 -j ${{env.proc_num}}
196+
- name: run tests
197+
run: |
198+
cd test
199+
sh ./run_tests.sh

BUILD.bazel

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ COPTS = [
5353
}) + select({
5454
"@platforms//cpu:x86_64": ["-DBRPC_BTHREAD_TRACER"],
5555
"//conditions:default": [],
56+
}) + select({
57+
"//bazel/config:brpc_with_asan": ["-fsanitize=address"],
58+
"//conditions:default": [""],
5659
})
5760

5861
LINKOPTS = [
@@ -87,7 +90,10 @@ LINKOPTS = [
8790
"-libverbs",
8891
],
8992
"//conditions:default": [],
90-
})
93+
}) + select({
94+
"//bazel/config:brpc_with_asan": ["-fsanitize=address"],
95+
"//conditions:default": [""],
96+
})
9197

9298
genrule(
9399
name = "config_h",

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ option(WITH_SNAPPY "With snappy" OFF)
2929
option(WITH_RDMA "With RDMA" OFF)
3030
option(WITH_DEBUG_BTHREAD_SCHE_SAFETY "With debugging bthread sche safety" OFF)
3131
option(WITH_DEBUG_LOCK "With debugging lock" OFF)
32+
option(WITH_ASAN "With AddressSanitizer" OFF)
3233
option(BUILD_UNIT_TESTS "Whether to build unit tests" OFF)
3334
option(BUILD_FUZZ_TESTS "Whether to build fuzz tests" OFF)
3435
option(BUILD_BRPC_TOOLS "Whether to build brpc tools" ON)
@@ -134,6 +135,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
134135
endif()
135136

136137
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} ${DEFINE_CLOCK_GETTIME} -DBRPC_WITH_GLOG=${WITH_GLOG_VAL} -DBRPC_WITH_RDMA=${WITH_RDMA_VAL} -DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=${WITH_DEBUG_BTHREAD_SCHE_SAFETY_VAL} -DBRPC_DEBUG_LOCK=${WITH_DEBUG_LOCK_VAL}")
138+
if (WITH_ASAN)
139+
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -fsanitize=address")
140+
set(CMAKE_C_FLAGS "${CMAKE_CPP_FLAGS} -fsanitize=address")
141+
endif()
137142
if(WITH_MESALINK)
138143
set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -DUSE_MESALINK")
139144
endif()

bazel/config/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,4 +120,10 @@ config_setting(
120120
name = "brpc_with_debug_lock",
121121
define_values = {"with_debug_lock": "true"},
122122
visibility = ["//visibility:public"],
123+
)
124+
125+
config_setting(
126+
name = "brpc_with_asan",
127+
define_values = {"with_asan": "true"},
128+
visibility = ["//visibility:public"],
123129
)

config_brpc.sh

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ else
3838
LDD=ldd
3939
fi
4040

41-
TEMP=`getopt -o v: --long headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-rdma,with-mesalink,with-bthread-tracer,with-debug-bthread-sche-safety,with-debug-lock,nodebugsymbols,werror -n 'config_brpc' -- "$@"`
41+
TEMP=`getopt -o v: --long headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-rdma,with-mesalink,with-bthread-tracer,with-debug-bthread-sche-safety,with-debug-lock,with-asan,nodebugsymbols,werror -n 'config_brpc' -- "$@"`
4242
WITH_GLOG=0
4343
WITH_THRIFT=0
4444
WITH_RDMA=0
4545
WITH_MESALINK=0
4646
WITH_BTHREAD_TRACER=0
47+
WITH_ASAN=0
4748
BRPC_DEBUG_BTHREAD_SCHE_SAFETY=0
4849
DEBUGSYMBOLS=-g
4950
WERROR=
@@ -74,6 +75,7 @@ while true; do
7475
--with-bthread-tracer) WITH_BTHREAD_TRACER=1; shift 1 ;;
7576
--with-debug-bthread-sche-safety ) BRPC_DEBUG_BTHREAD_SCHE_SAFETY=1; shift 1 ;;
7677
--with-debug-lock ) BRPC_DEBUG_LOCK=1; shift 1 ;;
78+
--with-asan) WITH_ASAN=1; shift 1 ;;
7779
--nodebugsymbols ) DEBUGSYMBOLS=; shift 1 ;;
7880
--werror ) WERROR=-Werror; shift 1 ;;
7981
-- ) shift; break ;;
@@ -345,10 +347,15 @@ else
345347
CXXFLAGS="-std=c++0x"
346348
fi
347349

348-
LEVELDB_HDR=$(find_dir_of_header_or_die leveldb/db.h)
349-
350350
CPPFLAGS=
351351

352+
if [ $WITH_ASAN != 0 ]; then
353+
CPPFLAGS="${CPPFLAGS} -fsanitize=address"
354+
DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -fsanitize=address"
355+
fi
356+
357+
LEVELDB_HDR=$(find_dir_of_header_or_die leveldb/db.h)
358+
352359
if [ $WITH_BTHREAD_TRACER != 0 ]; then
353360
if [ "$SYSTEM" != "Linux" ] || [ "$(uname -m)" != "x86_64" ]; then
354361
>&2 $ECHO "bthread tracer is only supported on Linux x86_64 platform"
@@ -425,7 +432,7 @@ append_to_output "STATIC_LINKINGS=$STATIC_LINKINGS"
425432
append_to_output "DYNAMIC_LINKINGS=$DYNAMIC_LINKINGS"
426433

427434
# CPP means C PreProcessing, not C PlusPlus
428-
CPPFLAGS="${CPPFLAGS} -DBRPC_WITH_GLOG=$WITH_GLOG -DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=$BRPC_DEBUG_BTHREAD_SCHE_SAFETY -DBRPC_DEBUG_LOCK=$BRPC_DEBUG_LOCK"
435+
CPPFLAGS="${CPPFLAGS} -DBRPC_WITH_GLOG=$WITH_GLOG -DBRPC_DEBUG_BTHREAD_SCHE_SAFETY=$BRPC_DEBUG_BTHREAD_SCHE_SAFETY -DBRPC_DEBUG_LOCK=$BRPC_DEBUG_LOCK"
429436

430437
# Avoid over-optimizations of TLS variables by GCC>=4.8
431438
# See: https://github.com/apache/brpc/issues/1693
@@ -523,7 +530,10 @@ append_to_output "ifeq (\$(NEED_GPERFTOOLS), 1)"
523530
TCMALLOC_LIB=$(find_dir_of_lib tcmalloc_and_profiler)
524531
if [ -z "$TCMALLOC_LIB" ]; then
525532
append_to_output " \$(error \"Fail to find gperftools\")"
533+
elif [ $WITH_ASAN != 0 ]; then
534+
append_to_output " \$(error \"gperftools is not compatible with ASAN\")"
526535
else
536+
append_to_output " CPPFLAGS+=-DBRPC_ENABLE_CPU_PROFILER"
527537
append_to_output_libs "$TCMALLOC_LIB" " "
528538
if [ -f $TCMALLOC_LIB/libtcmalloc.$SO ]; then
529539
append_to_output " DYNAMIC_LINKINGS+=-ltcmalloc_and_profiler"

docs/cn/getting_started.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,6 @@ bRPC 中使用了 protobuf 内部 API,上游不保证相关 API 的兼容性
352352

353353
[1.8.0](https://github.com/apache/brpc/releases/tag/1.8.0)[#2406](https://github.com/apache/brpc/pull/2406)[#2493](https://github.com/apache/brpc/pull/2493)引入了部分 proto3 语法,所以目前 bRPC 不再兼容 protobuf 2.x 版本。如果你希望使用 2.x 版本,可以使用 1.8.0 之前的 bRPC 版本。
354354

355-
pb 3.x中的Arena至今没被支持。
356-
357355
## gflags: 2.1-2.2.2
358356

359357
2.1.1 中存在一处已知问题,需要[补丁](https://github.com/gflags/gflags/commit/408061b46974cc8377a8a794a048ecae359ad887)

docs/cn/sanitizers.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Sanitizers
2+
3+
新版本的GCC/Clang支持[sanitizers](https://github.com/google/sanitizers),方便开发者排查代码中的bug。 bRPC对sanitizers提供了一定的支持。
4+
5+
## AddressSanitizer(ASan)
6+
7+
ASan提供了[对协程的支持](https://reviews.llvm.org/D20913)。 在bthread创建、切换、销毁时,让ASan知道当前bthread的栈信息,主要用于维护[fake stack](https://github.com/google/sanitizers/wiki/AddressSanitizerUseAfterReturn)
8+
9+
bRPC中启用ASan的方法:给config_brpc.sh增加`--with-glog`选项、给cmake增加`-DWITH_GLOG=ON`选项或者给bazel增加`--define with_asan=true`选项。
10+
11+
另外需要注意的是,ASan没法检测非ASan分配内存或者对象池复用内存。所以我们封装了两个宏,让ASan知道内存块是否能被使用。在非ASan环境下,这两个宏什么也不做,没有开销。
12+
13+
```c++
14+
#include <butil/debug/address_annotations.h>
15+
16+
BUTIL_ASAN_POISON_MEMORY_REGION(addr, size);
17+
BUTIL_ASAN_UNPOISON_MEMORY_REGION(addr, size);
18+
```
19+
20+
其他问题:如果ASan报告中new/delete的调用栈不完整,可以通过设置`fast_unwind_on_malloc=0`回溯出完整的调用栈了。需要注意的是`fast_unwind_on_malloc=0`很耗性能。
21+
22+
## ThreadSanitizer(TSan)
23+
24+
待支持(TODO)
25+
26+
## LeakSanitizer(LSan) / MemorySanitizer(MSan) / UndefinedBehaviorSanitizer(UBSan)
27+
28+
bRPC默认支持这三种sanitizers,编译及链接时加上对应的选项即可启用对应的sanitizers:
29+
30+
1. LSan: `-fsanitize=leak`
31+
2. MSan: `-fsanitize=memory`
32+
3. UBSan: `-fsanitize=undefined`

docs/en/getting_started.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,6 @@ Please [submit issue](https://github.com/apache/brpc/issues) if you have any pro
347347

348348
[#2406](https://github.com/apache/brpc/pull/2406) and [#2493](https://github.com/apache/brpc/pull/2493) in [version 1.8.0]((https://github.com/apache/brpc/releases/tag/1.8.0)) introduce some proto3 syntax, so currently bRPC is no longer compatible with pb 2.x version. If you want to use pb 2.x version, you can use bRPC version before 1.8.0.
349349

350-
Arena in pb 3.x is not supported yet.
351-
352350
## gflags: 2.0-2.2.2
353351

354352
[gflags patch](https://github.com/gflags/gflags/commit/408061b46974cc8377a8a794a048ecae359ad887) is required when compiled with 2.1.1.

src/brpc/details/http_message.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class HttpMessage {
8888
bool read_body_progressively() const { return _read_body_progressively; }
8989

9090
void set_read_body_progressively(bool read_body_progressively) {
91-
this->_read_body_progressively = read_body_progressively;
91+
_read_body_progressively = read_body_progressively;
9292
}
9393

9494
// Send new parts of the body to the reader. If the body already has some

src/brpc/details/http_parser.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,13 +2191,13 @@ http_parser_init (http_parser *parser, enum http_parser_type t)
21912191

21922192
const char *
21932193
http_errno_name(enum http_errno err) {
2194-
assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
2194+
assert(err < (http_errno)(sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
21952195
return http_strerror_tab[err].name;
21962196
}
21972197

21982198
const char *
21992199
http_errno_description(enum http_errno err) {
2200-
assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
2200+
assert(err < (http_errno)(sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0])));
22012201
return http_strerror_tab[err].description;
22022202
}
22032203

0 commit comments

Comments
 (0)