1

モノリシックなコードを動的にロードされたライブラリに分割し、main()それを呼び出します。stdc++ 以外のライブラリは使用せず、クラスもありません。メンバー関数を持たないテンプレート化された構造体だけです。メモリを明示的に割り当てたり、コード内の何かを削除または解放したりしていません。からオブジェクトを消去しますlist<T>

ライブラリ + メインに切り替えた後、断続的にクラッシュします。

*** glibc detected *** : free(): invalid pointer:

バックトレースから、リスト イテレータが関与しているように見えますが、名前がマングルされたシンボルのため、確認が難しくなっています。

ただし、gdb 内でクラッシュすることはなく、valgrind がメモリの破損やリークを検出することもありません。

以前に共有ライブラリを構築したことがありません。これは私が使用しているものです

g++ -fPIC -shared library_src.cpp -o libblaH.so

g++ main.cpp -lblaH

ライブラリ全体が単一のソース ファイルにあり、ライブラリ関数は extern "C"ブロックにラップされて c ユーザーがアクセスできるようになっていますが、現在、g++ を使用して main() を c++ コードとしてコンパイルしています。

最適化オプションを追加すると、-O2(特に) クラッシュが発生し始めます。

無効なポインターがmallocelectricfenceによって割り当てられなかったと言っています。

バグを追い詰める方法についての提案をいただければ幸いです。どこかでリストイテレータを無効にしているように感じますが、どうすればよいかわかりません。削除されたエントリを除いて、無効にすることはできないと思いました。

4

1 に答える 1

1

何らかの理由で、これは初期化されていない変数を私に叫びます。何年も前に、このようなクラッシュのデバッグを支援するために企業に時間単位で料金を請求したとき、半分の時間で、問題は初期化されていない変数でした。

私が使用するアプローチは次のとおりです。

  1. すべての変数を体系的に初期化し、宣言時にそれらをすべて初期化します。絶対に例外はありません。
  2. 無効化された反復子を探します。つまり、消去されたオブジェクトを指すイテレータは無効になるため、使用しないでください。
  3. 変数のハイジャックを探します。つまり、同じ名前の変数は同じ翻訳単位では正常に機能しましたが、別の翻訳単位では機能しません。
  4. フォーマット文字列がパラメーターと一致しない、sprintf などの安全でない関数呼び出しを探します。
  5. #pragma を使用してコードの一部の最適化を選択的に無効にし、問題領域を絞り込みます。二分探索のようなものです。前半を無効にしてもまだクラッシュする、後半に問題がある、前半を無効にして後半の 1/2 を...

複数のスレッドが関与していないと仮定しています。スレッドが関与すると、さらに多くのことがうまくいかなくなる可能性があります。私が顧客サイトに雇われたとき、デバッガーを起動する前に、常にすべての変数を最初に初期化してもらいました。50% の確率で、ステップ 1 の後、家に帰ることができます。

于 2012-09-30T03:51:43.740 に答える