18

最近のプロジェクトに取り組んでいるときに、顧客の QA 担当者が訪ねてきて、以前はあまり考えていなかった質問をしてきました。

使用しているコンパイラが C コードの機能と正確に一致するマシン コードを生成し、コンパイラが完全に決定論的であることをどのように確認しますか?

この質問に対して、私は常にコンパイラーを当然のことと思っていたので、まったく答えられませんでした。コードを取り込み、マシンコードを吐き出します。コンパイラが要求していない機能を実際に追加していないことをテストするにはどうすればよいですか? または、私が期待するものとはわずかに異なる方法でコードを実装するさらに危険なことはありますか?

これはおそらくすべての人にとって問題ではないことを認識しており、実際、答えは...「あなたはバレルを超えているので、それに対処する」だけかもしれません。ただし、組み込み環境で作業する場合は、コンパイラを暗黙のうちに信頼します。自分が正しいことを自分自身と QA に証明するにはどうすればよいですか?

4

22 に答える 22

12

その議論はどのレベルでも適用できます。サードパーティのライブラリを信頼しますか? OSを信頼しますか?プロセッサを信頼しますか?

もちろん、これが有効な懸念事項である理由の良い例は、Ken Thompson が元の「ログイン」プログラムにバックドアを配置した方法です...ログインを再コンパイルしてもバックドアを取得できるように C コンパイラを変更しました。詳細については、この投稿を参照してください。

暗号化アルゴリズムについても同様の質問が提起されています。NSA が詮索するためのバックドアが DES にないことをどのようにして知ることができますか?

最後に、構築しているインフラストラクチャを信頼して心配する必要がないかどうかを判断する必要があります。信頼できない場合は、独自のシリコン チップの開発を開始する必要があります。

于 2008-09-13T14:10:58.830 に答える
11

安全性が重要な組み込みアプリケーションの認証機関は、コンパイラの「使用実績」要件を満たす必要があります。通常、特定の要件 (「稼働時間」のようなもの) を満たし、詳細な文書によって証明する必要があります。ただし、ほとんどの人は、特に新しいターゲット/コンパイラを使用する最初のプロジェクトでは非常に困難になる可能性があるため、これらの要件を満たすことができないか、または満たしたくありません。

もう1つのアプローチは、基本的にコンパイラの出力をまったく信頼しないことです。コンパイラや言語依存 (C-90 標準の付録 G など) の欠陥は、後の機能テストに加えて、静的解析、単体テスト、カバレッジ テストの厳密なセットでカバーする必要があります。

MISRA-Cのような標準は、コンパイラへの入力を C 言語の「安全な」サブセットに制限するのに役立ちます。もう 1 つの方法は、コンパイラへの入力を言語のサブセットに制限し、サブセット全体の出力をテストすることです。アプリケーションがサブセットのコンポーネントのみで構築されている場合、コンパイラの出力がどうなるかはわかっていると想定されます。通常、「コンパイラの資格」によって行われます。

このすべての目標は、QA 担当者の質問に「コンパイラの決定論に頼るだけではなく、これが証明する方法です...」と答えることができるようにすることです。

于 2008-09-13T18:05:12.857 に答える
7

あなたはテストによって知っています。テストするときは、コードとコンパイラの両方をテストしています。

あなたやコンパイラの作成者がエラーを起こす可能性は、問題のプログラムをアセンブリ言語で書いた場合にエラーを起こす可能性よりもはるかに小さいことがわかります。

于 2008-09-16T21:33:37.947 に答える
5

利用可能なコンパイラ検証スーツがあります。
私が覚えているのは「Perennial」です。

組み込み SOC プロセッサ用の C コンパイラに取り組んだとき、これと他の 2 つの検証スーツ (名前は忘れました) に対してコンパイラを検証する必要がありました。これらのテスト スイートに対するコンパイラの適合性を特定のレベルまで検証することは、契約の一部でした。

于 2008-09-17T22:52:06.593 に答える
3

防衛ソフトウェア エンジニア向けの雑誌である Crosstalk には、知的な弾薬が見つかるかもしれません。この質問は、彼らが起きている時間の多くを費やすようなものです. http://www.stsc.hill.af.mil/crosstalk/2006/08/index.html (古いプロジェクトから古いメモを見つけることができれば、ここに戻ってきます...)

