# base::debug::Alias [base::debug::Alias](https://source.chromium.org/chromium/chromium/src/+/main:base/debug/alias.h;l=71;drc=6bd86800ed33e2765ffb14b63364f15b043ed20c)というメソッドがある。 ```cpp= ErrnoLogMessage::~ErrnoLogMessage() { stream() << ": " << SystemErrorCodeToString(err_); int last_error = err_; base::debug::Alias(&last_error); } ``` ## これはなに ```cpp= NOINLINE void Alias(const void* var) {} ``` `NOINLINE` attributeはこのメンバ関数をインラインにしないようにコンパイラに指示している。 この関数は実装が空っぽだがヘッダーファイルにその実装の定義を書いてはいけない。 alias.hをincludeしているところからbase::debug::Alias()を呼んでもその実装がリンク時までわからないようになっている必要がある。なので.ccファイルの中で定義しているし、NOINLINEをつけることでインライン展開を防ぎリンク時最適化(LTO)を防いでいる。 TODO(elkurin): ちゃんとリンク時最適化が起きるタイミングがよくわかってないので確認 結果何が起きるかというと、渡された引数`var`がどう扱われるかわからないので、実際は不要な挙動ではあるが最適化によって消えない。 ## 使用例 基本的にコンパイラの最適化による困った挙動を回避するために使われる。 以下に、例示されている使用方法をまとめる。 ### Prevent being optimized out コンパイラの最適化で実質不要な変数が省略されることがある。 例えば以下のようなローカル変数は消える。 ```cpp= int last_error = error_; CHECK(false); ``` CHECK(false)でクラッシュするとクラッシュ時にもう`error_`の値は死んでいる。 しかしCrash dumpに出力するためには`error_`が生き残って欲しい。 それを解決するためにbase::debug::Aliasが使える。 ただし、スタック領域にコピーすることでキープするロジックなので、保存する値はポインタではなく実値でないといけない。ポインタの場合、ポインタの値そのものは残るがポイント先のメモリが残っているかの保証はないため。 ### コールスタックに登場させる StackTraceを見ていると、たまに関数の呼び出しが飛んでいることがあり、追いたいスタックが負えないことがある。 それでは困る場合以下のようにかける。 ```cpp= NOINLINE void Foo() { ...; Bar(); base::debug::Alias(nullptr); } ``` Aliasの呼び出しが挟まるため、Fooが省略されず、StackTraceにも必ず現れるようになるということ。 ### non-unique関数のfoldを防ぐ 2つのidenticalな実装の関数は同じアドレスにアサインされることがある。Code foldingと呼ばれ、リンカーの最適化の一種。 これも、シンボル名で区別したい時など困ることがある。 以下のように防げる。 ```cpp= NOINLINE void Foo() { NO_CODE_FOLDING(); Bar(); } ``` なおNO_CODE_FOLDINGはbase::debug::Aliasを用いた以下のようなマクロである。 ```cpp #define NO_CODE_FOLDING() \ const int line_number = __LINE__; \ base::debug::Alias(&line_number) ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up