2015-06-23 6 views
0

Я получаю ошибку сегментации на CentOS 7 64-бит, сборки Release (нет никакой проблемы в отладочных)c linux - memset raise Сегментация Ошибка в выпуске сборки, printf как-то может «исправить» ее?

Я попытался добавления Printf, чтобы определить, где именно выдаёт ошибку сегментации происходит, ниже код, выдаёт ошибку сегментации повышается при: memset(len_p, 0, sizeof(*len_p));

Кроме того, если я добавлю printf для печати что-то прямо перед memeset, нет segfault, как будто printf здесь делает какую-то магию.

Пожалуйста, помогите мне разобраться с этой проблемой.

core dump закачано

Спасибо большое!

фрагмент кода (MySQL подготовленное заявление для запроса что-то):

(эта функция была вызвана несколько раз, это не всегда поднимают Segfault)

int mysql_odb_read(void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid) 
{ 
    MYSQL_BIND bind_buffers[2]; 
    MYSQL_BIND result_buffers[3]; 

    memset(bind_buffers, 0, sizeof(bind_buffers)); 

    // bind the repo passed to the statement 
    bind_buffers[0].buffer = &(backend->mysql->repo); 
    bind_buffers[0].buffer_length = sizeof(backend->mysql->repo); 
    bind_buffers[0].length = &bind_buffers[0].buffer_length; 
    bind_buffers[0].buffer_type = MYSQL_TYPE_LONGLONG; 

    // bind the oid passed to the statement 
    bind_buffers[1].buffer = (void*)oid->id; 
    bind_buffers[1].buffer_length = 20; 
    bind_buffers[1].length = &bind_buffers[1].buffer_length; 
    bind_buffers[1].buffer_type = MYSQL_TYPE_BLOB; 

    if (mysql_stmt_bind_param(backend->mysql->odb_read, bind_buffers) != 0) 
     return GIT_ERROR; 

    // execute the statement 
    if (mysql_stmt_execute(backend->mysql->odb_read) != 0) 
     return GIT_ERROR; 

    if (mysql_stmt_store_result(backend->mysql->odb_read) != 0) 
     return GIT_ERROR; 

    if (mysql_stmt_num_rows(backend->mysql->odb_read) == 1) { 

    memset(result_buffers, 0, sizeof(result_buffers)); 

    result_buffers[0].buffer_type = MYSQL_TYPE_TINY; 
    result_buffers[0].buffer = type_p; 
    result_buffers[0].buffer_length = sizeof(*type_p); 
    result_buffers[0].is_null = 0; 
    result_buffers[0].length = &result_buffers[0].buffer_length; 
    memset(type_p, 0, sizeof(*type_p)); 

    result_buffers[1].buffer_type = MYSQL_TYPE_LONG; 
    result_buffers[1].buffer = len_p; 
    result_buffers[1].buffer_length = sizeof(*len_p); 
    result_buffers[1].is_null = 0; 
    result_buffers[1].length = &result_buffers[1].buffer_length; 
    printf("len_p:%lu\n",*len_p);//if i remove this printf call, there will be segfault 
    memset(len_p, 0, sizeof(*len_p)); 

    result_buffers[2].buffer_type = MYSQL_TYPE_LONG_BLOB; 
    result_buffers[2].buffer = *data_p; 
    result_buffers[2].is_null = 0; 
    result_buffers[2].buffer_length = data_len; 
    result_buffers[2].length = &data_len; 
    //memset(&data_len, 0, sizeof(data_len)); 

    if (mysql_stmt_bind_result(backend->mysql->odb_read, result_buffers) != 0) 
     return GIT_ERROR; 

    error = mysql_stmt_fetch(backend->mysql->odb_read); 

    if (data_len > 0) { 
     *data_p = malloc(data_len); 
     if(*data_p){ 
    result_buffers[2].buffer_type = MYSQL_TYPE_LONG_BLOB; 
     result_buffers[2].buffer = *data_p; 
    result_buffers[2].is_null = 0; 
     result_buffers[2].buffer_length = data_len; 
    result_buffers[2].length = &data_len; 
     if (mysql_stmt_fetch_column(backend->mysql->odb_read, &result_buffers[2], 2, 0) != 0) 
      return GIT_ERROR; 
     } 
     else{ 
     printf("odb_read, malloc returned NULL\n"); 
     return GITERR_NOMEMORY; 
     } 
    } 

    error = GIT_OK; 
    } else 
    error = GIT_ENOTFOUND; 

    // free result 
    if (mysql_stmt_free_result(backend->mysql->odb_read) != 0) 
     return GIT_ERROR; 

    mysql_free_result(meta_result); 

    // reset the statement for further use 
    if (mysql_stmt_reset(backend->mysql->odb_read) != 0) 
     return GIT_ERROR; 

    return error; 
} 
+0

'printf' не делает никакой магии :) .... Задержка, введенная printf(), помогает для правильного вывода. – Jeyaram

ответ

1

Трудно сказать точную проблему без дампов или другой информации, но возможное объяснение может заключаться в том, что len_p является висящим указателем.

Это вызывает Segfault, однако, позвонив по телефону printf, вы, вероятно, заполняя область стека, где len_p указывает, с printf данных, следовательно, переназначение указатель с новым значением, избегая ошибки сегментации.

+0

спасибо, @jndok! Я буду исследовать больше и обновить – jerry

+0

Привет, @jndok, я загрузил [core dump] (https://github.com/JerryYangJin/CoreDump/raw/master/core.4814), сообщите мне, хотите ли вы весь исходный код, спасибо! – jerry

+0

Привет, @jndok, я использовал [gdb backtrace] (https://gist.github.com/JerryYangJin/264ffd8a14cd0b6f0307) на одном из дампов ядра, не уверен, что это поможет – jerry