于 2008-10-08T02:28:33.267 に答える
3

それはすべて信頼に帰着します。あなたの顧客はコンパイラを信頼していますか? それを使用するか、少なくともあなたと彼らの出力コードを比較してください。

彼らが何も信頼していない場合、その言語の参照実装はありますか? 彼らにそれを信頼するよう説得できますか? 次に、参照と比較するか、参照を使用します。

これはすべて、ベンダー/プロバイダーから取得した実際のコードを実際に検証し、コンパイラーが改ざんされていないことを確認することを前提としています。これが最初のステップである必要があります。

とにかく、これはまだ、参照なしでコンパイラを最初から検証する方法についての疑問を残しています。それは確かに膨大な作業のように見え、言語の定義が必要です。これは常に利用できるとは限りません。定義がコンパイラである場合もあります。

于 2008-09-13T14:08:01.757 に答える
3

使用しているコンパイラが C コードの機能と正確に一致するマシン コードを生成し、コンパイラが完全に決定論的であることをどのように確認しますか?

それが結果のバイナリをテストする理由であり、テストしたのと同じバイナリを確実に出荷する理由です。また、ソフトウェアに「マイナーな」変更を加える場合、古い機能が壊れていないことを確認するために回帰テストを行うのはなぜですか。

私が認定した唯一のソフトウェアはアビオニクスです。FAA 認定は、ソフトウェアが正しく動作することを証明するほど厳密ではありませんが、同時に、一定量のフープを飛び越える必要があります。秘訣は、「プロセス」を構造化して、可能な限り品質を向上させ、無関係なフープジャンプをできるだけ少なくすることです。したがって、あなたが知っていることはすべて価値がなく、実際にバグを見つけることはありません. そして、FAA から明示的に要求されていないバグを見つけるため、何をすべきかを知っている場合は、FAA/QA 担当者が要求したものを提供しているように聞こえるまで、言葉をねじ曲げることが最善の策です。

これは実際、私が言っているほど不誠実ではありません。一般的に、FAA は、あなたが正確に何をするかよりも、あなたが良心的で、良い仕事をしようとしていることに自信を持っていることを重視しています。

于 2008-10-07T00:56:04.890 に答える
3

強く推奨されているものであっても、コンパイラを完全に信頼することはできません。彼らはバグのある更新をリリースする可能性があり、コードは同じものをコンパイルします。この問題は、バグのあるコンパイラで古いコードを更新し、テストを行って商品を発送したときに、3 か月後に顧客から問題が発生した場合にのみ発生します。

すべてはテストに戻ります。私が学んだことが 1 つあるとすれば、重要な変更を行った後は徹底的にテストすることです。問題が見つからない場合は、コンパイルされたアセンブラを調べて、本来の動作を行っているかどうかを確認してください。

何度か、コンパイラにバグが見つかりました。1 回、16 ビット変数がインクリメントされるがキャリーがなく、16 ビット変数がヘッダー ファイルで定義された extern 構造体の一部である場合にのみ、バグがありました。

于 2008-10-26T14:23:58.397 に答える
2

ええと..コンパイラの出力を信頼していると単純に言うことはできません-特に埋め込みコードで作業している場合はそうです。まったく同じコードを異なるコンパイラでコンパイルするときに生成されるコード間の不一致を見つけるのは難しくありません。これは、C標準自体が緩すぎるためです。多くの詳細は、標準を破ることなく、異なるコンパイラーによって異なる方法で実装できます。このようなものにどのように対処しますか?可能な限り、コンパイラに依存する構造は避けます。ユーザーcscholが前述したように、 Misra-CのようなCのより安全なサブセットを選択することで対処できます。コンパイラーによって生成されたコードを検査する必要はめったにありませんが、それは時々私にも起こりました。ただし、最終的には、コードが意図したとおりに動作することを確認するために、テストに依存しています。

