我在Debian Etch上运行:Linux nereus 2.6.18-6-686#1 SMP Sat Dec 27 09:31:05 UTC 2008 i686 GNU/Linux
我有一个多线程的c应用程序,其中一个线程挂起。有时候。通过核心文件,我发现它挂在一个fopen()上:

#0  0xb7f4b410 in ?? ()
#1  0xb660521c in ?? ()
#2  0x000001b6 in ?? ()
#3  0x00008241 in ?? ()
#4  0xb77c45bb in open () from /lib/tls/i686/cmov/libc.so.6
#5  0xb7768142 in _IO_file_open () from /lib/tls/i686/cmov/libc.so.6
#6  0xb77682e8 in _IO_file_fopen () from /lib/tls/i686/cmov/libc.so.6
#7  0xb775d8c9 in fgets () from /lib/tls/i686/cmov/libc.so.6
#8  0xb775fe0a in fopen64 () from /lib/tls/i686/cmov/libc.so.6
#9  0x0805600f in comric_write_external_track_file (control=0xbfc9c284) at ../COMRIC/comric_thread.c:784
#10 0x08055b0e in store_tracks (control=0xbfc9c284, hdr=0xb3d1b828) at ../COMRIC/comric_thread.c:695
#11 0x080568be in comric_thread (userdata=0xbfc9c284) at ../COMRIC/comric_thread.c:997
#12 0xb789530f in g_thread_create_full () from /usr/lib/libglib-2.0.so.0
#13 0xb783f240 in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#14 0xb77d349e in clone () from /lib/tls/i686/cmov/libc.so.6

此线程从外部源获取数据,对其进行处理,并将其写入文本文件。当我们得到新的数据时,文本文件被一遍又一遍地写。没有其他人正在访问此文件。文件大小通常小于1KB。我正在检查fclose()调用,以确保它返回success,并且返回成功。
当主线程检测到30秒以上没有收到问题线程的消息时,它会调用abort(),这样我们就可以得到上面看到的核心转储。
99%的时间,一切都很顺利。但在过去的四天里,这种情况越来越多(每天6次以上)。我担心这可能是一个硬盘问题,但我找不到任何日志中报告的任何错误。(不幸的是,智能信息不可用。)此应用程序已平稳运行2年。
有人有什么想法吗?
源代码:
int comric_write_external_track_file( struct ComricControl *control ) {
    FILE *file;

    if( strlen( control->extern_track_file ) == 0 ) return 1;

    file = fopen( control->extern_track_file, "w" );
    if( !file ) {
        ps_slog( "ERROR opening external track file: \"%s\"", control->extern_track_file );
        return 0;
    }

    // Write the file
    G_MUTEX_LOCK( control->mutex );
        g_hash_table_foreach( control->tracks, comric_write_track, file );
    G_MUTEX_UNLOCK( control->mutex );

    fsync( fileno( file ));
    if( fclose( file ) != 0 ) {
        ps_slog( "FATAL ERROR - fclose() FAILED with error \"%s\" (%d)", strerror( errno ), errno );
        sleep( 1 ); abort();  // can we get any debug info out of this?
    }

    return 1;
}

我在网上打猎之后添加了fsync()调用。起初,我认为这可能与fclose()失败有关,但事实似乎并非如此。

最佳答案

你挂在open()-所以这可能是内核或驱动程序级别的问题。
首先,检查dmesg是否有明显的错误消息。如果失败,您可以尝试使用SysRq w命令获取违规进程的stacktrace。

关于c - fopen()挂起。有时,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7611131/

10-13 05:23