segfault в g_slice_alloc

Я вызываю функцию со следующими строками:

void call_system_command(const char *command_params)
{
    GString *cmd = g_string_sized_new(1024);
    g_string_append_printf(cmd, "/bin/bash /path/to/my/script '%s'", command_params);
    system(cmd->str);
    g_string_free(cmd, TRUE);
}

Я получаю segfault в строке с g_string_sized_new. Backtrace от GDB показывает:

(gdb) bt
#0  0x000000320ce56264 in g_slice_alloc () from /lib64/libglib-2.0.so.0
#1  0x000000320ce5c3db in g_string_sized_new () from /lib64/libglib-2.0.so.0
....

Я попытался экспортировать G_SLICE=always-malloc, чтобы вместо собственного распределителя glib использовался malloc. Однако проблема остается той же. Я все еще получаю segfault в g_slice_alloc. Также я вызываю эту функцию 'call_system_command' из нескольких потоков. Может ли это быть проблемой?

Эта функция является частью плагина, который вызывается cron каждые 15 минут. Сегфоут происходит не каждый раз, когда плагин запускается, а один раз в 3-4 дня.

Любые указатели на дальнейшую отладку будут полезны.

Заранее спасибо.

3 ответа

Я нашел проблему. Написал следующую тестовую программу для выявления проблемы.

#include <stdio.h>
#include <glib.h>
#include <pthread.h>

#pragma GCC optimize("O0")

#define NUM 20
void* run(void *d)
{
    int i;
    for (i = 0; i < 1000000; i++) {
        GString *str = g_string_sized_new(1024);
        g_string_append_printf(str, "%s", "hello hello\n");
        fprintf(stdout, "%s", str->str);
        g_string_free(str, TRUE);
    }
    pthread_exit(NULL);
}

int main()
{
    pthread_t threads[NUM];
    int j;
    for (j = 0; j < NUM; j++) {
        pthread_create(&threads[j], NULL, run, (void*) NULL);
    }
    pthread_exit(NULL);

    return 0;
}

Следующий segfault происходит последовательно

Программа получила сигнал SIGSEGV, Ошибка сегментации. [Переключение на поток 0x7fffecdfa700 (LWP 11277)] 0x000000320ce56257 в g_slice_alloc () из /lib64/libglib-2.0.so.0 Отсутствует отдельный debuginfos, используйте: debuginfo-install glib2-2.22.5-6.el6.x86_64 glic 1.47.el6.x86_64 libgcc-4.4.6-3.el6.x86_64

Вы должны запустить свое приложение под Valgrind, чтобы помочь в этом, это похоже на повреждение кучи.

Вы упоминаете темы, которые, конечно, являются полезной информацией, поскольку могут облегчить возникновение проблем.

Документация glib гласит:

Сам GLib является внутренне полностью поточно-ориентированным (все глобальные данные автоматически блокируются), но отдельные экземпляры структуры данных не блокируются автоматически по соображениям производительности.

А поскольку API слайса не предоставляет никаких экземпляров структуры данных, его можно безопасно вызывать из нескольких потоков.

Где твое pthread_join заявление? Ваша основная функция на самом деле может завершиться до того, как вернутся многопоточные функции - это может привести к самому разрушению объектов потока. Насколько я знаю pthread_exit предполагается использовать только в порожденных потоках, а не в основной цепочке ( http://cs.gmu.edu/~white/CS571/Examples/pthread_examples.html, http://man7.org/linux/man-pages/man3/pthread_exit.3.html) Таким образом, ваша демонстрация (возможно) не является оптимальной и может включать ту же причину проблемы, что и ваша программа.

Вы пытались просто вручную malloc куча памяти того же размера и проверьте еще раз с помощью valgrind и gdb.

Другие вопросы по тегам