【问题标题】:segfault in g_slice_allocg_slice_alloc 中的段错误
【发布时间】:2013-03-06 06:13:39
【问题描述】:

我正在调用具有以下行的函数:

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 天发生一次。

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

提前致谢。

【问题讨论】:

  • 请向我们展示一个最小的、可编译的测试用例。 “最小”是指“仅使用重现此问题所需的基本要素”,“可编译”是指“能够在我们的系统上编译和调试,而无需填写空白或修复基本语法错误”。

标签: c segmentation-fault glib gstring


【解决方案1】:

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

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

glib 文档指出:

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

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

【讨论】:

  • 在 valgrind 中运行插件会使其太慢。需要几个小时才能完成。我尝试通过测试程序在 valgrind 中运行该函数,但无法重现段错误。
  • ...valgrind 告诉你什么?有没有提到任何问题?如果不是,那你就误诊了,你需要开阔眼界,因为错误出在别处。
【解决方案2】:

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

#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)] /lib64/libglib-2.0.so.0 中的 g_slice_alloc () 中的 0x000000320ce56257 缺少单独的调试信息,使用: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

【讨论】:

    【解决方案3】:

    您的pthread_join 声明在哪里?您的 main 函数实际上可以在您的线程函数返回之前完成 - 这可能会破坏线程对象本身。据我所知,pthread_exit 应该在衍生线程中使用,而不是在主线程中使用(http://cs.gmu.edu/~white/CS571/Examples/pthread_examples.htmlhttp://man7.org/linux/man-pages/man3/pthread_exit.3.html) 因此,您的演示(可能)不是最佳的,并且可能包含与您的程序相同的问题原因。

    您是否尝试手动malloc 一个相同大小的内存,然后使用 valgrind 和 gdb 再次检查。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 2018-11-18
      • 2023-04-04
      • 2016-06-25
      • 2021-12-31
      相关资源
      最近更新 更多