1

我正在使用以下几行调用一个函数:

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);
}

我在 g_string_sized_new 的行中遇到了段错误。来自 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,以便使用 malloc 代替 glib 自己的分配器。但是问题仍然相同。我仍然在 g_slice_alloc 中遇到段错误。我也从多个线程调用这个函数'call_system_command'。这会是个问题吗?

该函数是 cron 每 15 分钟调用一次的插件的一部分。段错误不是每次执行插件时都会发生,而是每 3-4 天发生一次。

有关进一步调试的任何指示都会有所帮助。

提前致谢。

4

3 回答 3

0

你的pthread_join陈述在哪里?您的 main 函数实际上可以在您的线程函数返回之前完成 - 这可能会破坏线程对象本身。据我所知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 再次检查。

于 2013-03-05T22:13:39.373 回答
0

我发现了问题。编写了以下测试程序来确定问题。

#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;
}

以下段错误始终发生

程序收到信号 SIGSEGV,分段错误。[切换到线程 0x7fffecdfa700 (LWP 11277)] 0x000000320ce56257 in g_slice_alloc () from /lib64/libglib-2.0.so.0 缺少单独的调试信息,使用:debuginfo-install glib2-2.22.5-6.el6.x86_64 glibc-2.12- 1.47.el6.x86_64 libgcc-4.4.6-3.el6.x86_64

于 2013-02-25T10:36:08.097 回答
0

你应该在 Valgrind 下运行你的应用程序来帮助解决这个问题,这听起来像是堆损坏。

您提到线程,这当然是很好的信息,因为它可以更容易最终陷入困境。

glib 文档指出:

GLib 本身在内部是完全线程安全的(所有全局数据都被自动锁定),但出于性能原因,个别数据结构实例不会自动锁定。

而且由于 slice API 不公开任何数据结构实例,因此从多个线程调用应该是安全的。

于 2013-02-25T09:14:19.773 回答