linux - C 程序在 fopen 时失败,附加堆栈跟踪

标签 linux gcc kernel malloc fopen

我们已经移植了一个应用程序以在内核为 4.10.1 的 Linux 上运行。该程序似乎在 __GI_abort() 调用时挂起,后来针对该进程发出了 SIGABRT,它再次未能写入错误日志文件。同样的程序在 Linux 内核 2.6 上运行。堆栈跟踪和代码已附上。任何建议都会有所帮助。谢谢。

我们之前使用 gcc 6.3.1 构建了 4.10.1 内核和应用程序 该应用程序已编译: gcc 版本 6.3.1 20161221 (Red Hat 6.3.1-1) (GCC)

堆栈跟踪:

(gdb) where
#0  __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
#1  0x00007f8f1c16ffb2 in __GI___libc_malloc (bytes=140252631706336, bytes@entry=552) at malloc.c:2923
#2  0x00007f8f1c15905d in __fopen_internal (filename=0x7ffeb54deac0 "/tmp/logs/app_exit.log", mode=0x497fc2 "a+", is32=1) at iofopen.c:69
#3  0x0000000000477690 in fep_sigbus_handler (signum=6, info=0x7ffeb54decb0, ptr=0x7ffeb54deb80) at app_util.c:559
#4  <signal handler called>
#5  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:58
#6  0x00007f8f1c12151a in __GI_abort () at abort.c:89
#7  0x00007f8f1c169d68 in __malloc_assert (
    assertion=assertion@entry=0x7f8f1c277f90 "(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)", file=file@entry=0x7f8f1c274807 "malloc.c", line=line@entry=2403,
    function=function@entry=0x7f8f1c2787d8 <__func__.11266> "sysmalloc") at malloc.c:301
#8  0x00007f8f1c16d5b6 in sysmalloc (nb=nb@entry=560, av=0x7f8f1c4aaae0 <main_arena>) at malloc.c:2400
#9  0x00007f8f1c16e63a in _int_malloc (av=av@entry=0x7f8f1c4aaae0 <main_arena>, bytes=bytes@entry=552) at malloc.c:3862
#10 0x00007f8f1c16ff14 in __GI___libc_malloc (bytes=bytes@entry=552) at malloc.c:2925
#11 0x00007f8f1c15905d in __fopen_internal (filename=0xf4cda4 <file_tbl+4> "/etc/app_config.dat", mode=0x48b735 "r", is32=1)
    at iofopen.c:69
#12 0x000000000042e96c in load_conversion_file (filename=0xf4cda4 <file_tbl+4> "/etc/app_config.dat") at app_config.c:1817
#13 0x000000000042ebc2 in load_all_conversion_files () at app_config.c:1864
#14 0x000000000042eeb9 in app_config_init () at app_config.c:1958
#15 0x0000000000403d9e in main (argc=1, argv=0x7ffeb54df6e8) at app_main.c:271

static int load_conversion_file( const char* filename )
{
    int     rc = FAILURE;
    FILE*   fd = NULL;
    int     parsedbg = (app_debug_mask & APP_DBG_PARSECONV) ? 1 : 0;
    AppCfg* pcfg;

    pcfg = (AppCfg*) malloc( sizeof(AppCfg) );

    if ( pcfg == NULL )
        LOG(APP_DBG_ERROR, BLANK_TID, ( "error allocating AppCfg\n" ));

    else if ( (fd = fopen( filename, "r" )) == NULL )
        LOG(APP_DBG_CONFIG, BLANK_TID, ( "error opening conversion file: %s\n",
                                              filename ) );

    else if ( app_parse_file( fd, pcfg, parsedbg ) != 0 )
        LOG(APP_DBG_CONFIG, BLANK_TID, ( "Parser error %s on line %d at token <%s>\n",
                                              app_parser_get_error_string(),
                                              app_parser_get_error_line(),
                                              app_parser_get_error_token() ) );
.
.
.
}

最佳答案

其中一个函数中有一个 calloc() 内存分配,并且该函数在 fopen() 之前被调用。该函数的代码填充了已调用的缓冲区,并且还经过了最后一个条目。修复后,问题就解决了。然而,以前版本的 linux 中的代码,即使用旧版本的 gcc 构建的,并没有在 malloc() 处断言和中止。

关于linux - C 程序在 fopen 时失败,附加堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44243628/

相关文章:

assembly - 使引导加载程序和内核成为iso?

linux - 如何使用 shell 脚本根据数字名称值删除目录?

c++ - 在 Linux 上编译外部库

linux - 无法在 gcc 中链接 libsqlite3.so

Cygwin:Windows 上的 Linux?如何确保在 Windows 中创建的程序适用于 Linux

c++ - 错误 : linker command failed with exit code 1 (use -v to see invocation) : on Macbook

gdb可以自动在SIGSEGV上附加一个进程吗

gcc - GNU C++ 错误消息

c++ - fstat() 在预加载的 mmap() 系统调用中无法按预期工作

linux - 如何在 Linux 中停止/禁用 IPI(进程间中断)?