そこにもっと良いオプションはありますか?あると主張する人もいます。もう1つのオプションは、 SPARK/Adaでコードを記述することです。。私はSPARKでコードを書いたことがありませんが、「ベアメタル」のものを処理するCで書かれたルーチンに対してコードをリンクする必要があることを理解しています。SPARK / Adaの利点は、コンパイラによって生成されるコードが常に同じになることが絶対に保証されることです。あいまいさは一切ありません。その上、この言語を使用すると、コードがどのように動作するかについての説明をコードに注釈を付けることができます。SPARKツールセットは、これらのアノテーションを使用して、記述されたコードが実際にアノテーションで説明されていることを実行することを正式に証明します。したがって、重要なシステムの場合、SPARK/Adaはかなり良い賭けだと言われています。でも、自分で試したことはありません。

于 2010-01-08T02:15:23.137 に答える
2

コンパイラが期待どおりに動作するかどうかはわかりません。その理由はもちろん、コンパイラはソフトウェアの一部であり、バグの影響を受けやすいからです。

コンパイラの作成者は、高品質の仕様に基づいて作業できるという利点がありますが、それ以外の私たちは、作業を進めながら何を作成しているかを把握する必要があります。ただし、コンパイラの仕様にもバグがあり、微妙な相互作用を伴う複雑な部分もあります。したがって、コンパイラが何をすべきかを理解するのは簡単なことではありません。

それでも、言語仕様が何を意味すると考えるかを決定したら、すべてのニュアンスに対して優れた高速の自動テストを作成できます。これは、コンパイラーの記述が他の種類のソフトウェアの記述に比べて大きな利点がある場合です: テストにおいてです。すべてのバグは自動化されたテスト ケースになり、テスト スイートは非常に徹底できます。コンパイラ ベンダーは、コンパイラの正確性を検証するために、あなたよりも多くの予算を投資しています (あなたはすでに日雇いの仕事をしていますよね?)。

これはあなたにとって何を意味しますか?これは、コンパイラのバグの可能性に対してオープンである必要があることを意味しますが、自分でバグを見つけられない可能性があります。

すぐに廃業する可能性が低く、コンパイラの品質が高く、製品のサービス (パッチ) の能力が実証されているコンパイラ ベンダーを選択します。コンパイラは時間の経過とともにより正確になるように見えるので、私は 10 年か 20 年ほど経ったものを選びます。

コードを正しく作成することに注意を向けてください。明確で単純な 場合は、コンパイラのバグに遭遇たときに、問題がどこにあるかを判断するために真剣に考える必要はありません。 適切な単体テストを作成します。これにより、コードが期待どおりに動作することが保証されます。

于 2008-09-13T15:27:22.297 に答える
2

...コンパイラを暗黙的に信頼する

コンパイラのバグに初めて遭遇したときは、それをやめるでしょう。;-)

しかし、最終的にはこれがテストの目的です。そもそもバグが製品にどのように侵入したかは、テスト体制にとって重要ではありません。重要なのは、広範なテスト体制に合格しなかったことだけです。

于 2008-09-24T03:38:34.240 に答える
1

CompcertCコンパイラなどのフォーマル検証済みコンパイラを選択します。

于 2010-01-07T12:51:49.597 に答える
1

あなたはダイクストラが書いたものを手に入れます。

于 2008-10-26T14:38:58.927 に答える
1

ほとんどのソフトウェア開発 (デスクトップ アプリケーションを考えてください) の答えは、おそらく、あなたは知らないし、気にしないということです。

安全性が重要なシステム (原子力発電所や商用アビオニクスを考えてみてください) では注意を払う必要があり、規制当局はそれを証明するよう要求します。私の経験では、これは次の 2 つの方法のいずれかで行うことができます。

  1. 認定されたコンパイラを使用してください。「認定済み」とは、規制機関によって定められた基準に従って検証されたことを意味します。
  2. オブジェクト コード分析を実行します。基本的に、参照コードの一部をコンパイルし、出力を手動で分析して、コンパイラがソース コードまでたどることができない命令を挿入していないことを示します。
于 2008-09-17T20:04:56.013 に答える
1

積極的なレベルの最適化を要求すると、行動の変化が得られることがあります。

最適化と浮動小数点数は?忘れてください!

