https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081

            Bug ID: 81081
           Summary: [ASAN] ASAN is not properly calling libbacktrace to
                    symbolize program written on assembler
           Product: gcc
           Version: 7.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: d.khalikov at partner dot samsung.com
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

Hello everyone,
I've faced a situation with ASan and program which were written on assembler
with debug info generated by "as".

In this case asan can't properly render symbolic info for that kind of program.

Steps to reproduce:

1.For test purpose we can generate assembler code by gcc from c code.

$cat test.c
int main() {
 int ptr = 0x01;
 int value = *(int *) ptr;
 return 0;
}

/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/cc1 -quiet -v -imultiarch
x86_64-linux-gnu test.c -quiet -dumpbase test.c -mtune=generic -march=x86-64
-auxbase test -version -o test.S

2. Assemble the code and generate debug info. 
as -v --64 -o test.o test.S -gdwarf-2

3.Link the program.

/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/collect2 -plugin
/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/liblto_plugin.so
-plugin-opt=/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/lto-wrapper
-plugin-opt=-fresolution=/tmp/ccuSSiyf.res -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s
--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o
test /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o
/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/crtbegin.o
-L/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1
-L/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/../../../../lib64
-L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu
-L/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/../../.. test.o -lgcc
--as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/crtend.o
/usr/lib/x86_64-linux-gnu/crtn.o

4.Set LD_PRELOAD to look for segfault.

$export LD_PRELOAD=/lib64/libasan.so
$./test

#0 0x4004dd in main (test+0x4004dd)

As we can see symbolizer does not render the line number and filename, but
.debug_info section inside the file.

Looks like this happens because "as" can not generate dwarf tag
(DW_TAG_subprogram)
which consist address and name of the function.

In this case libbacktrace can't find function for specific address and call
callback with last param == NULL, which represents the name of the function:

return callback (data, pc, ln->filename, ln->lineno, NULL);

but filename and line number have a valid data.

The callback for backtrace_pcinfo check function and in case value is  NULL
assumes that other data is not valid.

111   if (function) {
112     AddressInfo *info = cdata->get_new_frame(addr);
113     info->function = DemangleAlloc(function, /*always_alloc*/ true);
114     if (filename)
115       info->file = internal_strdup(filename);
116     info->line = lineno;
117     cdata->frames_symbolized++;
118   }
119   return 0;

LibbacktraceSymbolizer::SymbolizePC function
skips execution to backtrace_syminfo and this function can symbolize address by
data from symbol table in elf file without debuginfo section.

So, should the callback be like this:  

111   AddressInfo *info = cdata->get_new_frame(addr);
112   if (filename)
113     info->file = internal_strdup(filename);
114   info->line = lineno;
115   if (function) {
116     info->function = DemangleAlloc(function, /*always_alloc*/ true);
117     cdata->frames_symbolized++;
118   }
119   return 0;
120 }

Thanks.

Reply via email to