Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segfault on kernel debug info #10

Open
vries opened this issue Sep 3, 2020 · 20 comments
Open

Segfault on kernel debug info #10

vries opened this issue Sep 3, 2020 · 20 comments

Comments

@vries
Copy link

vries commented Sep 3, 2020

$ ./build/pahole -C  mem_cgroup ~/vmlinux-5.3.18-107.g1c7b2b9-default.debug
tag__recode_dwarf_type: couldn't find 0x734b27 type for 0x3e (pointer_type)!
tag__recode_dwarf_type: couldn't find 0x22 type for 0x75 (array_type)!
  ...
tag__recode_dwarf_type: couldn't find 0x181e5 type for 0x452c8 (formal_parameter)!
tag__recode_dwarf_type: couldn't find 0x734b75 type for 0x452cd (formal_parameter)!
Segmentation fault (core dumped)
@vries
Copy link
Author

vries commented Sep 3, 2020

@vries
Copy link
Author

vries commented Sep 3, 2020

We segfault because tag is NULL:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f65d92 in tag__is_pointer (tag=0x0) at /home/vries/dwarves/src/dwarves.h:446
446             return tag->tag == DW_TAG_pointer_type;

Backtrace:

(gdb) bt
#0  0x00007ffff7f65d92 in tag__is_pointer (tag=0x0) at /home/vries/dwarves/src/dwarves.h:446
#1  0x00007ffff7f69914 in tag__natural_alignment (tag=0x0, cu=0xcd6520) at /home/vries/dwarves/src/dwarves.c:1428
#2  0x00007ffff7f69ad4 in type__natural_alignment (type=0x15867f0, cu=0xcd6520) at /home/vries/dwarves/src/dwarves.c:1469
#3  0x00007ffff7f699c0 in tag__natural_alignment (tag=0x15867f0, cu=0xcd6520) at /home/vries/dwarves/src/dwarves.c:1435
#4  0x00007ffff7f69bc1 in type__check_structs_at_unnatural_alignments (type=0x15263f0, cu=0xcd6520) at /home/vries/dwarves/src/dwarves.c:1494
#5  0x00007ffff7f69cd4 in class__infer_packed_attributes (cls=0x15263f0, cu=0xcd6520) at /home/vries/dwarves/src/dwarves.c:1521
#6  0x00007ffff7f70521 in __class__fprintf (class=0x15263f0, cu=0xcd6520, conf=0x7fffffffb610, fp=0x7ffff7e5e500 <_IO_2_1_stdout_>)
    at /home/vries/dwarves/src/dwarves_fprintf.c:1351
#7  0x00007ffff7f720f0 in tag__fprintf (tag=0x15263f0, cu=0xcd6520, conf=0x40e2a0 <conf>, fp=0x7ffff7e5e500 <_IO_2_1_stdout_>)
    at /home/vries/dwarves/src/dwarves_fprintf.c:1852
#8  0x0000000000407c51 in pahole_stealer (cu=0xcd6520, conf_load=0x40e300 <conf_load>) at /home/vries/dwarves/src/pahole.c:2481
#9  0x00007ffff7f811f1 in finalize_cu (cus=0x436870, cu=0xcd6520, dcu=0x7fffffffb850, conf=0x40e300 <conf_load>)
    at /home/vries/dwarves/src/dwarf_loader.c:2216
#10 0x00007ffff7f8122a in finalize_cu_immediately (cus=0x436870, cu=0xcd6520, dcu=0x7fffffffb850, conf=0x40e300 <conf_load>)
    at /home/vries/dwarves/src/dwarf_loader.c:2225
#11 0x00007ffff7f818d3 in cus__load_module (cus=0x436870, conf=0x40e300 <conf_load>, mod=0x436570, dw=0x432c50, elf=0x436890, 
    filename=0x7fffffffe1a7 "/home/vries/vmlinux-5.3.18-107.g1c7b2b9-default.debug") at /home/vries/dwarves/src/dwarf_loader.c:2378
#12 0x00007ffff7f819e7 in cus__process_dwflmod (dwflmod=0x436570, userdata=0x436580, 
    name=0x435d60 "/home/vries/vmlinux-5.3.18-107.g1c7b2b9-default.debug", base=18446744071578845184, arg=0x7fffffffda70)
    at /home/vries/dwarves/src/dwarf_loader.c:2423
