Skip to content

ODR違反の修正: ccbench_common を universal definitions 付きでビルドする#118

Merged
thawk105 merged 1 commit into
masterfrom
fix/ccbench-common-universal-defines
Jun 28, 2026
Merged

ODR違反の修正: ccbench_common を universal definitions 付きでビルドする#118
thawk105 merged 1 commit into
masterfrom
fix/ccbench-common-universal-defines

Conversation

@thawk105

Copy link
Copy Markdown
Owner

問題

CCBENCH_BACK_OFF=1CCBENCH_ADD_ANALYSIS=1 を同時指定したビルドが、起動直後の
TxExecutor::leaderWork() で必ず segfault します(スレッド数非依存)。BACK_OFF=1
単体・ADD_ANALYSIS=1 単体ではどちらも正常です。

根本原因(ODR 違反)

Result のレイアウトは #if ADD_ANALYSIS でフィールドが増え sizeof(Result) が変わります。
グローバルの CCBenchResultsstd::vector<Result>)を定義・resize() するのは
common/result.cc で、これは ccbench_common 静的ライブラリにコンパイルされます。

ところが ccbench_commonuniversal な CCBENCH_* 定義を一切受けずにビルドされて
いました。プロトコル各ターゲットは ccbench_add_protocol() 経由で
target_compile_definitions(... PRIVATE ...) として受け取りますが、ccbench_common
set_compile_options()(警告/標準のみ)しか受けません。

その結果 ADD_ANALYSIS=1 のとき:

  • ccbench_commonResultADD_ANALYSIS=0(小レイアウト)でコンパイルし、小さい
    stride で resize() する。
  • プロトコル側(silo 等)は ADD_ANALYSIS=1(大レイアウト)でコンパイルし、
    leaderBackoffWork() の range-for が大きい stride で CCBenchResults を走査する。

end() は小 stride で設定されているため、大 stride のループが要素1つ分 buffer 末尾を
追い越して読み、heap-buffer-overflow になります。BACK_OFF=1 のときだけ顕在化するのは、
プロトコル側が CCBenchResults を走査する唯一の箇所 leaderBackoffWork()#if BACK_OFF
内にあるためです。

AddressSanitizer:
heap-buffer-overflow ... READ of size 8
#0 loadAcquire<uint64_t> include/atomic_wrapper.hh:34
#1 leaderBackoffWork(...) include/backoff.hh:124
#2 TxExecutor::leaderWork() cc/silo/transaction.cc:597
... buffer allocated by:
#7 initResult(...) common/result.cc:26 (CCBenchResults.resize)

修正

  1. CMakeLists.txt: ccbench_commonccbench_universal_definitions() を適用し、
    リンクするプロトコルと同じ ADD_ANALYSIS(および他の universal フラグ)を見せる。
    ccbench_common 定義時にヘルパが必要なので include(Options) を早めに追加。
  2. common/result.cc: 上記で #if ADD_ANALYSIS 専用の displayForwardingCount() が初めて
    コンパイルされ、dead 変数 num_txns(使用箇所が全てコメントアウト)が
    -Werror=unused-variable に引っかかるので [[maybe_unused]] を付与。

検証(gcc-13)

  • BACK_OFF=1 + ADD_ANALYSIS=1 が ASan clean で動作し backoff_latency_rate を出力。
  • default(ADD_ANALYSIS=0)および Release -Werror ビルドは無影響(silo は 48 スレッドで
    従来どおり完走)。

再現(修正前)

cmake -S . -B build-aa -DCMAKE_BUILD_TYPE=Debug -DENABLE_SANITIZER=ON

-DCCBENCH_BACK_OFF=1 -DCCBENCH_ADD_ANALYSIS=1
cmake --build build-aa --target ycsb_silo.exe
build-aa/cc/silo/ycsb_silo.exe -thread_num=1 -ycsb_tuple_num=10000 -extime=1

ccbench_common (common/result.cc) defines and resize()s the global
CCBenchResults (std::vector<Result>), but was compiled WITHOUT the universal
CCBENCH_* definitions that protocol targets get via ccbench_add_protocol().
Result's layout depends on `#if ADD_ANALYSIS`, so sizeof(Result) differed
between ccbench_common (ADD_ANALYSIS=0) and a protocol built with
ADD_ANALYSIS=1. leaderBackoffWork()'s range-for over CCBenchResults then walked
the buffer with the larger stride and read past its end -> heap-buffer-overflow,
seen as a segfault for any BACK_OFF=1 + ADD_ANALYSIS=1 build (confirmed with
AddressSanitizer: crash in leaderBackoffWork (backoff.hh), buffer allocated by
initResult (result.cc) resize()).

Apply ccbench_universal_definitions() to ccbench_common so it sees the same
ADD_ANALYSIS (and other universal flags) as the protocols linking it.

This compiles result.cc's ADD_ANALYSIS-only display code for the first time,
exposing a dead variable (displayForwardingCount's num_txns, whose only uses are
commented out) under -Werror=unused-variable; mark it [[maybe_unused]].

Verified with gcc-13: BACK_OFF=1 + ADD_ANALYSIS=1 now runs clean under ASan and
emits backoff_latency_rate; default (ADD_ANALYSIS=0) and Release -Werror builds
are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@thawk105 thawk105 merged commit 50c7946 into master Jun 28, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant