[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
質問
FDK-AACへのJNAブリッジを実装しています。ソースコードは こちら
私のコードをベンチマークすると、同じ入力で何百回も成功することがあるのですが、たまにCレベルのクラッシュが発生してプロセス全体が停止し、コアダンプが生成されることがあります。
コアダンプを見ると、こんな感じです。
#1 0x00007f3e92e00f5d in __GI_abort () at abort.c:90
#2 0x00007f3e92e4928d in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7f3e92f70528 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007f3e92e5064a in malloc_printerr (action=<optimized out>, str=0x7f3e92f6cdee "corrupted size vs. prev_size", ptr=<optimized out>, ar_ptr=<optimized out>) at malloc.c:5426
#4 0x00007f3e92e5304a in _int_free (av=0x7f3de0000020, p=<optimized out>, have_lock=0) at malloc.c:4337
#5 0x00007f3e92e5744e in __GI___libc_free (mem=<optimized out>) at malloc.c:3145
#6 0x00007f3e113921e9 in FDKfree (ptr=0x7f3de009df60) at libSYS/src/genericStds.cpp:233
#7 0x00007f3e1130d7d3 in Free_AacEncoder (p=0x7f3de0115740) at libAACenc/src/aacenc_lib.cpp:407
#8 0x00007f3e1130fbb3 in aacEncClose (phAacEncoder=0x7f3de0115740) at libAACenc/src/aacenc_lib.cpp:1395
このバック/スタックトレースエラーは、ベンチマークを何度も繰り返せば再現可能なのですが、何が原因でこのようなエラーが発生するのか理解に苦しみます。ポインタに割り当てられたメモリ {コード {コード はCPP/Cのコード内部でも同様に割り当てられ、割り当てられた同じインスタンスが解放されていることは保証できます。ベンチマークはもちろんシングルスレッドです。
これらを読んで
セキュリティチェック && 内部機能
私はまだ理解に苦しんでいます - 私が上記のエラーを取得する原因となる実際の(非搾取ではなく、むしろエラー))シナリオは何でしょうか? そしてなぜ非常にまれにしか発生しないのでしょうか?
現在の疑惑 :
詳細なバックトレースを実行すると、このような入力があります。
0x7f3de009df60
- フレーム内 #6 の場合、問題のポインタが {コード . {を使用します。 フレーム内 #4 これは、リリースされる構造体の予想されるサイズです。
- しかし
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 set = {__val = {4, 6378670679680, 645636045657660056, 90523359816, 139904561311072, 292199584, 139903730612120, 139903730611784, 139904561311088, 1460617926600, 47573685816, 4119199860131166208, 139904593745464, 139904553224483, 139904561311136, 288245657}} pid = <optimized out> tid = <optimized out> #1 0x00007f3e92e00f5d in __GI_abort () at abort.c:90 save_stage = 2 act = {__sigaction_handler = {sa_handler = 0x7f3de026db10, sa_sigaction = 0x7f3de026db10}, sa_mask = {__val = {139903730540556, 19, 30064771092, 812522497172832284, 139903728706672, 1887866374039011357, 139900298780168, 3775732748407067896, 763430436865, 35180077121538, 4119199860131166208, 139904561311552, 139904553065676, 1, 139904561311584, 139904561312192}}, sa_flags = 4096, sa_restorer = 0x14} sigs = {__val = {32, 0 <repeats 15 times>}} #2 0x00007f3e92e4928d in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7f3e92f70528 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:181 ap = {{gp_offset = 40, fp_offset = 32574, overflow_arg_area = 0x7f3e11adf1d0, reg_save_area = 0x7f3e11adf160}} fd = <optimized out> list = <optimized out> nlist = <optimized out> cp = <optimized out> written = <optimized out> #3 0x00007f3e92e5064a in malloc_printerr (action=<optimized out>, str=0x7f3e92f6cdee "corrupted size vs. prev_size", ptr=<optimized out>, ar_ptr=<optimized out>) at malloc.c:5426 buf = "00007f3de009e9f0" cp = <optimized out> ar_ptr = <optimized out> ptr = <optimized out> str = 0x7f3e92f6cdee "corrupted size vs. prev_size" action = <optimized out> #4 0x00007f3e92e5304a in _int_free (av=0x7f3de0000020, p=<optimized out>, have_lock=0) at malloc.c:4337 size = 2720 fb = <optimized out> nextchunk = 0x7f3de009e9f0 nextsize = 736 nextinuse = <optimized out> prevsize = <optimized out> bck = <optimized out> fwd = <optimized out> errstr = 0x0 locked = <optimized out> #5 0x00007f3e92e5744e in __GI___libc_free (mem=<optimized out>) at malloc.c:3145 ar_ptr = <optimized out> p = <optimized out> hook = <optimized out> #6 0x00007f3e113921e9 in FDKfree (ptr=0x7f3de009df60) at libSYS/src/genericStds.cpp:233 No locals. #7 0x00007f3e1130d7d3 in Free_AacEncoder (p=0x7f3de0115740) at libAACenc/src/aacenc_lib.cpp:407 No locals. #8 0x00007f3e1130fbb3 in aacEncClose (phAacEncoder=0x7f3de0115740) at libAACenc/src/aacenc_lib.cpp:1395 hAacEncoder = 0x7f3de009df60 err = AACENC_OK
は {コード {コード であり、解放される現在のポインタから2704バイトしかない。 というのは、 - エラー再現時に必ずこのような状態になることが確認できています。
- これは、私が直面しているエラーの強い兆候かもしれませんね?
解決方法は?
OK、それでこの問題を克服することができたよ。
まず第一に、「破損したサイズ vs. prev_size」の現実的な原因は非常に単純で、コードによる境界外アクセスによって、隣接する後続チャンクのメモリチャンク制御構造フィールドが上書きされていることです。
{コード
{コード
バイトのポインタ
{コード
{コード
を超えて書いてしまう。
0x7f3de009df60
これは、現在のメモリ割り当て(チャンク)サイズと、次のチャンク制御構造で見つかるものが(上書きされたために)同じでないことを示すエラーです。
このメモリリークの原因として、Java/JNA層で行われる構造体マッピングが異なることを示唆しています。
nextchunk
dll/soがコンパイルされたときとは、関連するパディングやアライメントが異なっています。このため、割り当てられた構造体の境界を越えてデータが書き込まれることがありました。このアライメントを無効にすることで、問題が解消されました。(数千回の実行で一度もクラッシュしませんでした!).
関連
-
[解決済み】コンストラクターでのエラー:識別子を期待されますか?
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】抽象クラス型の無効なnew-expression
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】1つのホストで複数のglibcライブラリを使用する場合
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】変数 '' を抽象型 '' と宣言できない。
-
[解決済み】C++エラー:の初期化に一致するコンストラクタがありません。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】デバッグアサーションに失敗しました。C++のベクトル添え字が範囲外
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】C++ - ステートメントがオーバーロードされた関数のアドレスを解決できない。
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み】 while(cin) と while(cin >> num) の違いは何ですか?)