#13 0x00007ffff7ee96c1 in dwfl_getmodules () from /usr/lib64/libdw.so.1
#14 0x00007ffff7f81aa7 in cus__process_file (cus=0x436870, conf=0x40e300 <conf_load>, fd=3, 
    filename=0x7fffffffe1a7 "/home/vries/vmlinux-5.3.18-107.g1c7b2b9-default.debug") at /home/vries/dwarves/src/dwarf_loader.c:2476
#15 0x00007ffff7f81b23 in dwarf__load_file (cus=0x436870, conf=0x40e300 <conf_load>, 
    filename=0x7fffffffe1a7 "/home/vries/vmlinux-5.3.18-107.g1c7b2b9-default.debug") at /home/vries/dwarves/src/dwarf_loader.c:2493
#16 0x00007ffff7f6ac7e in cus__load_file (cus=0x436870, conf=0x40e300 <conf_load>, 
    filename=0x7fffffffe1a7 "/home/vries/vmlinux-5.3.18-107.g1c7b2b9-default.debug") at /home/vries/dwarves/src/dwarves.c:1941
#17 0x00007ffff7f6b7af in cus__load_files (cus=0x436870, conf=0x40e300 <conf_load>, filenames=0x7fffffffdcf0)
    at /home/vries/dwarves/src/dwarves.c:2299
#18 0x00000000004082c8 in main (argc=4, argv=0x7fffffffdcd8) at /home/vries/dwarves/src/pahole.c:2675

@vries
Copy link
Author

vries commented Sep 3, 2020

Tag is NULL because member_type is NULL:


(gdb) up
#2  0x00007ffff7f69ad4 in type__natural_alignment (type=0x15867f0, cu=0xcd6520) at /home/vries/dwarves/src/dwarves.c:1469
1469                    size_t member_natural_alignment = tag__natural_alignment(member_type, cu);
(gdb) p member_type
$1 = (struct tag *) 0x0

which was set just before:
1468 struct tag *member_type = tag__strip_typedefs_and_modifiers(&member->tag, cu);
but ends up as NULL because member->tag->type is 0:

(gdb) p *member
$3 = {tag = {node = {next = 0x15869e0, prev = 0x1586920}, type = 0, tag = 13, visited = false, top_level = false, recursivity_level = 0, 
    priv = 0x1585e30}, name = 55224, bit_offset = 128, bit_size = 0, byte_offset = 16, byte_size = 0, bitfield_offset = 0 '\000', 
  bitfield_size = 0 '\000', bit_hole = 0 '\000', bitfield_end = 0 '\000', const_value = 0, alignment = 8, visited = 0 '\000', 
  is_static = 0 '\000', accessibility = 0 '\000', virtuality = 0 '\000', hole = 0}

Looking a bit more in detail:

(gdb) p /x *((struct dwarf_tag *)member.tag.priv)
$6 = {hash_node = {next = 0x1574700, pprev = 0x15758d0}, type = {from_types = 0x0, off = 0x726e}, id = 0x4273c, {abstract_origin = {
      from_types = 0x0, off = 0x0}, containing_type = {from_types = 0x0, off = 0x0}}, tag = 0x1586980, small_id = 0x0, decl_file = 0x0, 
  decl_line = 0x0}

we can see that the member is a DIE at 0x4273c with type DIE 0x726e, which corresponds to one of the messages:
namespace__recode_dwarf_types: couldn't find 0x726e type for 0x4273c (member)!

@acmel
Copy link
Owner

acmel commented Sep 9, 2020

I'm downloading the file to try and fix this.

@acmel
Copy link
Owner

acmel commented Sep 9, 2020

I couldn't find the SLES15-SP2 directory under Kernel:/, can you please check and provide some other URL for download?

@vries
Copy link
Author

vries commented Sep 9, 2020

I couldn't find the SLES15-SP2 directory under Kernel:/, can you please check and provide some other URL for download?

https://download.opensuse.org/repositories/Kernel:/SLE15-SP2/standard/x86_64/kernel-default-debuginfo-5.3.18-109.1.g8ff6392.x86_64.rpm

@vries
Copy link
Author

vries commented Sep 9, 2020

I couldn't find the SLES15-SP2 directory under Kernel:/,

FWIW, you tried SLES15-SP2 but the dir is called SLE15-SP2.

@acmel
Copy link
Owner

acmel commented Sep 9, 2020

It works now, but I had just copy'n'pasted the provided URL to use with wget, it didn't work, so I accessed the https://download.opensuse.org/repositories/Kernel:/ directory, there was nothing starting with SLE, I used SLES out of muscle memory for SuSE's SLES Enterprise distro :-) Maybe some mirror without that dir, anyway, looking at it.

@acmel
Copy link
Owner

acmel commented Sep 9, 2020

Yeah, SUSE is using partial units, probably using some kernel config option to reduce the size of the kernel debuginfo packages:

<0>: Abbrev Number: 45 (DW_TAG_partial_unit)
DW_AT_stmt_list : 0x185
<10> DW_AT_comp_dir : (indirect string, offset: 0x1bc53f): /usr/src/debug/kernel-default-5.3.18-109.1.g8ff6392.x86_64/linux-5.3/linux-obj

And that isn't yet supported in dwarves.

The fact that SuSE ships it this way makes supporting DW_TAG_partial_unit a priority for dwarves 1.19, I'll try and get v1.18 out of the door and then work on this, thanks for the report.

@vries
Copy link
Author

vries commented Sep 14, 2020

Thanks for the feedback.

Just curious, are you planning to fix the segfault in v1.18 in a conservative way?

@acmel
Copy link
Owner

acmel commented Sep 17, 2020 via email

@vries
Copy link
Author

vries commented Sep 17, 2020

Em Mon, Sep 14, 2020 at 12:27:31AM -0700, Tom de Vries escreveu:

can you provide me with this kernel .config file?

I downloaded https://download.opensuse.org/repositories/Kernel:/SLE15-SP2/standard/x86_64/kernel-default-5.3.18-112.1.gd6c1198.x86_64.rpm and got:

$ grep DEBUG_INFO boot/config-5.3.18-112.gd6c1198-default
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_INFO_REDUCED is not set
# CONFIG_DEBUG_INFO_SPLIT is not set
CONFIG_DEBUG_INFO_DWARF4=y
# CONFIG_DEBUG_INFO_BTF is not set

I'm not sure tif the partial units are caused by a kernel option.

It might just be a consequence of rpm's find-debuginfo.sh calling dwz.

@acmel
Copy link
Owner

acmel commented Sep 17, 2020 via email

acmel added a commit that referenced this issue Sep 18, 2020
We will have to keep all CUs in memory and do lookups in imported units,
for now, just don't segfault.

Reported-by: Tom de Vries
Bugtracker: #10
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Sep 18, 2020
We need to support these in a future version, for now, just bail out to
avoid segfaults afterwards.

  $ pahole examples/sles/vmlinux-5.3.18-109.g8ff6392-default.debug
  WARNING: DW_TAG_partial_unit used, some types will not be considered!
           Probably this was optimized using a tool like 'dwz'
           A future version of pahole will take support this.
  $

Reported-by: Tom de Vries
Bugtracker: #10
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Jul 8, 2021
…() calls

As this ends up racing on a tsearch() call, probably for some libdw
cache that gets updated/lookedup in concurrent pahole threads (-j N).

This cures the following, a patch for libdw will be cooked up and sent.

  (gdb) run -j -I -F dwarf vmlinux > /dev/null
  Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null
  warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0.
  warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
  warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
  [New LWP 844789]
  [New LWP 844790]
  [New LWP 844791]
  [New LWP 844792]
  [New LWP 844793]
  [New LWP 844794]
  [New LWP 844795]
  [New LWP 844796]
  [New LWP 844797]
  [New LWP 844798]
  [New LWP 844799]
  [New LWP 844800]
  [New LWP 844801]
  [New LWP 844802]
  [New LWP 844803]
  [New LWP 844804]
  [New LWP 844805]
  [New LWP 844806]
  [New LWP 844807]
  [New LWP 844808]
  [New LWP 844809]
  [New LWP 844810]
  [New LWP 844811]
  [New LWP 844812]
  [New LWP 844813]
  [New LWP 844814]

  Thread 2 "pahole" received signal SIGSEGV, Segmentation fault.
  [Switching to LWP 844789]
  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  (gdb) bt
  #0  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  #1  0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6
  #2  0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8)
      at dwarf_getsrclines.c:1129
  #3  0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213
  #4  0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66
  #5  0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476
  #6  0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576
  #7  0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595
  #8  0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614
  #9  0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212
  #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823
  #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848
  #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311
  #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326
  #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644
  #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687
  #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0
  #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6
  (gdb)
  (gdb) fr 2
  1085
  (gdb) list files_lines_compare
  1086    static int
  1087    files_lines_compare (const void *p1, const void *p2)
  1088    {
  1089	  const struct files_lines_s *t1 = p1;
  1090	  const struct files_lines_s *t2 = p2;
  1091
  1092	  if (t1->debug_line_offset < t2->debug_line_offset)
  (gdb)
  1093        return -1;
  1094	  if (t1->debug_line_offset > t2->debug_line_offset)
  1095        return 1;
  1096
  1097	  return 0;
  1098    }
  1099
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  (gdb) list __libdw_getsrclines
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  1103                         const char *comp_dir, unsigned address_size,
  1104                         Dwarf_Lines **linesp, Dwarf_Files **filesp)
  1105    {
  1106	  struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
  1107	  struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
  1108                                            files_lines_compare);
  1109	  if (found == NULL)
  (gdb)
  1110        {
  1111          Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
  1112          if (data == NULL
  1113              || __libdw_offset_in_section (dbg, IDX_debug_line,
  1114                                            debug_line_offset, 1) != 0)
  1115            return -1;
  1116
  1117          const unsigned char *linep = data->d_buf + debug_line_offset;
  1118          const unsigned char *lineendp = data->d_buf + data->d_size;
  1119
  (gdb)
  1120          struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
  1121                                                    sizeof *node, 1);
  1122
  1123          if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
  1124                             &node->lines, &node->files) != 0)
  1125            return -1;
  1126
  1127          node->debug_line_offset = debug_line_offset;
  1128
  1129          found = tsearch (node, &dbg->files_lines, files_lines_compare);
  (gdb)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Jul 27, 2021
