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 の行で segfault が発生しています。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 が使用されます。ただし、問題は同じままです。g_slice_alloc でまだ segfault が発生しています。また、この関数「call_system_command」を複数のスレッドから呼び出しています。それは問題になるでしょうか?

この関数は、15 分ごとに cron によって呼び出されるプラグインの一部です。segfault は、プラグインが実行されるたびに発生するのではなく、3 ~ 4 日ごとに発生します。

さらにデバッグするための指針は役に立ちます。

前もって感謝します。

4

3 に答える 3

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) に切り替えます] /lib64/libglib-2.0.so.0 からの g_slice_alloc () の 0x000000320ce56257 1.47.el6.x86_64 libgcc-4.4.6-3.el6.x86_64

于 2013-02-25T10:36:08.097 に答える
0

これを追跡するには、Valgrind でアプリケーションを実行する必要があります。ヒープが破損しているように聞こえます。

あなたはスレッドについて言及しましたが、これはトラブルに巻き込まれやすくなるため、もちろん良い情報です。

glib のドキュメントには次のように記載されています。

GLib 自体は内部的に完全にスレッドセーフです (すべてのグローバル データは自動的にロックされます) が、個々のデータ構造インスタンスはパフォーマンス上の理由から自動的にロックされません。

また、スライス API はデータ構造のインスタンスを公開しないため、複数のスレッドから安全に呼び出すことができます。

于 2013-02-25T09:14:19.773 に答える
0

pthread_joinあなたの声明はどこにありますか?スレッド化された関数が戻る前にメイン関数が実際に終了する可能性があります。これにより、スレッドオブジェクト自体が破壊される可能性があります。私の知る限り、メインスレッド内ではなく、生成されたスレッド内でのみ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 で再度確認しようとしましたか。

于 2013-03-05T22:13:39.373 に答える