質問

私はdivide and Conquerの多項式アルゴリズムを実装しているので、OpenCLの実装に対してそれをベンチマークできますが、取得できません malloc 働くために。私がプログラムを実行するとき、それはたくさんのものを割り当て、いくつかのものをチェックしてから、 size/2 アルゴリズムに。それから私がヒットしたとき malloc もう一度ラインそれはこれを吐き出します:

malloc.c:3096:sysmalloc:assertion `(old_top ==(((mbinptr)((char *)」)> bins [((1) - 1) * 2]) - __builtin_offsetof(struct(struct) malloc_chunk、fd))))))&& old_size == 0)|| ((unsigned long)(old_size)> =(unsigned long)(((((__ bulintin_offsetof(struct malloc_chunk、fd_nextsize))+((2 *(sizeof(size_t))))))))))) (size_t)) - 1)))))中止

問題の行は次のとおりです。

int *mult(int size, int *a, int *b) {
    int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2;
    fprintf(stdout, "size: %d\n", size);

    out = (int *)malloc(sizeof(int) * size * 2);
}

でサイズをチェックしました fprintf, 、そしてそれは正の整数です(通常はその時点で50)。電話してみました malloc 単純な数字もありますが、それでもエラーが発生します。私はただ何が起こっているのかを困惑させていますが、これまでに私が見つけたGoogleからは何も役立ちません。

何が起こっているのか何かアイデアはありますか?コンパイラエラーである場合に備えて、新しいGCCをコンパイルする方法を見つけようとしていますが、本当に疑っています。

役に立ちましたか?

解決

99.9%がメモリを破壊した可能性が高い(バッファーを過剰または下回っているか、ポインターが解放された後にポインターに手紙を書き、同じポインターで2回無料と呼ばれるなど)

下でコードを実行します Valgrind あなたのプログラムがどこで何か正しくなかったかを見るために。

他のヒント

あなたにより良い理解を与えるために どうして これが起こります、私は @R-Samuel-Klatchkoの答えを少し拡張したいと思います。

あなたが電話するとき malloc, 、実際に起こっていることは、単にプレイする記憶の塊を与えるよりも少し複雑です。フードの下、 malloc また、それがあなたに与えた記憶に関するいくつかのハウスキーピング情報を保持します(最も重要なのは、そのサイズ)。 free, 、それはどれだけのメモリを解放するかのようなことを知っています。この情報は、メモリの場所があなたに戻る直前に一般的に保持されます malloc. 。より徹底的な情報を見つけることができます インターネット™, 、しかし、(非常に)基本的なアイデアは次のようなものです:

+------+-------------------------------------------------+
+ size |                  malloc'd memory                +
+------+-------------------------------------------------+
       ^-- location in pointer returned by malloc

あなたが電話するとき、これに基づいて(そして物事を大幅に単純化する) malloc, 、利用可能なメモリの次の部分へのポインターを取得する必要があります。これを行う非常に簡単な方法の1つは、それが与えた以前の記憶を見て、動くことです size メモリでさらに下(または上に)バイト。この実装により、あなたはあなたの記憶が割り当てられた後にこのようなものを見ることになります p1, p2p3:

+------+----------------+------+--------------------+------+----------+
+ size |                | size |                    | size |          +
+------+----------------+------+--------------------+------+----------+
       ^- p1                   ^- p2                       ^- p3

それで、あなたのエラーは何ですか?

まあ、あなたのコードがあなたが割り当てたメモリの量を誤って書いていることを想像してください(あなたがあなたの問題と同じようにあなたが必要とするよりも少ない割り当てを割り当てるため、またはあなたがあなたのコードのどこかで間違った境界条件を使用しているため)。あなたのコードが非常に多くのデータを書いているとします p2 内容が上書きし始めること p3's size 分野。あなたが今次の電話をかけるとき malloc, 、それは返された最後のメモリの位置を見て、そのサイズフィールドを見て、に移動します p3 + size そして、そこからメモリの割り当てを開始します。あなたのコードが上書きされているので size, ただし、このメモリの位置は、以前に割り当てられたメモリの後にはなくなりました。

言うまでもなく、これは大混乱を破壊する可能性があります!の実装者 malloc したがって、多くの「アサーション」、またはチェックを入れて、これら(および他の問題)が発生しようとしている場合に多くの正気チェックをしようとします。あなたの特定のケースでは、これらの主張は違反されているため、 malloc あなたのコードが本当にやるべきではないことをしようとしていることをあなたに伝えて、中止します。

前に述べたように、これは重大な過剰な単純化ですが、ポイントを説明するには十分です。のGLIBC実装 malloc 5k以上のラインであり、優れた動的メモリ割り当てメカニズムを構築する方法に関するかなりの量の研究があるため、SOの答えですべてをカバーすることは不可能です。うまくいけば、これにより、実際に問題を引き起こしているものの少しの見解が得られます!

Valgrindを使用するための私の代替ソリューション:

友達がプログラムをデバッグするのを手伝ってくれたので、とてもうれしいです。彼のプログラムにはこの正確な問題がありました(malloc() GDBから同じエラーメッセージを使用して、Abortを引き起こします。

私は彼のプログラムを使用して編集しました 住所消毒剤

gcc -Wall -g3 -fsanitize=address -o new new.c
              ^^^^^^^^^^^^^^^^^^

そして走った gdb new. 。プログラムがによって終了するとき SIGABRT その後に引き起こされます malloc(), 、多くの有用な情報が印刷されています:

=================================================================
==407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000000b4 at pc 0x7ffffe49ed1a bp 0x7ffffffedc20 sp 0x7ffffffed3c8
WRITE of size 104 at 0x6060000000b4 thread T0
    #0 0x7ffffe49ed19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x8001dab in CreatHT2 /home/wsl/Desktop/hash/new.c:59
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #4 0x8001679 in _start (/mnt/d/Desktop/hash/new+0x1679)

0x6060000000b4 is located 0 bytes to the right of 52-byte region [0x606000000080,0x6060000000b4)
allocated by thread T0 here:
    #0 0x7ffffe51eb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x8001d56 in CreatHT2 /home/wsl/Desktop/hash/new.c:55
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

出力、特にスタックトレースを見てみましょう。

最初の部分では、無効な書き込み操作があると言っています new.c:59. 。その行は読みます

memset(len,0,sizeof(int*)*p);
             ^^^^^^^^^^^^

2番目の部分では、悪い書き方が起こった記憶が作成されていると言います new.c:55. 。その行は読みます

if(!(len=(int*)malloc(sizeof(int)*p))){
                      ^^^^^^^^^^^

それでおしまい。数時間、友人を混乱させたバグを見つけるのに30分もかかりませんでした。彼はなんとか失敗を見つけることができましたが、それはその後です malloc() 前のコードでこのエラーを見つけることができずに、失敗したことを呼び出します。

合計:試してみてください -fsanitize=address GCCまたはCLANGの。メモリの問題をデバッグすると、非常に役立ちます。

あなたはおそらくどこかで割り当てられたMEMを超えてオーバーランニングしているでしょう。その後、基礎となるSWは、mallocと呼ばれるまでそれを拾いません

Mallocに捕まえられているガード価値がclobberedされている可能性があります。

編集...これを追加して、Boundsチェックヘルプを追加しました

http://www.lrde.epita.fr/~akim/ccmp/doc/bounds-checking.html

私はあなたのものと同様の次のメッセージを受け取りました:

    program: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.

Mallocを使用すると、前にいくつかのメソッドコールを間違えました。 [a+'で乗算標識'*'を誤って上書きしました。[sizeof of() - operatorを符号なしのcharアレイに追加するfactor after sizeof() - 演算子を更新するとき。

これが私の場合のエラーの責任のあるコードです。

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5);
    b[INTBITS]=(some calculation);
    b[BUFSPC]=(some calculation);
    b[BUFOVR]=(some calculation);
    b[BUFMEM]=(some calculation);
    b[MATCHBITS]=(some calculation);

別の方法では、Mallocを再度使用し、上記のエラーメッセージが作成されました。呼び出しは(十分に単純でした):

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)*50);

「+」を使用して、1回目の呼び出しに署名します。これは、アレイの即時初期化(配列に割り当てられていないメモリを上書きする)と組み合わせて誤りにつながることを考えて、Mallocのメモリマップに混乱をもたらしました。 したがって、2回目の呼び出しが間違っていました。

sizeof(int)を掛けるのを忘れたため、このエラーが発生しました。 Malloc(..)への引数は、マシンワードの数などではなく、多数のバイトです。

Linuxを介してVisual CからGCCに1つのアプリケーションを移植していましたが、同じ問題が発生しました

Malloc.C:3096:Sysmalloc:Ubuntu 11でGCCを使用したアサーション。

同じコードを(他のコンピューターで)suse配布に移動しましたが、問題はありません。

問題は私たちのプログラムではなく、独自のLIBCにあるのではないかと思います。

同じ問題が発生しました。新しいChar *Stringデータを追加するために、ループでMallocを再び使用しました。私は同じ問題に直面しましたが、割り当てられたメモリをリリースした後 void free() 問題がソートされました

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top