…() calls

As this ends up racing on a tsearch() call, probably for some libdw
cache that gets updated/lookedup in concurrent pahole threads (-j N).

This cures the following, a patch for libdw will be cooked up and sent.

  (gdb) run -j -I -F dwarf vmlinux > /dev/null
  Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null
  warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0.
  warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
  warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
  [New LWP 844789]
  [New LWP 844790]
  [New LWP 844791]
  [New LWP 844792]
  [New LWP 844793]
  [New LWP 844794]
  [New LWP 844795]
  [New LWP 844796]
  [New LWP 844797]
  [New LWP 844798]
  [New LWP 844799]
  [New LWP 844800]
  [New LWP 844801]
  [New LWP 844802]
  [New LWP 844803]
  [New LWP 844804]
  [New LWP 844805]
  [New LWP 844806]
  [New LWP 844807]
  [New LWP 844808]
  [New LWP 844809]
  [New LWP 844810]
  [New LWP 844811]
  [New LWP 844812]
  [New LWP 844813]
  [New LWP 844814]

  Thread 2 "pahole" received signal SIGSEGV, Segmentation fault.
  [Switching to LWP 844789]
  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  (gdb) bt
  #0  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  #1  0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6
  #2  0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8)
      at dwarf_getsrclines.c:1129
  #3  0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213
  #4  0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66
  #5  0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476
  #6  0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576
  #7  0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595
  #8  0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614
  #9  0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212
  #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823
  #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848
  #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311
  #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326
  #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644
  #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687
  #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0
  #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6
  (gdb)
  (gdb) fr 2
  1085
  (gdb) list files_lines_compare
  1086    static int
  1087    files_lines_compare (const void *p1, const void *p2)
  1088    {
  1089	  const struct files_lines_s *t1 = p1;
  1090	  const struct files_lines_s *t2 = p2;
  1091
  1092	  if (t1->debug_line_offset < t2->debug_line_offset)
  (gdb)
  1093        return -1;
  1094	  if (t1->debug_line_offset > t2->debug_line_offset)
  1095        return 1;
  1096
  1097	  return 0;
  1098    }
  1099
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  (gdb) list __libdw_getsrclines
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  1103                         const char *comp_dir, unsigned address_size,
  1104                         Dwarf_Lines **linesp, Dwarf_Files **filesp)
  1105    {
  1106	  struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
  1107	  struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
  1108                                            files_lines_compare);
  1109	  if (found == NULL)
  (gdb)
  1110        {
  1111          Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
  1112          if (data == NULL
  1113              || __libdw_offset_in_section (dbg, IDX_debug_line,
  1114                                            debug_line_offset, 1) != 0)
  1115            return -1;
  1116
  1117          const unsigned char *linep = data->d_buf + debug_line_offset;
  1118          const unsigned char *lineendp = data->d_buf + data->d_size;
  1119
  (gdb)
  1120          struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
  1121                                                    sizeof *node, 1);
  1122
  1123          if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
  1124                             &node->lines, &node->files) != 0)
  1125            return -1;
  1126
  1127          node->debug_line_offset = debug_line_offset;
  1128
  1129          found = tsearch (node, &dbg->files_lines, files_lines_compare);
  (gdb)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Jul 28, 2021