于 2008-09-13T15:00:48.320 に答える
1

単体テストを試してください。

それでも不十分な場合は、さまざまなコンパイラを使用して単体テストの結果を比較してください。strace の出力を比較し、VM でテストを実行し、ディスクとネットワーク I/O のログを保持してから、それらを比較します。

または、独自のコンパイラを作成して、そのコストを伝えることを提案します。

于 2008-09-13T13:58:34.493 に答える
1

簡単に証明できるのは、プロバイダー X の改ざんされていないコンパイラを使用していることです。プロバイダー X が信頼されていない場合、それは彼らの問題です (X が十分に信頼できる場合)。彼らがどのコンパイラ プロバイダも信頼していない場合は、完全に不合理です。

彼らの質問に答える: 私は、これらの手段を通じて、X から改ざんされていないコンパイラを使用していることを確認します。X は評判が高く、さらに、アプリケーションが期待どおりに動作することを示す優れた一連のテストがあります。

他のすべてがワームの缶を開け始めています。ロブが言うように、どこかで立ち止まらなければなりません。

于 2008-09-13T14:27:29.680 に答える
0

認定または認定されたコンパイラでさえ、望ましくない結果を生成する可能性があります。コードをシンプルに保ち、テスト、テスト、テストします。それか、人為的ミスを許さずに機械コードを手作業で調べます。加えて、オペレーティング システムまたは実行している環境 (できれば、オペレーティング システムはなく、プログラムのみ)。

この問題は、ソフトウェアとコンパイラが登場して以来、ミッション クリティカルな環境で解決されてきました。回答した他の多くの人も知っています。各業界には、認定されたコンパイラからプログラミング スタイル (常にこの方法でプログラミングする必要があり、これを使用したり、あれを使用したりしないでください)、多くのテストやピア レビューなど、独自のルールがあります。すべての実行パスの検証など

あなたがそれらの業界のいずれにも属していない場合は、得られるものを手に入れることができます。COTS ハードウェア上の COTS オペレーティング システム上の商用プログラム。それは失敗します、それは保証です。

于 2008-09-19T00:57:33.900 に答える
0

この問題をどうにかして停止問題に還元することは可能だと思います。

最も明白な問題は、ある種のプログラムを使用してコンパイラとその決定論を分析する場合、プログラムが正しくコンパイルされ、正しい結果が生成されることをどのようにして知ることができるかということです。

ただし、別の「安全な」コンパイラを使用している場合は、わかりません。私が確信しているのは、コンパイラをゼロから作成する方がおそらく簡単な仕事だということです。

于 2008-09-13T15:02:57.147 に答える
0
  1. コンパイラの最適化レベルを変更すると、出力が変更されます。
  2. 関数にわずかな変更を加えると、コンパイラがインライン化されるか、関数がインライン化されなくなります。
  3. コンパイラ (gcc のバージョンなど) を変更すると、出力が変わる可能性があります
  4. 一部のライブラリ関数は組み込み (つまり、最適化されたアセンブリを発行する) である場合がありますが、ほとんどのライブラリ関数はそうではありません。

幸いなことに、ほとんどの場合、それはそれほど重要ではありません。それが行われる場合、それが本当に重要な場合 (ISR など) は、アセンブリを検討することをお勧めします。

于 2008-09-13T14:16:46.197 に答える
0

目に見える結果が得られない予期しないマシン コードについて懸念がある場合、おそらく唯一の方法は、コンパイラ ベンダーに連絡して、顧客を満足させる何らかの認証を取得することです。

それ以外の場合は、コードのバグについて知っているのと同じように知っているでしょう-テスト.

最新のコンパイラの機械語コードは、非常に異なっており、ちっぽけな人間にはまったく理解できないことがあります。

于 2008-09-13T14:27:35.123 に答える
0

コンパイラの悪意のあるバグが心配な場合、1 つの推奨事項 (IIRC、一部のプロジェクトの NSA 要件) は、コンパイラ バイナリがコードの記述よりも前にあることです。少なくとも、あなたのプログラムを対象としたバグを誰も追加していないことがわかります。

于 2010-01-07T18:53:39.597 に答える