bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/17819] New: gold crashes when generating build-id for a large


From: guillaume at morinfr dot org
Subject: [Bug gold/17819] New: gold crashes when generating build-id for a large .so
Date: Thu, 08 Jan 2015 20:00:21 +0000

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>,
address@hidden, address@hidden) 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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]