…() calls

As this ends up racing on a tsearch() call, probably for some libdw
cache that gets updated/lookedup in concurrent pahole threads (-j N).

This cures the following, a patch for libdw will be cooked up and sent.

  (gdb) run -j -I -F dwarf vmlinux > /dev/null
  Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null
  warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0.
  warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
  warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
  [New LWP 844789]
  [New LWP 844790]
  [New LWP 844791]
  [New LWP 844792]
  [New LWP 844793]
  [New LWP 844794]
  [New LWP 844795]
  [New LWP 844796]
  [New LWP 844797]
  [New LWP 844798]
  [New LWP 844799]
  [New LWP 844800]
  [New LWP 844801]
  [New LWP 844802]
  [New LWP 844803]
  [New LWP 844804]
  [New LWP 844805]
  [New LWP 844806]
  [New LWP 844807]
  [New LWP 844808]
  [New LWP 844809]
  [New LWP 844810]
  [New LWP 844811]
  [New LWP 844812]
  [New LWP 844813]
  [New LWP 844814]

  Thread 2 "pahole" received signal SIGSEGV, Segmentation fault.
  [Switching to LWP 844789]
  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  (gdb) bt
  #0  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  #1  0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6
  #2  0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8)
      at dwarf_getsrclines.c:1129
  #3  0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213
  #4  0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66
  #5  0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476
  #6  0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576
  #7  0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595
  #8  0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614
  #9  0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212
  #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823
  #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848
  #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311
  #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326
  #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644
  #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687
  #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0
  #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6
  (gdb)
  (gdb) fr 2
  1085
  (gdb) list files_lines_compare
  1086    static int
  1087    files_lines_compare (const void *p1, const void *p2)
  1088    {
  1089	  const struct files_lines_s *t1 = p1;
  1090	  const struct files_lines_s *t2 = p2;
  1091
  1092	  if (t1->debug_line_offset < t2->debug_line_offset)
  (gdb)
  1093        return -1;
  1094	  if (t1->debug_line_offset > t2->debug_line_offset)
  1095        return 1;
  1096
  1097	  return 0;
  1098    }
  1099
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  (gdb) list __libdw_getsrclines
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  1103                         const char *comp_dir, unsigned address_size,
  1104                         Dwarf_Lines **linesp, Dwarf_Files **filesp)
  1105    {
  1106	  struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
  1107	  struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
  1108                                            files_lines_compare);
  1109	  if (found == NULL)
  (gdb)
  1110        {
  1111          Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
  1112          if (data == NULL
  1113              || __libdw_offset_in_section (dbg, IDX_debug_line,
  1114                                            debug_line_offset, 1) != 0)
  1115            return -1;
  1116
  1117          const unsigned char *linep = data->d_buf + debug_line_offset;
  1118          const unsigned char *lineendp = data->d_buf + data->d_size;
  1119
  (gdb)
  1120          struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
  1121                                                    sizeof *node, 1);
  1122
  1123          if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
  1124                             &node->lines, &node->files) != 0)
  1125            return -1;
  1126
  1127          node->debug_line_offset = debug_line_offset;
  1128
  1129          found = tsearch (node, &dbg->files_lines, files_lines_compare);
  (gdb)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Aug 6, 2021
…() calls

As this ends up racing on a tsearch() call, probably for some libdw
cache that gets updated/lookedup in concurrent pahole threads (-j N).

