https://sourceware.org/bugzilla/show_bug.cgi?id=17819
Bug ID: 17819 Summary: gold crashes when generating build-id for a large .so Product: binutils Version: 2.24 Status: NEW Severity: normal Priority: P2 Component: gold Assignee: ccoutant at google dot com Reporter: guillaume at morinfr dot org CC: ian at airs dot com Tested against Debian 2.24 binutils. But it seems the bug is still tehre in 2.25 and 2.26 This happens when I generate a large so file with ld.gold and passing --build-id. This does not seem to happen with wheezy but I did not investigate too much. The sequence of event is pretty simple. gold creates a md5 task for its workqueue by binding a pointer to mmap'ed address of the output file. Unfortunately, the file is resized and re-mmaped to a different address later so when the hash_task is run, the src pointer pointing to unmapped memory and generating a crash. This is a full gdb session showing the crash: The OutputFile object is opened with a size of 46793152: Breakpoint 3, gold::Output_file::open (this=0xd31bed0, file_size=46793152) at ../../gold/output.cc:5001 (gdb) print * this $3 = {name_ = 0x7fffffffde6a "/usr/scratch/tmp/a.out", o_ = -1, file_size_ = 0, base_ = 0x0, map_is_anonymous_ = false, map_is_allocated_ = false, is_temporary_ = false} (gdb) bt #0 gold::Output_file::open (this=0xd31bed0, file_size=46793152) at ../../gold/output.cc:5001 #1 0x00000000004be203 in gold::Layout_task_runner::run (this=0xab83ec0, workqueue=0x7fffffff6fe0, task=0xab83fc0) at ../../gold/layout.cc:395 #2 0x000000000048ada1 in gold::Task_function::run (this=0xab83fc0, workqueue=0x7fffffff6fe0) at ../../gold/workqueue.h:178 #3 0x00000000005d6242 in gold::Workqueue::find_and_run_task (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:319 #4 0x00000000005d688c in gold::Workqueue::process (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:495 #5 0x0000000000404a00 in main (argc=136, argv=0x7fffffffd6b8) at ../../gold/main.cc:252 And mapped right after: Breakpoint 4, gold::Output_file::map (this=0xd31bed0) at ../../gold/output.cc:5168 (gdb) bt #0 gold::Output_file::map (this=0xd31bed0) at ../../gold/output.cc:5168 #1 0x000000000052205c in gold::Output_file::open (this=0xd31bed0, file_size=46793152) at ../../gold/output.cc:5050 #2 0x00000000004be203 in gold::Layout_task_runner::run (this=0xab83ec0, workqueue=0x7fffffff6fe0, task=0xab83fc0) at ../../gold/layout.cc:395 #3 0x000000000048ada1 in gold::Task_function::run (this=0xab83fc0, workqueue=0x7fffffff6fe0) at ../../gold/workqueue.h:178 #4 0x00000000005d6242 in gold::Workqueue::find_and_run_task (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:319 #5 0x00000000005d688c in gold::Workqueue::process (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:495 #6 0x0000000000404a00 in main (argc=136, argv=0x7fffffffd6b8) at ../../gold/main.cc:252 (gdb) p file_size_ $4 = 46793152 (gdb) p base_ $5 = (unsigned char *) 0x0 (gdb) fin Run till exit from #0 gold::Output_file::map (this=0xd31bed0) at ../../gold/output.cc:5168 0x000000000052205c in gold::Output_file::open (this=0xd31bed0, file_size=46793152) at ../../gold/output.cc:5050 5050 in ../../gold/output.cc (gdb) p base_ $6 = (unsigned char *) 0x7fff6a983000 "" (gdb) A bit later, the workqueue item for md5'ing this file is built: Breakpoint 1, gold::Layout::queue_build_id_tasks (this=0x7fffffff7590, workqueue=0x7fffffff6fe0, build_id_blocker=0xd286490, of=0xd31bed0) at ../../gold/layout.cc:5384 (gdb) bt #0 gold::Layout::queue_build_id_tasks (this=0x7fffffff7590, workqueue=0x7fffffff6fe0, build_id_blocker=0xd286490, of=0xd31bed0) at ../../gold/layout.cc:5384 #1 0x000000000048a7af in gold::queue_final_tasks (options=..., input_objects=0x7fffffff7100, symtab=0x7fffffff7330, layout=0x7fffffff7590, workqueue=0x7fffffff6fe0, of=0xd31bed0) at ../../gold/gold.cc:880 #2 0x00000000004be2a6 in gold::Layout_task_runner::run (this=0xab83ec0, workqueue=0x7fffffff6fe0, task=0xab83fc0) at ../../gold/layout.cc:416 #3 0x000000000048ada1 in gold::Task_function::run (this=0xab83fc0, workqueue=0x7fffffff6fe0) at ../../gold/workqueue.h:178 #4 0x00000000005d6242 in gold::Workqueue::find_and_run_task (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:319 #5 0x00000000005d688c in gold::Workqueue::process (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:495 #6 0x0000000000404a00 in main (argc=136, argv=0x7fffffffd6b8) at ../../gold/main.cc:252 (gdb) print *of $8 = {name_ = 0x7fffffffde6a "/usr/scratch/tmp/a.out", o_ = 660, file_size_ = 46793152, base_ = 0x7fff6a983000 "", map_is_anonymous_ = false, map_is_allocated_ = false, is_temporary_ = false} (gdb) print src $9 = (const unsigned char *) 0x7fff6a983000 "" (gdb) print src_offset $10 = 0 So far so good it seems, but the problem is the file is resized after that: Breakpoint 5, gold::Output_file::resize (this=0xd31bed0, file_size=241002406) at ../../gold/output.cc:5061 (gdb) bt #0 gold::Output_file::resize (this=0xd31bed0, file_size=241002406) at ../../gold/output.cc:5061 #1 0x00000000004c95f8 in gold::Layout::write_sections_after_input_sections (this=0x7fffffff7590, of=0xd31bed0) at ../../gold/layout.cc:5336 #2 0x00000000004ca35b in gold::Write_after_input_sections_task::run (this=0xd2864c0) at ../../gold/layout.cc:5629 #3 0x00000000005d6242 in gold::Workqueue::find_and_run_task (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:319 #4 0x00000000005d688c in gold::Workqueue::process (this=0x7fffffff6fe0, thread_number=0) at ../../gold/workqueue.cc:495 #5 0x0000000000404a00 in main (argc=136, argv=0x7fffffffd6b8) at ../../gold/main.cc:252 (gdb) print file_size_ $11 = 46793152 (gdb) fin Run till exit from #0 gold::Output_file::resize (this=0xd31bed0, file_size=241002406) at ../../gold/output.cc:5086 gold::Layout::write_sections_after_input_sections (this=0x7fffffff7590, of=0xd31bed0) at ../../gold/layout.cc:5337 (gdb) print of->file_size_ $12 = 241002406 (gdb) print of->base_ $13 = (unsigned char *) 0x7fff23e91000 "\177ELF\002\001\001" But at that point, the old address is still attached to the work queue, triggering a crash when trying to run the md5 task: Program received signal SIGSEGV, Segmentation fault. 0x000000000063d250 in md5_process_block (buffer=<optimized out>, len=len@entry=2097152, ctx=ctx@entry=0x7fffffff6ca0) at ../../libiberty/md5.c:336 (gdb) x /i $rip => 0x63d250 <md5_process_block+128>: mov 0x0(%rbp),%r11d (gdb) p $rbp $14 = (void *) 0x7fff6a983000 (gdb) This can be worked around by using other --build-id options -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils