gcc - calloc 崩溃

标签 gcc crash openmp calloc

我正在尝试调试我编写的程序。我在里面运行它gdb我成功地捕获了SIGABRT从里面calloc() 。我完全不明白这是怎么发生的。这可能是 gcc 中的错误吗?甚至 libc ??

更多详细信息:我的程序使用 OpenMP。我运行了valgrind在单线程模式下没有错误。我也用mmap()加载 40GB 文件,但我怀疑这是否相关。里面gdb ,我正在运行 30 个线程。几次相同的运行(相同的输入和 CL)正确完成,直到我发现有问题的运行。从表面上看,这表明可能存在某种类型的竞争条件。然而,SIGABRT来自calloc()这是我无法控制的。这是一些相关的gdb输出:

(gdb) info threads
[...]
  17 Thread 0x7fffec450700 (LWP 73455)  0x00007ffff6b3ce00 in __read_nocancel () from /lib64/libc.so.6
  16 Thread 0x7fffece51700 (LWP 73454)  _mm_slli_si128 (genome=<value optimized out>, goff=<value optimized out>, glen=50, read=<value optimized out>, rlen=36, genome_ls=<value optimized out>, initbp=-1, is_rna=false) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/emmintrin.h:1155
  14 Thread 0x7fffee253700 (LWP 73452)  0x000000000041183e in _mm_prefetch (re=0x7fff291c0f10, st=1, options=0x632014) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/xmmintrin.h:1193
  13 Thread 0x7fffeec54700 (LWP 73451)  0x00007ffff6ae5c84 in __memset_sse2 () from /lib64/libc.so.6
  12 Thread 0x7fffef655700 (LWP 73450)  _mm_cmpeq_epi16 (genome=<value optimized out>, goff=<value optimized out>, glen=33, read=<value optimized out>, rlen=24, genome_ls=<value optimized out>, initbp=-1, is_rna=false) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/emmintrin.h:1263
* 11 Thread 0x7ffff0056700 (LWP 73449)  0x00007ffff6a948a5 in raise () from /lib64/libc.so.6
  10 Thread 0x7ffff0a57700 (LWP 73448)  _mm_sub_epi16 (genome=<value optimized out>, goff=<value optimized out>, glen=36, read=<value optimized out>, rlen=26, genome_ls=<value optimized out>, initbp=-1, is_rna=false) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/emmintrin.h:1046
  5 Thread 0x7ffff3c5c700 (LWP 73443)  0x000000000041183e in _mm_prefetch (re=0x7fff28615010, st=1, options=0x632014) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/xmmintrin.h:1193
  2 Thread 0x7ffff5a5f700 (LWP 73440)  0x000000000041e4cd in _mm_max_epi16 (genome=<value optimized out>, goff=<value optimized out>, glen=29, read=<value optimized out>, rlen=21, genome_ls=<value optimized out>, initbp=-1, is_rna=false) at /usr/lib/gcc/x86_64-redhat-linux/4.4.6/include/emmintrin.h:1331
  1 Thread 0x7ffff7fdcae0 (LWP 73437)  0x00007ffff6ae5cff in __memset_sse2 () from /lib64/libc.so.6
[...]
(gdb) thread 11
[Switching to thread 11 (Thread 0x7ffff0056700 (LWP 73449))]#0  0x00007ffff6a948a5 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff6a948a5 in raise () from /lib64/libc.so.6
#1  0x00007ffff6a96085 in abort () from /lib64/libc.so.6
#2  0x00007ffff6ad1fe7 in __libc_message () from /lib64/libc.so.6
#3  0x00007ffff6ad7916 in malloc_printerr () from /lib64/libc.so.6
#4  0x00007ffff6adb79f in _int_malloc () from /lib64/libc.so.6
#5  0x00007ffff6adbdd6 in calloc () from /lib64/libc.so.6
#6  0x000000000040e87f in my_calloc (re=0x7fff2867ef10, st=0, options=0x632020) at gmapper/../gmapper/../common/my-alloc.h:286
#7  read_get_hit_list_per_strand (re=0x7fff2867ef10, st=0, options=0x632020) at gmapper/mapping.c:1046
#8  0x000000000041308a in read_get_hit_list (re=<value optimized out>, options=0x632010, n_options=1) at gmapper/mapping.c:1239
#9  handle_read (re=<value optimized out>, options=0x632010, n_options=1) at gmapper/mapping.c:1806
#10 0x0000000000404f35 in launch_scan_threads (.omp_data_i=<value optimized out>) at gmapper/gmapper.c:557
#11 0x00007ffff7230502 in ?? () from /usr/lib64/libgomp.so.1
#12 0x00007ffff6dfc851 in start_thread () from /lib64/libpthread.so.0
#13 0x00007ffff6b4a11d in clone () from /lib64/libc.so.6
(gdb) f 6   
#6  0x000000000040e87f in my_calloc (re=0x7fff2867ef10, st=0, options=0x632020) at gmapper/../gmapper/../common/my-alloc.h:286
286         res = calloc(size, 1);
(gdb) p size
$2 = 814080
(gdb) 