This cures the following, a patch for libdw will be cooked up and sent.

  (gdb) run -j -I -F dwarf vmlinux > /dev/null
  Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null
  warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0.
  warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
  warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
  [New LWP 844789]
  [New LWP 844790]
  [New LWP 844791]
  [New LWP 844792]
  [New LWP 844793]
  [New LWP 844794]
  [New LWP 844795]
  [New LWP 844796]
  [New LWP 844797]
  [New LWP 844798]
  [New LWP 844799]
  [New LWP 844800]
  [New LWP 844801]
  [New LWP 844802]
  [New LWP 844803]
  [New LWP 844804]
  [New LWP 844805]
  [New LWP 844806]
  [New LWP 844807]
  [New LWP 844808]
  [New LWP 844809]
  [New LWP 844810]
  [New LWP 844811]
  [New LWP 844812]
  [New LWP 844813]
  [New LWP 844814]

  Thread 2 "pahole" received signal SIGSEGV, Segmentation fault.
  [Switching to LWP 844789]
  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  (gdb) bt
  #0  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  #1  0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6
  #2  0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8)
      at dwarf_getsrclines.c:1129
  #3  0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213
  #4  0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66
  #5  0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476
  #6  0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576
  #7  0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595
  #8  0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614
  #9  0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212
  #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823
  #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848
  #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311
  #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326
  #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644
  #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687
  #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0
  #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6
  (gdb)
  (gdb) fr 2
  1085
  (gdb) list files_lines_compare
  1086    static int
  1087    files_lines_compare (const void *p1, const void *p2)
  1088    {
  1089	  const struct files_lines_s *t1 = p1;
  1090	  const struct files_lines_s *t2 = p2;
  1091
  1092	  if (t1->debug_line_offset < t2->debug_line_offset)
  (gdb)
  1093        return -1;
  1094	  if (t1->debug_line_offset > t2->debug_line_offset)
  1095        return 1;
  1096
  1097	  return 0;
  1098    }
  1099
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  (gdb) list __libdw_getsrclines
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  1103                         const char *comp_dir, unsigned address_size,
  1104                         Dwarf_Lines **linesp, Dwarf_Files **filesp)
  1105    {
  1106	  struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
  1107	  struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
  1108                                            files_lines_compare);
  1109	  if (found == NULL)
  (gdb)
  1110        {
  1111          Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
  1112          if (data == NULL
  1113              || __libdw_offset_in_section (dbg, IDX_debug_line,
  1114                                            debug_line_offset, 1) != 0)
  1115            return -1;
  1116
  1117          const unsigned char *linep = data->d_buf + debug_line_offset;
  1118          const unsigned char *lineendp = data->d_buf + data->d_size;
  1119
  (gdb)
  1120          struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
  1121                                                    sizeof *node, 1);
  1122
  1123          if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
  1124                             &node->lines, &node->files) != 0)
  1125            return -1;
  1126
  1127          node->debug_line_offset = debug_line_offset;
  1128
  1129          found = tsearch (node, &dbg->files_lines, files_lines_compare);
  (gdb)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Aug 12, 2021
…() calls

As this ends up racing on a tsearch() call, probably for some libdw
cache that gets updated/lookedup in concurrent pahole threads (-j N).

