2

編集:私の仮定を無視するようにタイトルを変更しました。

c で記述されたライブラリがあります。このライブラリは、posix メッセージ キューを使用して、スレッド間のランタイム データへのポインタを渡します。

データがユーザー アプリケーションからのものである場合、すべて正常に動作しているように見え、メッセージ キューからの構造体へのポインタが指すデータにアクセスできます。

ここで、ライブラリ自体が構造体の 1 つのインスタンスの malloc を実行し、フラグを設定して同じキューに送信する特別なケースがあります。受信側では、構造体は空で、フラグはゼロです。ポインターで free を呼び出すと、クラッシュが発生します。

コードは次のとおりです。

volatile s_thestruct * volatile data = malloc(sizeof(s_thestruct));
data->flags = THE_FLAG;
mq_send(handle, (char *)&data, sizeof(s_thestruct *), 1)

そして、受信側で:

ssize_t read = mq_receive(handle, (char*)&data, sizeof(s_thestruct*), NULL);
if(read != sizeof(s_thestruct *))
{
 // Error handling, no problems here
}
if(data->flags == THE_FLAG)
{
// Do something, never gets here
}
// Do something else, no it is not freed here

// Finally
free(data); // <--CRASH

そして私は得るでしょう:

*** glibc detected *** /usr/bin/applicationthingy: free(): invalid pointer: 0x08053cf0 ***

続いてダンプ。メモリ マップ ダンプ内に次のものが見つかります。

....
08048000-0804a000 r-xp 00000000 08:01 802680     /usr/bin/applicationthingy
0804a000-0804b000 r--p 00001000 08:01 802680     /usr/bin/applicationthingy
0804b000-0804c000 rw-p 00002000 08:01 802680     /usr/bin/applicationthingy
0804c000-0806f000 rw-p 00000000 00:00 0          [heap]
b6e00000-b6e21000 rw-p 00000000 00:00 0 
....

それで、誰かがここで何が起こっているかについて何か提案を受けましたか?

4

2 に答える 2

4

それらが同じアドレス空間からのものであると仮定すると、それ(ポインターの受け渡し)は問題なく機能するはずです。

私が考えることができる唯一のことは、キューがのプロセスから書き込まれている可能性があるかどうかです? ポインターが指しているものはプロセスによってまったく異なるため、ポインターは役に立たなくなります。

正直なところ、構造自体が大規模でない限り、そのようにポインターを渡すことはありません。構造体を渡すと、適切なプロセス間キューを実行できるというすべての利点が得られます。

もう 1 つ確認することは、ライブラリがメイン コードとは異なるメモリ領域から何らかの方法で割り当てを取得していることです。これは失敗の原因となる状況ですが、free異なるアリーナを使用していても、両方が同じアドレス空間にあるため、おそらく間違ったフラグではありません。

最低限、data送信側と受信側で の値を出力して、無傷であることを確認する必要があります。のコードが破損している可能性は十分にあります (バッファ オーバーフローなど)。

于 2012-10-04T10:24:39.947 に答える
1

dataではなく&data(データのアドレス)を渡す必要がありますmq_send(handle, (char *)&data, sizeof(s_thestruct *), 1)

于 2012-10-04T10:26:51.773 に答える