0

私はこのようなコマンドという名前の構造を持っています。列挙型の最初の値はAND_COMMANDです

struct command
{
  enum command_type type;
  int status;
  char *input;
  char *output;
  union
  {
    struct command *command[2];
    char **word;
    struct command *subshell_command;
  } u;
};

pthread_createを呼び出すときは、command_tの形式でコマンドを渡します(これは(void *)にキャストされます)。

typedef struct command *command_t;

私のスレッドはこれ(void *)command_tを受け取り、それをキャストバック(command_t)して、構造を使用しようとします。

void execute_thread(void *c) {
  command_t command = (command_t) c;

ただし、execute_threadに構造体を渡すと、最初の値はゼロになります。command_typeがSIMPLE_COMMANDでステータスが-1の場合、スレッドに渡されると、command_typeはAND_COMMANDでステータスは0になります。ただし、構造体の他の値は変更されません。さらに興味深いのは、このデータマングリングがいつ発生するかです。この現象をgdbでキャプチャできました。

445   command_t command = (command_t) c;
(gdb) p *((command_t) c)
$6 = {type = SIMPLE_COMMAND, status = -1, input = 0x605370 "abc", output = 0x605390 "def", u = {
command = {0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}
(gdb) n
(gdb) p *((command_t) c)
$7 = {type = AND_COMMAND, status = 0, input = 0x605370 "abc", output = 0x605390 "def", u = {command = {
  0x6052e0, 0x0}, word = 0x6052e0, subshell_command = 0x6052e0}}

(command_t) c;cが指す構造は、私と一緒にキャストするまで変更されないようです。この動作に完全に混乱しています。ポインタをキャストすると、それが指す値が変わるとは思いませんでした。誰かが指摘してもらえますか、ハハ、ここで何が起こっているのでしょうか?よろしくお願いします。

4

1 に答える 1

2

さらに興味深いのは、このデータ マングリングがいつ発生するかです。gdb で現象をキャプチャできました。

ここでの言い回しは、問題が決定論的ではないと私に信じさせます。つまり、時々発生しないか、たまたま質問でgdbにキャプチャした瞬間に発生しません。

その場合(そうでない場合でも)、問題はstruct commandメインスレッド(またはスレッドを作成しているexecute_thread()スレッド)で割り当てられたメモリを破棄していることだと思います。スレッド作成コードは表示されませんでしたが、ローカル変数を使用してそのアドレスを作成されたスレッドに渡す場合、ローカル変数の有効期間が 2 番目のスレッドの前に期限切れにならないようにするのは難しい場合があります。それを使用するようになります。struct commandヒープに割り当てられたを渡したい場合があります。

struct command* thread_data = malloc(sizeof(struct command));
struct_command_init(thread_data);

pthread_create(/* ... */, thread_data);
// ...

そしてexecute_command()スレッドで:

void* execute_command(void* p)
{
    struct command cmd = *(struct command*)p;
    free(p);

    // use cmd to get at the structure data passed in...
}

さまざまなポインターによって参照されるデータstruct commandも、それらの有効期間と所有権を明確に管理する必要があることに注意してください。

于 2013-02-03T10:13:26.727 に答える