This cures the following, a patch for libdw will be cooked up and sent.

  (gdb) run -j -I -F dwarf vmlinux > /dev/null
  Starting program: /var/home/acme/git/pahole/build/pahole -j -I -F dwarf vmlinux > /dev/null
  warning: Expected absolute pathname for libpthread in the inferior, but got .gnu_debugdata for /lib64/libpthread.so.0.
  warning: File "/usr/lib64/libthread_db-1.0.so" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
  warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
  [New LWP 844789]
  [New LWP 844790]
  [New LWP 844791]
  [New LWP 844792]
  [New LWP 844793]
  [New LWP 844794]
  [New LWP 844795]
  [New LWP 844796]
  [New LWP 844797]
  [New LWP 844798]
  [New LWP 844799]
  [New LWP 844800]
  [New LWP 844801]
  [New LWP 844802]
  [New LWP 844803]
  [New LWP 844804]
  [New LWP 844805]
  [New LWP 844806]
  [New LWP 844807]
  [New LWP 844808]
  [New LWP 844809]
  [New LWP 844810]
  [New LWP 844811]
  [New LWP 844812]
  [New LWP 844813]
  [New LWP 844814]

  Thread 2 "pahole" received signal SIGSEGV, Segmentation fault.
  [Switching to LWP 844789]
  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  (gdb) bt
  #0  0x00007ffff7dfa321 in ?? () from /lib64/libc.so.6
  #1  0x00007ffff7dfa4bb in ?? () from /lib64/libc.so.6
  #2  0x00007ffff7f5eaa6 in __libdw_getsrclines (dbg=0x4a7f90, debug_line_offset=10383710, comp_dir=0x7ffff3c29f01 "/var/home/acme/git/build/v5.13.0-rc6+", address_size=address_size@entry=8, linesp=linesp@entry=0x7fffcfe04ba0, filesp=filesp@entry=0x7fffcfe04ba8)
      at dwarf_getsrclines.c:1129
  #3  0x00007ffff7f5ed14 in dwarf_getsrclines (cudie=cudie@entry=0x7fffd210caf0, lines=lines@entry=0x7fffd210cac0, nlines=nlines@entry=0x7fffd210cac8) at dwarf_getsrclines.c:1213
  #4  0x00007ffff7f64883 in dwarf_decl_file (die=<optimized out>) at dwarf_decl_file.c:66
  #5  0x0000000000425f24 in tag__init (tag=0x7fff0421b710, cu=0x7fffcc001e40, die=0x7fffd210cd30) at /var/home/acme/git/pahole/dwarf_loader.c:476
  #6  0x00000000004262ec in namespace__init (namespace=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:576
  #7  0x00000000004263ac in type__init (type=0x7fff0421b710, die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:595
  #8  0x00000000004264d1 in type__new (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:614
  #9  0x0000000000427ba6 in die__create_new_typedef (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1212
  #10 0x0000000000428df5 in __die__process_tag (die=0x7fffd210cd30, cu=0x7fffcc001e40, top_level=1, fn=0x45cee0 <__FUNCTION__.10> "die__process_unit", conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1823
  #11 0x0000000000428ea1 in die__process_unit (die=0x7fffd210cd30, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:1848
  #12 0x0000000000429e45 in die__process (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2311
  #13 0x0000000000429ecb in die__process_and_recode (die=0x7fffd210ce20, cu=0x7fffcc001e40, conf=0x475600 <conf_load>) at /var/home/acme/git/pahole/dwarf_loader.c:2326
  #14 0x000000000042a9d6 in dwarf_cus__create_and_process_cu (dcus=0x7fffffffddc0, cu_die=0x7fffd210ce20, pointer_size=8 '\b') at /var/home/acme/git/pahole/dwarf_loader.c:2644
  #15 0x000000000042ab28 in dwarf_cus__process_cu_thread (arg=0x7fffffffddc0) at /var/home/acme/git/pahole/dwarf_loader.c:2687
  #16 0x00007ffff7ed6299 in start_thread () from /lib64/libpthread.so.0
  #17 0x00007ffff7dfe353 in ?? () from /lib64/libc.so.6
  (gdb)
  (gdb) fr 2
  1085
  (gdb) list files_lines_compare
  1086    static int
  1087    files_lines_compare (const void *p1, const void *p2)
  1088    {
  1089	  const struct files_lines_s *t1 = p1;
  1090	  const struct files_lines_s *t2 = p2;
  1091
  1092	  if (t1->debug_line_offset < t2->debug_line_offset)
  (gdb)
  1093        return -1;
  1094	  if (t1->debug_line_offset > t2->debug_line_offset)
  1095        return 1;
  1096
  1097	  return 0;
  1098    }
  1099
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  (gdb) list __libdw_getsrclines
  1100    int
  1101    internal_function
  1102    __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
  1103                         const char *comp_dir, unsigned address_size,
  1104                         Dwarf_Lines **linesp, Dwarf_Files **filesp)
  1105    {
  1106	  struct files_lines_s fake = { .debug_line_offset = debug_line_offset };
  1107	  struct files_lines_s **found = tfind (&fake, &dbg->files_lines,
  1108                                            files_lines_compare);
  1109	  if (found == NULL)
  (gdb)
  1110        {
  1111          Elf_Data *data = __libdw_checked_get_data (dbg, IDX_debug_line);
  1112          if (data == NULL
  1113              || __libdw_offset_in_section (dbg, IDX_debug_line,
  1114                                            debug_line_offset, 1) != 0)
  1115            return -1;
  1116
  1117          const unsigned char *linep = data->d_buf + debug_line_offset;
  1118          const unsigned char *lineendp = data->d_buf + data->d_size;
  1119
  (gdb)
  1120          struct files_lines_s *node = libdw_alloc (dbg, struct files_lines_s,
  1121                                                    sizeof *node, 1);
  1122
  1123          if (read_srclines (dbg, linep, lineendp, comp_dir, address_size,
  1124                             &node->lines, &node->files) != 0)
  1125            return -1;
  1126
  1127          node->debug_line_offset = debug_line_offset;
  1128
  1129          found = tsearch (node, &dbg->files_lines, files_lines_compare);
  (gdb)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Jan 28, 2022
…ne_size field

tldr;

  gdb pfunct
  (gdb) run --compile tcp.o
  Program received signal SIGFPE, Arithmetic exception.
  0x00007ffff7f18551 in class__fprintf_cacheline_boundary (conf=0x7fffffffda10, offset=0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1319
  1319		uint32_t cacheline = offset / conf->cacheline_size;
  (gdb) bt
  #0  0x00007ffff7f18551 in class__fprintf_cacheline_boundary (conf=0x7fffffffda10, offset=0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1319
  #1  0x00007ffff7f16af2 in class_member__fprintf (member=0x45de10, union_member=false, type=0x45dfb0, cu=0x435a40, conf=0x7fffffffda10, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:869
  #2  0x00007ffff7f1717b in struct_member__fprintf (member=0x45de10, type=0x45dfb0, cu=0x435a40, conf=0x7fffffffda10, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:983
  #3  0x00007ffff7f1945c in __class__fprintf (class=0x45dcc0, cu=0x435a40, conf=0x7fffffffdbb0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1583
  #4  0x00007ffff7f1a6bd in tag__fprintf (tag=0x45dcc0, cu=0x435a40, conf=0x7fffffffdc70, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_fprintf.c:1906
  #5  0x00007ffff7fbf022 in type__emit (tag=0x45dcc0, cu=0x435a40, prefix=0x0, suffix=0x0, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:333
  #6  0x00007ffff7fbed3d in tag__emit_definitions (tag=0x6b21e0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:265
  #7  0x00007ffff7fbef45 in type__emit_definitions (tag=0x6b20c0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:315
  #8  0x00007ffff7fbed15 in tag__emit_definitions (tag=0x6b3b40, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:264
  #9  0x00007ffff7fbef45 in type__emit_definitions (tag=0x6b31d0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:315
  #10 0x00007ffff7fbed15 in tag__emit_definitions (tag=0x4cb920, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:264
  #11 0x00007ffff7fbef45 in type__emit_definitions (tag=0x4cb7d0, cu=0x435a40, emissions=0x408300 <emissions>, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/dwarves_emit.c:315
  #12 0x0000000000403592 in function__emit_type_definitions (func=0x738ad0, cu=0x435a40, fp=0x7ffff7e17520 <_IO_2_1_stdout_>) at /var/home/acme/git/pahole/pfunct.c:353
  #13 0x0000000000403670 in function__show (func=0x738ad0, cu=0x435a40) at /var/home/acme/git/pahole/pfunct.c:371
  #14 0x00000000004038e9 in cu_function_iterator (cu=0x435a40, cookie=0x0) at /var/home/acme/git/pahole/pfunct.c:404
  #15 0x00007ffff7f1296b in cus__for_each_cu (cus=0x4369e0, iterator=0x403869 <cu_function_iterator>, cookie=0x0, filter=0x0) at /var/home/acme/git/pahole/dwarves.c:1919
  #16 0x000000000040432a in main (argc=3, argv=0x7fffffffe1f8) at /var/home/acme/git/pahole/pfunct.c:776
  (gdb) p conf->cacheline_size
  $2 = 0

We need to pass a conf_fprintf pointer to the chain starting with
function__emit_type_definitions(), i.e. dwarves_emit.c needs to receive
the printing configuration instead of, right at type__emit() synthesize
a conf_fprintf without initializing conf_fprintf->cacheline_size which
ends up in a division by zero.

But to fix this quicker just add a helper that checks if it is zero and
uses the conf_fprintf__defaults.cacheline_size field that is being
initialized by all tools via:

  dwarves__resolve_cacheline_size(&conf_load, 0);

Fixes: 772725a ("dwarves_fprintf: Move cacheline_size into struct conf_fprintf")
Cc: Douglas Raillard <douglas.raillard@arm.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
@brycekahle
Copy link

👋 I just ran into the lack of support for DWARF4 / DW_TAG_partial_unit in dwarves and pahole. I was trying to generate BTF for SLES15 kernels. Anything I can do to help get this over the finish line?

@acmel
Copy link
Owner

acmel commented Feb 1, 2023 via email

@brycekahle
Copy link

@acmel that seemed to work for me, but I haven't done extended validation on the BTF it generated. Commands like pahole -C task_struct work too.

@acmel
Copy link
Owner

acmel commented Feb 1, 2023 via email

@brycekahle
Copy link

brycekahle commented Feb 1, 2023

Hmm it worked for 15-SP3 kernels, but not for 15-SP2 or 15-SP1

@brycekahle
Copy link

These are actually SLES kernels, so not opensuse. I can try and find a way to upload one somewhere.

@brycekahle
Copy link

And if you could make one of these kernel rpms available somewhere

I shared a Google Drive link with your RedHat email of an SLES15-SP2 kernel that doesn't work. Let me know if you need other kernels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants