最新世代のコンパイラは非常にスマートになり、ほとんど独立してコードを生成し、すべてを連続して最適化します。 時にはこれは不快な結果につながります。
Linux 3.16カーネルで次のリリース候補を準備する過程で、Linux 3.16-rc6のロードバランシング機能の完全に予測できない動作を発見しました。 カーネル開発者向けのメーリングリストでは、2人の作成者が異なるバグに関するメッセージを送信しましたが、共通の性質を持つ可能性があります。
Linus Torvaldsは質問を注意深く整理し、バグレポートの1つに
簡潔に答えました。
ライナスの手紙の継続。
gcc-4.9.0は最終的に壊れているように見えるので、私はYakubをメーリングリストに含めました。
見てください、あなたのコンパイラは、 定数を混雑させるなど、データを混雑させる(流出させる)ことで絶対に想像を絶することをします。 主よ、このコンパイラはまだ幼稚園を離れるべきではありません。 私たちは子供の頃に頭を落としたバカについて話している-それは発達遅延のレベルです:
... movq $load_balance_mask, -136(%rbp) #, %sfp subq $184, %rsp #, movq (%rdx), %rax # sd_22(D)->parent, sd_parent movl %edi, -144(%rbp) # this_cpu, %sfp movl %ecx, -140(%rbp) # idle, %sfp movq %r8, -200(%rbp) # continue_balancing, %sfp movq %rax, -184(%rbp) # sd_parent, %sfp movq -136(%rbp), %rax # %sfp, tcp_ptr__ #APP add %gs:this_cpu_off, %rax # this_cpu_off, tcp_ptr__ #NO_APP ...
-136(%rbp)
の内容に注意してください。 本当に。 これは、コンパイラーが置き換えた直接定数です。
誰かがこれをgccのバグとして発行する必要があります。 クソクソクレイジーくそだから。
しかし、定数の混み合っているこの部分は、「生きるにはあまりにも愚かな」と考えることができます。 本当のバグはこちらです:
movq $load_balance_mask, -136(%rbp) #, %sfp subq $184, %rsp #,
ここで、gccは、スタックフレームよりもはるかに多くの定数を保存するために使用した後 、スタックフレームを作成します。
いずれにしても、これはカーネルのバグではない、とLinusは強調しています。 彼は、gcc-4.9.0コンパイラを使用しないよう全員に公式の警告を作成し、「Debianユーザーはおそらく新しいクールなコンパイラをダウングレードするべきだ」と提案しています。
PS
コメントのあるユーザー
a5bのコメント :Linus
は、バグ61904 (gcc bugzilla)が
バグ61801の複製としてクローズされたことを
発見しました 。 61801は、gccのバージョン4.5.0から4.8.3、4.9.0、4.9.1に存在していました(ただし、4.9.0までは、エラーによりload_balanceコードの定数が切断されませんでした)。 4.8.4、4.9.2、4.10.0以降に修正されました。 パッチ
-sched_analyze_2の1行 。