函数my_calloc()只是一个包装器,但问题并不在那里,因为真正的 calloc()电话看起来合法。这些是在 shell 中设置的限制:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 2067285
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

该程序没有内存不足,它在有 256GB 可用内存的机器上使用了 41GB:

$ top -b -n 1 | grep gmapper
 73437 user      20   0 41.5g  16g  15g T  0.0  6.6  55:17.24 gmapper-ls
$ free -m
             total       used       free     shared    buffers     cached
Mem:        258437     195567      62869          0         82     189677
-/+ buffers/cache:       5807     252629
Swap:            0          0          0

我使用 g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4) 进行编译,带有标志-g -O2 -DNDEBUG -mmmx -msse -msse2 -fopenmp -Wall -Wno-deprecated -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS .

编辑:我收到的详细错误消息如下。我截断了它,未显示的行与最后 5 行类似。

*** glibc detected *** /tmp/t/gmapper-ls: corrupted double-linked list: 0x0000000009447380 ***
*** glibc detected *** /tmp/t/gmapper-ls: corrupted double-linked list: 0x0000000009447380 ***
======= Backtrace: =========
======= Backtrace: =========
/lib64/libc.so.6(+0x75916)[0x7ffff6ad7916]
/lib64/libc.so.6(+0x75916)[0x7ffff6ad7916]
/lib64/libc.so.6(+0x7979f)[0x7ffff6adb79f]
/lib64/libc.so.6(+0x7979f)[0x7ffff6adb79f]
/lib64/libc.so.6(__libc_malloc+0x71)[0x7ffff6adc141]
/lib64/libc.so.6(__libc_calloc+0xc6)[0x7ffff6adbdd6]
/usr/lib64/libgomp.so.1(+0x8502)[0x7ffff7230502]
/usr/lib64/libgomp.so.1(+0x8502)[0x7ffff7230502]
/lib64/libc.so.6(clone+0x6d)[0x7ffff6b4a11d]
/lib64/libpthread.so.0(+0x7851)[0x7ffff6dfc851]
/lib64/libc.so.6(clone+0x6d)[0x7ffff6b4a11d]
======= Memory map: ========
00400000-00430000 r-xp 00000000 00:14 927268870                          /tmp/t/gmapper
00630000-00631000 rw-p 00030000 00:14 927268870                          /tmp/t/gmapper
00631000-2f461000 rw-p 00000000 00:00 0                                  [heap]
7f749d9be000-7f7e2053b000 r--p 00000000 00:0f 1278724                    /dev/shm/hg19-ls
7fff24000000-7fff2727a000 rw-p 00000000 00:00 0
7fff2727a000-7fff28000000 ---p 00000000 00:00 0
7fff285ce000-7fff2c000000 rw-p 00000000 00:00 0
7fff2c000000-7fff2f547000 rw-p 00000000 00:00 0
7fff2f547000-7fff30000000 ---p 00000000 00:00 0
[...]

Edit2:我添加了所有在看似“不平凡”的地方停止的线程的线程信息(10/30)。

最佳答案

请注意,您的 GCC 版本相当旧。当前的 GCC 是 4.7.2

出于调试目的,您可以使用较少的优化进行编译:不使用 -g -O2 -NDEBUG -mmmx -msse -msse2 -fopenmp -Wall 只需使用 -g -Wall.

使用较少的优化进行编译使 gdb 调试器更加满意

然后,使用 valgrindgdb 来调试您的程序。

关于gcc - calloc 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13102209/

相关文章:

c++ - OpenMP 函数并行调用

c - 如何将可执行入口点的名称从 main 更改为其他名称?

对指针的更改不是永久性的

c 未知段错误(核心已转储)

c++ - 如何使用 PatchELF 或 chrpath 替换库共享对象

android - 我的应用程序在尝试禁用主页按钮时崩溃

objective-c - 为什么这个简单的 NSWindow 创建代码会在 ARC 下关机时触发自动释放池崩溃?

android 系统尝试绘制大尺寸位图(崩溃报告)

c++ - 多线程强调内存碎片吗?

c++ - 初始化变量以减少 OMP