【问题标题】:Struct argument passed in pthread create gets mangled在 pthread create 中传递的结构参数被破坏
【发布时间】:2013-02-03 08:10:55
【问题描述】:

我有一个名为 command 的结构,看起来像这样。枚举中的第一个值是 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 时,第一个值被清零。如果我有一个 SIMPLE_COMMAND 的 command_type 和 -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}}

似乎 c 指向的结构在使用(command_t) c; 强制转换之前不会改变,我完全被这种行为弄糊涂了。我不认为投射指针会改变它指向的值。有人可以指出,哈哈,这里可能发生了什么?我会非常感激。

【问题讨论】:

    标签: c multithreading gnu


    【解决方案1】:

    更令人好奇的是何时会发生这种数据修改。我能够在 gdb 中捕捉到这种现象:

    这里的措辞让我相信问题不是确定性的;即,有时它不会发生,或者在您碰巧在问题中的gdb中捕获时它不会发生。

    如果是这种情况(甚至可能不是),我怀疑您的问题是您正在丢弃分配给主线程中 struct command 的内存(或任何创建 @987654322 的线程@ 线)。您没有向我们展示线程创建代码,但是如果您使用局部变量并将其地址传递给创建的线程,那么确保局部变量的生命周期不会在第二个线程之前到期可能会很棘手开始使用它。您可能希望传入已在堆上分配的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 内的各种指针所引用的数据也需要对其生命周期和所有权进行明确管理。

    【讨论】:

    • 是的 - 这大约每周发生一次,速率逐渐上升到“浮点比较不起作用”和“strcpy into char *myString 导致段错误”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-17
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    相关资源
    最近更新 更多