[llvm-bugs] [Bug 42030] New: lld doesn't generate DW_MACRO_import like ld.bfd does, leading to gdb cpu/memory hog

via llvm-bugs llvm-bugs at lists.llvm.org
Mon May 27 02:07:28 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=42030

            Bug ID: 42030
           Summary: lld doesn't generate DW_MACRO_import like ld.bfd does,
                    leading to gdb cpu/memory hog
           Product: lld
           Version: unspecified
          Hardware: PC
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: ELF
          Assignee: unassignedbugs at nondot.org
          Reporter: romain.geissler at amadeus.com
                CC: llvm-bugs at lists.llvm.org, peter.smith at linaro.org

Hi,

While transitioning from ld.bfd to ld.lld, I found that on big binaries gdb was
*VERY* slow to display backtraces (up to 30 minutes for the full stack) and
consumed tens and tens of GBs of memory.

I was able to reproduce this, and found that the issue comes from the
.debug_macro section of the final binary, if I remove it with objcopy then gdb
happily displays stacks almost instantly. When checking the difference between
ld.bfd and ld.lld (using "readelf --debug-dump=macro") I saw these kind of
differences:

--- macro.exe.bfd       2019-05-26 20:45:11.174723997 +0000
+++ macro.exe.lld       2019-05-26 20:45:16.882756121 +0000
@@ -3433,38 +3433,38 @@
  DW_MACRO_import - offset : 0x4abb
  DW_MACRO_start_file - lineno: 0 filenum: 1 filename: object.cpp
  DW_MACRO_start_file - lineno: 0 filenum: 55 filename:
/opt/1A/toolchain/x86_64-v19.0.20/include/stdc-predef.h
- DW_MACRO_import - offset : 0x13cc
+ DW_MACRO_import - offset : 0x0
  DW_MACRO_end_file
  DW_MACRO_start_file - lineno: 1 filenum: 56 filename:
/remote/tools/Linux/2.6/1A/toolchain/x86_64-v19.0.20/include/c++/9.1.1/string
  DW_MACRO_define_strp - lineno : 34 macro : _GLIBCXX_STRING 1
  DW_MACRO_start_file - lineno: 38 filenum: 4 filename:
/remote/tools/Linux/2.6/1A/toolchain/x86_64-v19.0.20/include/c++/9.1.1/x86_64-1a-linux-gnu/bits/c++config.h
- DW_MACRO_import - offset : 0x13e8
+ DW_MACRO_import - offset : 0x0
  DW_MACRO_start_file - lineno: 524 filenum: 57 filename:
/remote/tools/Linux/2.6/1A/toolchain/x86_64-v19.0.20/include/c++/9.1.1/x86_64-1a-linux-gnu/bits/os_defines.h
- DW_MACRO_import - offset : 0x1564
+ DW_MACRO_import - offset : 0x0
  DW_MACRO_start_file - lineno: 39 filenum: 58 filename:
/opt/1A/toolchain/x86_64-v19.0.20/include/features.h
- DW_MACRO_import - offset : 0x1574
+ DW_MACRO_import - offset : 0x0
  DW_MACRO_start_file - lineno: 450 filenum: 59 filename:
/opt/1A/toolchain/x86_64-v19.0.20/include/sys/cdefs.h

always around the value of DW_MACRO_import which is always 0 when using ld.lld,
and always non zero when using ld.bfd.

I have applied a warkaround in gdb to ignore DW_MACRO_import when the value is
0, and indeed it "fixes" our issue (bug maybe we loose some macro data).

Here is a full reproducer of my issue:

> cat main.cpp 
#include <iostream>

extern int f1();

int main()
{
    std::cout << f1() << std::endl;
}

> cat object.cpp
#include <string>
#include <memory>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <list>
#include <vector>
#include <unordered_map>

#define CONCAT_AUX(a,b) a##b
#define CONCAT(a,b) CONCAT_AUX(a,b)

extern int CONCAT(f,BUG_NEXT_ITERATION)();

int CONCAT(f,BUG_ITERATION)()
{   
    return CONCAT(f,BUG_NEXT_ITERATION)() + BUG_ITERATION;
}

#if BUG_ITERATION == BUG_LAST_ITERATION
int CONCAT(f,BUG_NEXT_ITERATION)()
{
    return 42;
}   
#endif

> cat Makefile
N=10000
OBJECT_FILES=$(shell echo object{1..${N}}.o)

all:exe.bfd exe.lld exe.lld.no-macro

exe.bfd exe.lld:${OBJECT_FILES} main.o
        g++ -fuse-ld=${LINKER} -o "$@" $^

exe.lld.no-macro:exe.lld
        objcopy --remove-section .debug_macro "$<" "$@"

exe.bfd:LINKER=bfd
exe.lld:LINKER=lld

main.o:main.cpp
        g++ -ggdb3 -O2 -c "$<" -o "$@"

${OBJECT_FILES}:object.cpp
        g++ -DBUG_ITERATION=$$(sed -e 's/[^[:digit:]]*//g'<<<"$@")
-DBUG_NEXT_ITERATION=$$(( $$(sed -e 's/[^[:digit:]]*//g'<<<"$@") + 1 ))
-DBUG_LAST_ITERATION=${N} -ggdb3 -O2 -c "$<" -o "$@"

clean:  
        ${RM} *.o exe.bfd exe.lld exe.lld.no-macro

.PHONY:all clean

Just type "make -j $CPU_COUNT" and wait for the 10000 object files to be
created. Then open "exe.lld" with gdb, add a breakpoint on "f10000", run the
program, and when the breakpoint is hit just display the backtrace: it will be
very slow. If you do the same with "exe.bfd", it will be done instantly.

Note: I am using gcc 9, if you don't use it then "-fuse-ld=lld" will not work.
I don't know if using clang exposes similar issues.

Cheers,
Romain

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190527/c544e233/attachment.html>


More information about the llvm-bugs mailing list