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

Segfaults on gdb testsuite #9

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

Segfaults on gdb testsuite #9

vries opened this issue Sep 3, 2020 · 19 comments

Comments

@vries
Copy link

vries commented Sep 3, 2020

After running the gdb testsuite, we have a directory with test-case executables. We can use those to test pahole as well:
...
$ for f in $(find build/gdb/testsuite -type f -executable); do ~/dwarves/build/pahole $f > /dev/null 2>&1; st=$?; if [ $st -ne 0 ]; then echo "$f $st"; fi; done
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.fortran/derived-type/derived-type 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.fortran/max-depth/max-depth 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/O2_float_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/access_tagged_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/access_to_packed_array/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/access_to_unbounded_array/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/addr_arith/foo_na07_019 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/aliased_array/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/arr_acc_idx_w_gap/enum_with_gap_main 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/arr_arr/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/arr_enum_idx_w_gap/foo_q418_043 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/array_bounds/bar 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/array_char_idx/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/array_of_variable_length/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/array_ptr_renaming/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/array_return/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/array_subscript_addr/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/arraydim/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/arrayidx/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/arrayparam/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/arrayptr/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/assign_arr/main_p324_051 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/atomic_enum/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/attr_ref_and_charlit/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bad-task-bp-keyword/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bias/bias 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/big_packed_array/foo_ra24_010 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bp_c_mixed_case/foo_h731_021 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bp_enum_homonym/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bp_fun_addr/bp_fun_addr 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bp_inlined_func/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bp_on_var/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bp_range_type/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/bp_reset/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/byte_packed_arr/reprod_main 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/call_pn/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/catch_assert_if/bla 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/catch_ex/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/catch_ex_std/libsome_package.so 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/catch_ex_std/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/char_enum/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/char_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/complete/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/cond_lang/a 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/convvar_comp/pb16_063 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/dgopt/x 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/disc_arr_bound/foo_n612_026 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/display_nested/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/dot_all/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/dyn_arrayidx/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/dyn_loc/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/dyn_stride/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/enum_idx_packed/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/excep_handle/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/exec_changed/first 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/exec_changed/common 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/expr_delims/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/expr_with_funcall/expr_r821_013 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/exprs/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fin_fun_out/foo_o525_013 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fixed_cmp/fixed 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fixed_points/fixed_points 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/float_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/formatted_ref/formatted_ref 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/frame_arg_lang/bla 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/frame_args/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fullname_bp/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fun_addr/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fun_in_declare/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fun_overload_menu/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/fun_renaming/fun_renaming 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/funcall_char/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/funcall_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/funcall_ptr/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/funcall_ref/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/homonym/homonym_main 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/info_addr_mixed_case/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/info_auto_lang/proc_in_ada 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/info_exc/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/info_locals_renaming/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/int_deref/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/interface/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/iwide/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/lang_switch/lang_switch 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/length_cond/length_cond 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/maint_with_ada/var_arr_typedef 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_catch_assert/bla 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_catch_ex/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_catch_ex_hand/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_dyn_arr/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_ex_cond/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_exc_info/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_interface/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_prot/prot 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_ref_changeable/foo_rb20_056 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_string_access/bar 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_task_arg/task_switch 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_task_info/task_switch 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_var_array/bar 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_var_union/bar 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mi_variant/pkg 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/minsyms/foo_qb07_057 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/mod_from_name/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/n_arr_bound/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/nested/hello 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/notcplusplus/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/null_array/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/null_record/null_record 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/operator_bp/ops_test 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/optim_drec/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/out_of_line_in_inlined/foo_o224_021 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/packed_array/pa 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/packed_array_assign/tester 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/packed_tagged/comp_bug 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/pckd_arr_ren/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/pckd_neg/foo_o508_021 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/pkd_arr_elem/failure 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/pp-rec-component/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/print_chars/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/print_pc/dummy 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/ptr_typedef/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/ptype_array/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/ptype_field/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/ptype_tagged_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/ptype_tagged_param/gnat_debug_info_test 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/py_range/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/py_taft/main 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/rdv_wait/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/rec_comp/bar_o203_012 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/rec_return/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/ref_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/ref_tick_size/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/rename_subscript_param/pb30_012 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/repeat_dyn/foo_oc22_002 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/same_component_name/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/same_enum/a 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/scalar_storage/storage 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/scoped_watch/foo_p708_025 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/set_pckd_arr_elt/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/set_wstr/a 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/small_reg_param/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/start/dummy 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/str_binop_equal/foo_p211_061 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/str_ref_cmp/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/str_uninit/parse 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/sub_variant/subv 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/sym_print_name/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/taft_type/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/tagged/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/tagged_access/p 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/tagged_not_init/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/task_bp/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/task_switch_in_core/crash 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/tasks/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/tick_last_segv/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/tick_length_array_enum_idx/foo_n207_004 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/type_coercion/assign 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/unc_arr_ptr_in_var_rec/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/unchecked_union/unchecked_union 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/uninitialized_vars/parse 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/var_arr_attrs/foo_o115_002 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/var_arr_typedef/var_arr_typedef 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/var_rec_arr/foo_na09_042 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/variant-record/proc 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/variant/pkg 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/variant_record_packed_array/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/varsize_limit/vsizelim 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/vla/vla 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/watch_arg/watch 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/watch_minus_l/foo_ra10_006 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/whatis_array_val/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/widewide/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.ada/win_fu_syms/foo 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.base/gdb-caching-proc/gnat_debug_info_test 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.dwarf2/dw2-error/dw2-error 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.dwarf2/variant/variant 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.rust/methods/methods 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.rust/modules/modules 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.rust/rust-style/rust-style 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.rust/simple/simple 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.rust/traits/traits 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.rust/union/union 139
Segmentation fault (core dumped)
build/gdb/testsuite/outputs/gdb.rust/unsized/unsized 139
...

@vries
Copy link
Author

vries commented Sep 3, 2020

First (build/gdb/testsuite/outputs/gdb.fortran/derived-type/derived-type) in more detail:
...
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f65ce2 in tag__is_struct (tag=0x0) at /home/vries/dwarves/src/dwarves.h:419
419 return tag->tag == DW_TAG_structure_type ||
...

with backtrace:
...
(gdb) bt
#0 0x00007ffff7f65ce2 in tag__is_struct (tag=0x0) at /home/vries/dwarves/src/dwarves.h:419
#1 0x00007ffff7f69baa in type__check_structs_at_unnatural_alignments (type=0x4399d0, cu=0x432ad0)
at /home/vries/dwarves/src/dwarves.c:1491
#2 0x00007ffff7f69cd4 in class__infer_packed_attributes (cls=0x4399d0, cu=0x432ad0) at /home/vries/dwarves/src/dwarves.c:1521
#3 0x00007ffff7f70521 in __class__fprintf (class=0x4399d0, cu=0x432ad0, conf=0x7fffffffb590, fp=0x7ffff7e5e500 <IO_2_1_stdout>)
at /home/vries/dwarves/src/dwarves_fprintf.c:1351
#4 0x00007ffff7f720f0 in tag__fprintf (tag=0x4399d0, cu=0x432ad0, conf=0x40e2a0 , fp=0x7ffff7e5e500 <IO_2_1_stdout>)
at /home/vries/dwarves/src/dwarves_fprintf.c:1852
#5 0x0000000000402f8c in class_formatter (class=0x4399d0, cu=0x432ad0, id=5) at /home/vries/dwarves/src/pahole.c:229
#6 0x0000000000403302 in print_classes (cu=0x432ad0) at /home/vries/dwarves/src/pahole.c:324
#7 0x00000000004077af in pahole_stealer (cu=0x432ad0, conf_load=0x40e300 <conf_load>) at /home/vries/dwarves/src/pahole.c:2378
#8 0x00007ffff7f811f1 in finalize_cu (cus=0x436870, cu=0x432ad0, dcu=0x7fffffffb860, conf=0x40e300 <conf_load>)
at /home/vries/dwarves/src/dwarf_loader.c:2216
#9 0x00007ffff7f8122a in finalize_cu_immediately (cus=0x436870, cu=0x432ad0, dcu=0x7fffffffb860, conf=0x40e300 <conf_load>)
at /home/vries/dwarves/src/dwarf_loader.c:2225
#10 0x00007ffff7f818d3 in cus__load_module (cus=0x436870, conf=0x40e300 <conf_load>, mod=0x436570, dw=0x432c50, elf=0x436890,
filename=0x7fffffffe191 "build/gdb/testsuite/outputs/gdb.fortran/derived-type/derived-type")
at /home/vries/dwarves/src/dwarf_loader.c:2378
#11 0x00007ffff7f819e7 in cus__process_dwflmod (dwflmod=0x436570, userdata=0x436580,
name=0x432fa0 "build/gdb/testsuite/outputs/gdb.fortran/derived-type/derived-type", base=4194304, arg=0x7fffffffda80)
at /home/vries/dwarves/src/dwarf_loader.c:2423
#12 0x00007ffff7ee96c1 in dwfl_getmodules () from /usr/lib64/libdw.so.1
#13 0x00007ffff7f81aa7 in cus__process_file (cus=0x436870, conf=0x40e300 <conf_load>, fd=3,
filename=0x7fffffffe191 "build/gdb/testsuite/outputs/gdb.fortran/derived-type/derived-type")
at /home/vries/dwarves/src/dwarf_loader.c:2476
#14 0x00007ffff7f81b23 in dwarf__load_file (cus=0x436870, conf=0x40e300 <conf_load>,
filename=0x7fffffffe191 "build/gdb/testsuite/outputs/gdb.fortran/derived-type/derived-type")
--Type for more, q to quit, c to continue without paging--
at /home/vries/dwarves/src/dwarf_loader.c:2493
#15 0x00007ffff7f6ac7e in cus__load_file (cus=0x436870, conf=0x40e300 <conf_load>,
filename=0x7fffffffe191 "build/gdb/testsuite/outputs/gdb.fortran/derived-type/derived-type")
at /home/vries/dwarves/src/dwarves.c:1941
#16 0x00007ffff7f6b7af in cus__load_files (cus=0x436870, conf=0x40e300 <conf_load>, filenames=0x7fffffffdcf0)
at /home/vries/dwarves/src/dwarves.c:2299
#17 0x00000000004082c8 in main (argc=2, argv=0x7fffffffdce8) at /home/vries/dwarves/src/pahole.c:2675
...

@vries
Copy link
Author

vries commented Sep 3, 2020

Reproducer:
derived-type.debug.gz

@vries
Copy link
Author

vries commented Sep 3, 2020

Reproducer:
derived-type.debug.gz

To be more explicit:

$ ~/dwarves/build/pahole derived-type.debug 
die__process_unit: DW_TAG_string_type (0x12) @ <0x122> not handled!
namespace__recode_dwarf_types: couldn't find 0x122 type for 0x116 (member)!
struct bar {
        integer(kind=4)            c;                    /*     0     4 */
        real(kind=4)               d;                    /*     4     4 */

        /* size: 8, cachelines: 1, members: 2 */
        /* last cacheline: 8 bytes */
};
Segmentation fault (core dumped)

@acmel
Copy link
Owner

acmel commented Sep 9, 2020

This is a mix of FORTRAN 95, ANSI C99 and MIPS assembler, so something not really tested before, I'll see if we can fix it to the point of not segfaulting, perhaps a warning should be produced as a comment at the start of the output stating that this isn't a language really supported.

@acmel
Copy link
Owner

acmel commented Sep 18, 2020 via email

@acmel
Copy link
Owner

acmel commented Sep 18, 2020 via email

acmel added a commit that referenced this issue Sep 18, 2020
This dodges a SEGFAULT at type__check_structs_at_unnatural_alignments()
so that we can finish processing, give the warnings and produce as much
as we can:

  $ pahole examples/fortran95/derived-type.debug
  die__process_unit: DW_TAG_string_type (0x12) @ <0x122> not handled!
  namespace__recode_dwarf_types: couldn't find 0x122 type for 0x116 (member)!
  struct bar {
  	integer(kind=4)            c;                    /*     0     4 */
  	real(kind=4)               d;                    /*     4     4 */

  	/* size: 8, cachelines: 1, members: 2 */
  	/* last cacheline: 8 bytes */
  };
  struct foo {
  	real(kind=4)               a;                    /*     0     4 */
  	struct bar                 x;                    /*     4     8 */
  	<ERROR(__class__fprintf:1519): 0 not found!>

  	/* size: 20, cachelines: 1, members: 3 */
  	/* padding: 8 */
  	/* last cacheline: 20 bytes */
  };
  $

Reported-by: Tom de Vries
Bugtracker: #9
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Sep 18, 2020
FORTRAN 95 stuff:

  $ readelf -wi examples/fortran95/derived-type.debug | grep Fortran -A2
      <9c>   DW_AT_producer    : (indirect string, offset: 0x1fb): GNU Fortran2008 10.2.1 20200728 [revision c0438ced53bcf57e4ebb1c38c226e41571aca892] -mtune=generic -march=x86-64 -g -fno-stack-protector -J /home/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.fortran/derived-type -fintrinsic-modules-path /usr/lib64/gcc/x86_64-suse-linux/10/finclude -fpre-include=/usr/include/finclude/math-vector-fortran.h
      <a0>   DW_AT_language    : 14	(Fortran 95)
      <a1>   DW_AT_identifier_case: 2	(down_case)
      <a2>   DW_AT_name        : (indirect string, offset: 0x365): /home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.fortran/derived-type.f90
  [acme@five pahole]$ readelf -wi examples/fortran95/derived-type.debug | grep DW_TAG_string_type -A2
   <1><122>: Abbrev Number: 6 (DW_TAG_string_type)
      <123>   DW_AT_byte_size   : 7
  $

Kinda like an array, but number of entries is given by DW_AT_byte_size,
if it isn't there, then 1 byte. DW_TAG_array_type can have zero size.

Next patch will pretty print it.

Reported-by: Tom de Vries
Bugtracker: #9
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Sep 18, 2020
We don't really reconstruct source code for FORTRAN, we just print it as
if it was C:

  $ pahole examples/fortran95/derived-type.debug
  struct bar {
  	integer(kind=4)            c;                    /*     0     4 */
  	real(kind=4)               d;                    /*     4     4 */

  	/* size: 8, cachelines: 1, members: 2 */
  	/* last cacheline: 8 bytes */
  };
  struct foo {
  	real(kind=4)               a;                    /*     0     4 */
  	struct bar                 x;                    /*     4     8 */
  	string                     b[7];                 /*    12     7 */

  	/* size: 20, cachelines: 1, members: 3 */
  	/* padding: 1 */
  	/* last cacheline: 20 bytes */
  };
  $

This comes from GCC build tests:

  $ readelf -wi examples/fortran95/derived-type.debug | grep Fortran -A2
      <9c>   DW_AT_producer    : (indirect string, offset: 0x1fb): GNU Fortran2008 10.2.1 20200728 [revision c0438ced53bcf57e4ebb1c38c226e41571aca892] -mtune=generic -march=x86-64 -g -fno-stack-protector -J /home/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.fortran/derived-type -fintrinsic-modules-path /usr/lib64/gcc/x86_64-suse-linux/10/finclude -fpre-include=/usr/include/finclude/math-vector-fortran.h
      <a0>   DW_AT_language    : 14     (Fortran 95)
      <a1>   DW_AT_identifier_case: 2   (down_case)
      <a2>   DW_AT_name        : (indirect string, offset: 0x365): /home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.fortran/derived-type.f90
  [acme@five pahole]$ readelf -wi examples/fortran95/derived-type.debug | grep DW_TAG_string_type -A2
   <1><122>: Abbrev Number: 6 (DW_TAG_string_type)
      <123>   DW_AT_byte_size   : 7
  $

Now lets see whats more that is there segfaulting pahole, but for now I
think I don't have any segfaults, so just wait a bit for Hao to submit
the patch to selectively encode the per-cpu variables in BTF and then
cut v1.18.

Reported-by: Tom de Vries
Bugtracker: #9
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
@vries
Copy link
Author

vries commented Sep 19, 2020

So this now looks like below, please let me know if you is ok with my adding your e-mail to the Reported-by tag.

Hi,

sure, this is ok.

@acmel
Copy link
Owner

acmel commented Sep 21, 2020 via email

@vries
Copy link
Author

vries commented Sep 21, 2020

Also I don't recall if you made the other object files causing segfaults available somewhere, have you?

I didn't. I'll retest with the latest fixes, and report back.

@vries
Copy link
Author

vries commented Sep 21, 2020

simple.debug.gz

Simple.debug, a rust executable:

$ ~/dwarves/build/pahole simple.debug 
die__process_function: tag not supported 0x2f (template_type_parameter)!
die__process_class: DW_TAG_variant_part (0x33) @ <0x220> not handled!
Segmentation fault (core dumped)

@vries
Copy link
Author

vries commented Sep 21, 2020

foo.debug.gz

Foo.debug, an ada exec:

$ ~/dwarves/build/pahole foo.debug 
die__process_unit: DW_TAG_subrange_type (0x21) @ <0x10b> not handled!
die__process_unit: DW_TAG_subrange_type (0x21) @ <0x134> not handled!
die__process_unit: DW_TAG_subrange_type (0x21) @ <0x148> not handled!
die__process_class: DW_TAG_subrange_type (0x21) @ <0x201> not handled!
Segmentation fault (core dumped)

@vries
Copy link
Author

vries commented Sep 21, 2020

dw2-error.debug.gz

Dwarf assembly test-case:

$ ~/dwarves/build/pahole dw2-error.debug 
Segmentation fault (core dumped)

@acmel
Copy link
Owner

acmel commented Sep 22, 2020 via email

@acmel
Copy link
Owner

acmel commented Sep 22, 2020 via email

acmel added a commit that referenced this issue Sep 22, 2020
Some parts are corrupt, and most are empty CUs, that were causing the
segfault, now pahole doesn't crash and pdwtags, a debug utility that
prints most dwarf tags, produces some output.

  [acme@quaco pahole]$ readelf -wi examples/asm/dw2-error.debug  | grep -i corrupt
  readelf: examples/asm/dw2-error.debug: Warning: Invalid pointer size (0) in compunit header, using 4 instead
  readelf: examples/asm/dw2-error.debug: Warning: CU at offset 90 contains corrupt or unsupported version number: 153.
  [acme@quaco pahole]$ pahole examples/asm/dw2-error.debug
  [acme@quaco pahole]$ pdwtags examples/asm/dw2-error.debug
  /* Types: */

  /* Functions: */

  /* Variables: */

  /* Types: */

  /* 1 */
  int
   /* size: 4 */

  /* 2 */
  /* tag__fprintf: const_type tag not supported! */; /* size: 4 */

  /* Functions: */

  /* Variables: */

  const int                  _IO_stdin_used; /* size: 4 */

  /* Types: */

  /* Functions: */

  /* Variables: */

  [acme@quaco pahole]$

Reported-by: Tom de Vries
Bugtracker: #9 (comment)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Sep 22, 2020
[simple.debug.gz](https://github.com/acmel/dwarves/files/5257290/simple.debug.gz)

Simple.debug, a rust executable:
```
$ ~/dwarves/build/pahole simple.debug
die__process_function: tag not supported 0x2f (template_type_parameter)!
die__process_class: DW_TAG_variant_part (0x33) @ <0x220> not handled!
Segmentation fault (core dumped)

Added a XXX for looking into DW_TAG_variant_part later, with that:

  $ pahole examples/rust/simple.debug
  die__process_function: tag not supported 0x2f (template_type_parameter)!
  die__process_class: tag not supported 0x33 (variant_part)!
  die__create_new_enumeration: DW_TAG_subprogram (0x2e) @ <0x2da3> not handled!
  struct (core::ptr::non_null::NonNull<u8>, core::alloc::layout::Layout) {
  	struct NonNull<u8>         __0 __attribute__((__aligned__(8))); /*     0     8 */
  	struct Layout              __1 __attribute__((__aligned__(8))); /*     8    16 */

  	/* size: 24, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 24 bytes */
  } __attribute__((__aligned__(8)));
  struct vtable {

  	/* size: 0, cachelines: 0, members: 0 */
  } __attribute__((__aligned__(8)));
  struct (&usize, &usize) {
  	usize *                    __0 __attribute__((__aligned__(8))); /*     0     8 */
  	usize *                    __1 __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct &str {
  	u8 *                       data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct *const [u8] {
  	u8 *                       data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct *const [i32] {
  	i32 *                      data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct *mut [u8] {
  	u8 *                       data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct &[u8] {
  	u8 *                       data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct (i32, f64) {
  	i32                        __0 __attribute__((__aligned__(4))); /*     0     4 */

  	/* XXX 4 bytes hole, try to pack */

  	f64                        __1 __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* sum members: 12, holes: 1, sum holes: 4 */
  	/* forced alignments: 2, forced holes: 1, sum forced holes: 4 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct &[i32] {
  	i32 *                      data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct &mut [u8] {
  	u8 *                       data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct &[&str] {
  	struct &str *              data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct &[core::fmt::rt::v1::Argument] {
  	struct Argument *          data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct &[core::fmt::ArgumentV1] {
  	struct ArgumentV1 *        data_ptr __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      length __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct Opaque {

  	/* size: 0, cachelines: 0, members: 0 */
  } __attribute__((__aligned__(1)));
  struct (usize, usize) {
  	usize                      __0 __attribute__((__aligned__(8))); /*     0     8 */
  	usize                      __1 __attribute__((__aligned__(8))); /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct (core::alloc::layout::Layout, usize) {
  	struct Layout              __0 __attribute__((__aligned__(8))); /*     0    16 */
  	usize                      __1 __attribute__((__aligned__(8))); /*    16     8 */

  	/* size: 24, cachelines: 1, members: 2 */
  	/* forced alignments: 2 */
  	/* last cacheline: 24 bytes */
  } __attribute__((__aligned__(8)));
  struct (usize, bool) {
  	usize                      __0 __attribute__((__aligned__(8))); /*     0     8 */
  	bool                       __1 __attribute__((__aligned__(1))); /*     8     1 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* padding: 7 */
  	/* forced alignments: 2 */
  	/* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));
  struct backtrace_state {
  	const char  *              filename;             /*     0     8 */
  	int                        threaded;             /*     8     4 */

  	/* XXX 4 bytes hole, try to pack */

  	void *                     lock;                 /*    16     8 */
  	fileline                   fileline_fn;          /*    24     8 */
  	void *                     fileline_data;        /*    32     8 */
  	syminfo                    syminfo_fn;           /*    40     8 */
  	void *                     syminfo_data;         /*    48     8 */
  	int                        fileline_initialization_failed; /*    56     4 */
  	int                        lock_alloc;           /*    60     4 */
  	/* --- cacheline 1 boundary (64 bytes) --- */
  	struct backtrace_freelist_struct * freelist;     /*    64     8 */

  	/* size: 72, cachelines: 2, members: 10 */
  	/* sum members: 68, holes: 1, sum holes: 4 */
  	/* last cacheline: 8 bytes */
  };
  struct timespec {
  	__time_t                   tv_sec;               /*     0     8 */
  	__syscall_slong_t          tv_nsec;              /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* last cacheline: 16 bytes */
  };
  struct stat {
  	__dev_t                    st_dev;               /*     0     8 */
  	__ino_t                    st_ino;               /*     8     8 */
  	__nlink_t                  st_nlink;             /*    16     8 */
  	__mode_t                   st_mode;              /*    24     4 */
  	__uid_t                    st_uid;               /*    28     4 */
  	__gid_t                    st_gid;               /*    32     4 */
  	int                        __pad0;               /*    36     4 */
  	__dev_t                    st_rdev;              /*    40     8 */
  	__off_t                    st_size;              /*    48     8 */
  	__blksize_t                st_blksize;           /*    56     8 */
  	/* --- cacheline 1 boundary (64 bytes) --- */
  	__blkcnt_t                 st_blocks;            /*    64     8 */
  	struct timespec            st_atim;              /*    72    16 */
  	struct timespec            st_mtim;              /*    88    16 */
  	struct timespec            st_ctim;              /*   104    16 */
  	__syscall_slong_t          __glibc_reserved[3];  /*   120    24 */

  	/* size: 144, cachelines: 3, members: 15 */
  	/* last cacheline: 16 bytes */
  };
  struct dl_phdr_info {
  	Elf64_Addr                 dlpi_addr;            /*     0     8 */
  	const char  *              dlpi_name;            /*     8     8 */
  	const Elf64_Phdr  *        dlpi_phdr;            /*    16     8 */
  	Elf64_Half                 dlpi_phnum;           /*    24     2 */

  	/* XXX 6 bytes hole, try to pack */

  	long long unsigned int     dlpi_adds;            /*    32     8 */
  	long long unsigned int     dlpi_subs;            /*    40     8 */
  	size_t                     dlpi_tls_modid;       /*    48     8 */
  	void *                     dlpi_tls_data;        /*    56     8 */

  	/* size: 64, cachelines: 1, members: 8 */
  	/* sum members: 58, holes: 1, sum holes: 6 */
  };
  struct backtrace_view {
  	const void  *              data;                 /*     0     8 */
  	void *                     base;                 /*     8     8 */
  	size_t                     len;                  /*    16     8 */

  	/* size: 24, cachelines: 1, members: 3 */
  	/* last cacheline: 24 bytes */
  };
  struct dwarf_sections {
  	const unsigned char  *     data[9];              /*     0    72 */
  	/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
  	size_t                     size[9];              /*    72    72 */

  	/* size: 144, cachelines: 3, members: 2 */
  	/* last cacheline: 16 bytes */
  };
  struct debug_section_info {
  	off_t                      offset;               /*     0     8 */
  	size_t                     size;                 /*     8     8 */
  	const unsigned char  *     data;                 /*    16     8 */
  	int                        compressed;           /*    24     4 */

  	/* size: 32, cachelines: 1, members: 4 */
  	/* padding: 4 */
  	/* last cacheline: 32 bytes */
  };
  struct elf_symbol {
  	const char  *              name;                 /*     0     8 */
  	uintptr_t                  address;              /*     8     8 */
  	size_t                     size;                 /*    16     8 */

  	/* size: 24, cachelines: 1, members: 3 */
  	/* last cacheline: 24 bytes */
  };
  struct elf_syminfo_data {
  	struct elf_syminfo_data *  next;                 /*     0     8 */
  	struct elf_symbol *        symbols;              /*     8     8 */
  	size_t                     count;                /*    16     8 */

  	/* size: 24, cachelines: 1, members: 3 */
  	/* last cacheline: 24 bytes */
  };
  struct elf_ppc64_opd_data {
  	b_elf_addr                 addr;                 /*     0     8 */
  	const char  *              data;                 /*     8     8 */
  	size_t                     size;                 /*    16     8 */
  	struct backtrace_view      view;                 /*    24    24 */

  	/* size: 48, cachelines: 1, members: 4 */
  	/* last cacheline: 48 bytes */
  };
  struct phdr_data {
  	struct backtrace_state *   state;                /*     0     8 */
  	backtrace_error_callback   error_callback;       /*     8     8 */
  	void *                     data;                 /*    16     8 */
  	fileline *                 fileline_fn;          /*    24     8 */
  	int *                      found_sym;            /*    32     8 */
  	int *                      found_dwarf;          /*    40     8 */
  	const char  *              exe_filename;         /*    48     8 */
  	int                        exe_descriptor;       /*    56     4 */

  	/* size: 64, cachelines: 1, members: 8 */
  	/* padding: 4 */
  };
  struct backtrace_vector {
  	void *                     base;                 /*     0     8 */
  	size_t                     size;                 /*     8     8 */
  	size_t                     alc;                  /*    16     8 */

  	/* size: 24, cachelines: 1, members: 3 */
  	/* last cacheline: 24 bytes */
  };
  struct dwarf_buf {
  	const char  *              name;                 /*     0     8 */
  	const unsigned char  *     start;                /*     8     8 */
  	const unsigned char  *     buf;                  /*    16     8 */
  	size_t                     left;                 /*    24     8 */
  	int                        is_bigendian;         /*    32     4 */

  	/* XXX 4 bytes hole, try to pack */

  	backtrace_error_callback   error_callback;       /*    40     8 */
  	void *                     data;                 /*    48     8 */
  	int                        reported_underflow;   /*    56     4 */

  	/* size: 64, cachelines: 1, members: 8 */
  	/* sum members: 56, holes: 1, sum holes: 4 */
  	/* padding: 4 */
  };
  struct attr {
  	enum dwarf_attribute       name;                 /*     0     4 */
  	enum dwarf_form            form;                 /*     4     4 */
  	int64_t                    val;                  /*     8     8 */

  	/* size: 16, cachelines: 1, members: 3 */
  	/* last cacheline: 16 bytes */
  };
  struct abbrev {
  	uint64_t                   code;                 /*     0     8 */
  	enum dwarf_tag             tag;                  /*     8     4 */
  	int                        has_children;         /*    12     4 */
  	size_t                     num_attrs;            /*    16     8 */
  	struct attr *              attrs;                /*    24     8 */

  	/* size: 32, cachelines: 1, members: 5 */
  	/* last cacheline: 32 bytes */
  };
  struct abbrevs {
  	size_t                     num_abbrevs;          /*     0     8 */
  	struct abbrev *            abbrevs;              /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* last cacheline: 16 bytes */
  };
  struct attr_val {
  	enum attr_val_encoding     encoding;             /*     0     4 */

  	/* XXX 4 bytes hole, try to pack */

  	union {
  		uint64_t           uint;                 /*     8     8 */
  		int64_t            sint;                 /*     8     8 */
  		const char  *      string;               /*     8     8 */
  	} u;                                             /*     8     8 */

  	/* size: 16, cachelines: 1, members: 2 */
  	/* sum members: 12, holes: 1, sum holes: 4 */
  	/* last cacheline: 16 bytes */
  };
  struct line_header {
  	int                        version;              /*     0     4 */
  	int                        addrsize;             /*     4     4 */
  	unsigned int               min_insn_len;         /*     8     4 */
  	unsigned int               max_ops_per_insn;     /*    12     4 */
  	int                        line_base;            /*    16     4 */
  	unsigned int               line_range;           /*    20     4 */
  	unsigned int               opcode_base;          /*    24     4 */

  	/* XXX 4 bytes hole, try to pack */

  	const unsigned char  *     opcode_lengths;       /*    32     8 */
  	size_t                     dirs_count;           /*    40     8 */
  	const char  * *            dirs;                 /*    48     8 */
  	size_t                     filenames_count;      /*    56     8 */
  	/* --- cacheline 1 boundary (64 bytes) --- */
  	const char  * *            filenames;            /*    64     8 */

  	/* size: 72, cachelines: 2, members: 12 */
  	/* sum members: 68, holes: 1, sum holes: 4 */
  	/* last cacheline: 8 bytes */
  };
  struct line_header_format {
  	int                        lnct;                 /*     0     4 */
  	enum dwarf_form            form;                 /*     4     4 */

  	/* size: 8, cachelines: 1, members: 2 */
  	/* last cacheline: 8 bytes */
  };
  struct line {
  	uintptr_t                  pc;                   /*     0     8 */
  	const char  *              filename;             /*     8     8 */
  	int                        lineno;               /*    16     4 */
  	int                        idx;                  /*    20     4 */

  	/* size: 24, cachelines: 1, members: 4 */
  	/* last cacheline: 24 bytes */
  };
  struct line_vector {
  	struct backtrace_vector    vec;                  /*     0    24 */
  	size_t                     count;                /*    24     8 */

  	/* size: 32, cachelines: 1, members: 2 */
  	/* last cacheline: 32 bytes */
  };
  struct function {
  	const char  *              name;                 /*     0     8 */
  	const char  *              caller_filename;      /*     8     8 */
  	int                        caller_lineno;        /*    16     4 */

  	/* XXX 4 bytes hole, try to pack */

  	struct function_addrs *    function_addrs;       /*    24     8 */
  	size_t                     function_addrs_count; /*    32     8 */

  	/* size: 40, cachelines: 1, members: 5 */
  	/* sum members: 36, holes: 1, sum holes: 4 */
  	/* last cacheline: 40 bytes */
  };
  struct function_addrs {
  	uint64_t                   low;                  /*     0     8 */
  	uint64_t                   high;                 /*     8     8 */
  	struct function *          function;             /*    16     8 */

  	/* size: 24, cachelines: 1, members: 3 */
  	/* last cacheline: 24 bytes */
  };
  struct function_vector {
  	struct backtrace_vector    vec;                  /*     0    24 */
  	size_t                     count;                /*    24     8 */

  	/* size: 32, cachelines: 1, members: 2 */
  	/* last cacheline: 32 bytes */
  };
  struct unit {
  	const unsigned char  *     unit_data;            /*     0     8 */
  	size_t                     unit_data_len;        /*     8     8 */
  	size_t                     unit_data_offset;     /*    16     8 */
  	size_t                     low_offset;           /*    24     8 */
  	size_t                     high_offset;          /*    32     8 */
  	int                        version;              /*    40     4 */
  	int                        is_dwarf64;           /*    44     4 */
  	int                        addrsize;             /*    48     4 */

  	/* XXX 4 bytes hole, try to pack */

  	off_t                      lineoff;              /*    56     8 */
  	/* --- cacheline 1 boundary (64 bytes) --- */
  	uint64_t                   str_offsets_base;     /*    64     8 */
  	uint64_t                   addr_base;            /*    72     8 */
  	uint64_t                   rnglists_base;        /*    80     8 */
  	const char  *              filename;             /*    88     8 */
  	const char  *              comp_dir;             /*    96     8 */
  	const char  *              abs_filename;         /*   104     8 */
  	struct abbrevs             abbrevs;              /*   112    16 */
  	/* --- cacheline 2 boundary (128 bytes) --- */
  	struct line *              lines;                /*   128     8 */
  	size_t                     lines_count;          /*   136     8 */
  	struct function_addrs *    function_addrs;       /*   144     8 */
  	size_t                     function_addrs_count; /*   152     8 */

  	/* size: 160, cachelines: 3, members: 20 */
  	/* sum members: 156, holes: 1, sum holes: 4 */
  	/* last cacheline: 32 bytes */
  };
  struct unit_addrs {
  	uint64_t                   low;                  /*     0     8 */
  	uint64_t                   high;                 /*     8     8 */
  	struct unit *              u;                    /*    16     8 */

  	/* size: 24, cachelines: 1, members: 3 */
  	/* last cacheline: 24 bytes */
  };
  struct unit_addrs_vector {
  	struct backtrace_vector    vec;                  /*     0    24 */
  	size_t                     count;                /*    24     8 */

  	/* size: 32, cachelines: 1, members: 2 */
  	/* last cacheline: 32 bytes */
  };
  struct unit_vector {
  	struct backtrace_vector    vec;                  /*     0    24 */
  	size_t                     count;                /*    24     8 */

  	/* size: 32, cachelines: 1, members: 2 */
  	/* last cacheline: 32 bytes */
  };
  struct dwarf_data {
  	struct dwarf_data *        next;                 /*     0     8 */
  	struct dwarf_data *        altlink;              /*     8     8 */
  	uintptr_t                  base_address;         /*    16     8 */
  	struct unit_addrs *        addrs;                /*    24     8 */
  	size_t                     addrs_count;          /*    32     8 */
  	struct unit * *            units;                /*    40     8 */
  	size_t                     units_count;          /*    48     8 */
  	struct dwarf_sections      dwarf_sections;       /*    56   144 */
  	/* --- cacheline 3 boundary (192 bytes) was 8 bytes ago --- */
  	int                        is_bigendian;         /*   200     4 */

  	/* XXX 4 bytes hole, try to pack */

  	struct function_vector     fvec;                 /*   208    32 */

  	/* size: 240, cachelines: 4, members: 10 */
  	/* sum members: 236, holes: 1, sum holes: 4 */
  	/* last cacheline: 48 bytes */
  };
  struct pcrange {
  	uint64_t                   lowpc;                /*     0     8 */
  	int                        have_lowpc;           /*     8     4 */
  	int                        lowpc_is_addr_index;  /*    12     4 */
  	uint64_t                   highpc;               /*    16     8 */
  	int                        have_highpc;          /*    24     4 */
  	int                        highpc_is_relative;   /*    28     4 */
  	int                        highpc_is_addr_index; /*    32     4 */

  	/* XXX 4 bytes hole, try to pack */

  	uint64_t                   ranges;               /*    40     8 */
  	int                        have_ranges;          /*    48     4 */
  	int                        ranges_is_index;      /*    52     4 */

  	/* size: 56, cachelines: 1, members: 10 */
  	/* sum members: 52, holes: 1, sum holes: 4 */
  	/* last cacheline: 56 bytes */
  };
  struct stat64 {
  	__dev_t                    st_dev;               /*     0     8 */
  	__ino64_t                  st_ino;               /*     8     8 */
  	__nlink_t                  st_nlink;             /*    16     8 */
  	__mode_t                   st_mode;              /*    24     4 */
  	__uid_t                    st_uid;               /*    28     4 */
  	__gid_t                    st_gid;               /*    32     4 */
  	int                        __pad0;               /*    36     4 */
  	__dev_t                    st_rdev;              /*    40     8 */
  	__off_t                    st_size;              /*    48     8 */
  	__blksize_t                st_blksize;           /*    56     8 */
  	/* --- cacheline 1 boundary (64 bytes) --- */
  	__blkcnt64_t               st_blocks;            /*    64     8 */
  	struct timespec            st_atim;              /*    72    16 */
  	struct timespec            st_mtim;              /*    88    16 */
  	struct timespec            st_ctim;              /*   104    16 */
  	__syscall_slong_t          __glibc_reserved[3];  /*   120    24 */

  	/* size: 144, cachelines: 3, members: 15 */
  	/* last cacheline: 16 bytes */
  };

Reported-by: Tom de Vries
Bugtracker: #9 (comment)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
acmel added a commit that referenced this issue Sep 22, 2020
This was found in a ADA object, part of gdb's test suite, for now just
make the code a bit more robust when not finding a type for some struct
member, etc, which avoids segfaults and produces output from ADA
objects, but there are other problems to solve as this is a _type tag, I
need to provide some better support so that type resolution works.

  [foo.debug.gz](https://github.com/acmel/dwarves/files/5257332/foo.debug.gz)

  Foo.debug, an ada exec:
  ```
  $ ~/dwarves/build/pahole foo.debug
  die__process_unit: DW_TAG_subrange_type (0x21) @ <0x10b> not handled!
  die__process_unit: DW_TAG_subrange_type (0x21) @ <0x134> not handled!
  die__process_unit: DW_TAG_subrange_type (0x21) @ <0x148> not handled!
  die__process_class: DW_TAG_subrange_type (0x21) @ <0x201> not handled!
  Segmentation fault (core dumped)
  $

These are fixed, the warnings continue to be produced.

Reported-by: Tom de Vries
Bugtracker: #9 (comment)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
@vries
Copy link
Author

vries commented Sep 23, 2020

pkg.debug.gz

I retested with master, and there's just one segfault left :)

acmel added a commit that referenced this issue Sep 23, 2020
When die__process_tag() gets some tag it hasn't support for, it returns
the special zeroed 'unsupported_tag' struct tag pointer, but
die__process_class() wasn't handling that, assuming since it isn't NULL
that it is a valid 'struct tag' pointer and proceeded to try to use its
->priv area, b00m.

So catch that and print an "unsuported tag FOO" for that case, this
makes the code way more robust as any unsupported tag will not cause a
segfault, just a warning.

So, for the case in the Bugtracker tag below, we don't segfault instead
we show just that DW_TAG_variant_part isn't supported when found inside
a DW_TAG_structure_type (or DW_TAG_class_type) as is the case with ADA
95.

Reported-by: Tom de Vries
Bugtracker: #9 (comment)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
@acmel
Copy link
Owner

acmel commented Sep 23, 2020 via email

@vries
Copy link
Author

vries commented Sep 23, 2020

I retested with master, no segfaults anymore, so I think this could be closed.

@vries
Copy link
Author

vries commented Sep 23, 2020

We also need to support DW_TAG_subrange_type and DW_TAG_subprogram inside DW_TAG_enumeration (wow, appeared in a rust binary), also DW_TAG_variant_part (rust). Perhaps we should open github separate issues to track those things? If you could please do it, I'd appreciate.

I opened two issues on dwz support.

I don't feel capable though to file sensible issues on the missing support you mention above.

@acmel
Copy link
Owner

acmel commented Sep 23, 2020 via email

acmel pushed a commit that referenced this issue Apr 7, 2021
With latest bpf-next built with clang LTO (thin or full), I hit one test
failures:

  $ ./test_progs -t tcp
  ...
  libbpf: extern (func ksym) 'tcp_slow_start': func_proto [23] incompatible with kernel [115303]
  libbpf: failed to load object 'bpf_cubic'
  libbpf: failed to load BPF skeleton 'bpf_cubic': -22
  test_cubic:FAIL:bpf_cubic__open_and_load failed
  #9/2 cubic:FAIL
  ...

The reason of the failure is due to bpf program 'tcp_slow_start' func
signature is different from vmlinux BTF. bpf program uses the following
signature:

  extern __u32 tcp_slow_start(struct tcp_sock *tp, __u32 acked);

which is identical to the kernel definition in linux:include/net/tcp.h:

  u32 tcp_slow_start(struct tcp_sock *tp, u32 acked);

While vmlinux BTF definition like:

  [115303] FUNC_PROTO '(anon)' ret_type_id=0 vlen=2
          'tp' type_id=39373
          'acked' type_id=18
  [115304] FUNC 'tcp_slow_start' type_id=115303 linkage=static

The above is dumped with `bpftool btf dump file vmlinux`.

You can see the ret_type_id is 0 and this caused the problem.

Looking at dwarf, we have:

0x11f2ec67:   DW_TAG_subprogram
                DW_AT_low_pc    (0xffffffff81ed2330)
                DW_AT_high_pc   (0xffffffff81ed235c)
                DW_AT_frame_base        ()
                DW_AT_GNU_all_call_sites        (true)
                DW_AT_abstract_origin   (0x11f2ed66 "tcp_slow_start")
...
0x11f2ed66:   DW_TAG_subprogram
                DW_AT_name      ("tcp_slow_start")
                DW_AT_decl_file ("/home/yhs/work/bpf-next/net/ipv4/tcp_cong.c")
                DW_AT_decl_line (392)
                DW_AT_prototyped        (true)
                DW_AT_type      (0x11f130c2 "u32")
                DW_AT_external  (true)
                DW_AT_inline    (DW_INL_inlined)

We have a subprogram which has an abstract_origin pointing to the
subprogram prototype with return type. Current one pass recoding cannot
easily resolve this easily since at the time recoding for 0x11f2ec67,
the return type in 0x11f2ed66 has not been resolved.

To simplify implementation, I just added another pass to go through all
functions after recoding pass. This should resolve the above issue.

With this patch, among total 250999 functions in vmlinux, 4821 functions
needs return type adjustment from type id 0 to correct values. The above
failed bpf selftest passed too.

Committer testing:

Before:

  $ pfunct tcp_slow_start
  void tcp_slow_start(struct tcp_sock * tp, u32 acked);
  $
  $ pfunct --prototypes /sys/kernel/btf/vmlinux > before
  $ head before
  int fb_is_primary_device(struct fb_info * info);
  int arch_resume_nosmt(void);
  int relocate_restore_code(void);
  int arch_hibernation_header_restore(void * addr);
  int get_e820_md5(struct e820_table * table, void * buf);
  int arch_hibernation_header_save(void * addr, unsigned int max_size);
  int pfn_is_nosave(long unsigned int pfn);
  int swsusp_arch_resume(void);
  int amd_bus_cpu_online(unsigned int cpu);
  void pci_enable_pci_io_ecs(void);
  $

After:

  $ pfunct -F btf ../build/bpf_clang_thin_lto/vmlinux -f tcp_slow_start
  u32 tcp_slow_start(struct tcp_sock * tp, u32 acked);
  $
  $ pfunct -F btf --prototypes ../build/bpf_clang_thin_lto/vmlinux > after
  $
  $ head after
  int fb_is_primary_device(struct fb_info * info);
  int arch_resume_nosmt(void);
  int relocate_restore_code(void);
  int arch_hibernation_header_restore(void * addr);
  int get_e820_md5(struct e820_table * table, void * buf);
  int arch_hibernation_header_save(void * addr, unsigned int max_size);
  int pfn_is_nosave(long unsigned int pfn);
  int swsusp_arch_resume(void);
  int amd_bus_cpu_online(unsigned int cpu);
  void pci_enable_pci_io_ecs(void);
  $
  $ diff -u before after | grep ^+ | wc -l
  1604
  $

  $ diff -u before after | grep tcp_slow_start
  -void tcp_slow_start(struct tcp_sock * tp, u32 acked);
  +u32 tcp_slow_start(struct tcp_sock * tp, u32 acked);
  $
  $ diff -u before after | grep ^[+-] | head
  --- before	2021-04-02 11:35:15.578160795 -0300
  +++ after	2021-04-02 11:33:34.204847317 -0300
  -void set_bf_sort(const struct dmi_system_id  * d);
  +int set_bf_sort(const struct dmi_system_id  * d);
  -void raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 val);
  -void raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 * val);
  +int raw_pci_write(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 val);
  +int raw_pci_read(unsigned int domain, unsigned int bus, unsigned int devfn, int reg, int len, u32 * val);
  -void xen_find_device_domain_owner(struct pci_dev * dev);
  +int xen_find_device_domain_owner(struct pci_dev * dev);
  $

The same results are obtained if using /sys/kernel/btf/vmlinux after
rebooting with the kernel built from the ../build/bpf_clang_thin_lto/vmlinux
file used in the above 'after' examples.

Signed-off-by: Yonghong Song <yhs@fb.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: David Blaikie <dblaikie@gmail.com>
Link: https://lore.kernel.org/bpf/82dfd420-96f9-aedc-6cdc-bf20042455db@fb.com/
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Bill Wendling <morbo@google.com>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: bpf@vger.kernel.org
Cc: dwarves@vger.kernel.org
Cc: kernel-team@fb.com
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>
acmel added a commit that referenced this issue Jun 18, 2024
In cu__new() zalloc() is used defensively, and that helped catch this
problem where we assume that a cu us in the cus list of cu instances,
but that is not the case when we use cus__merge_and_process_cu(), for
instance when loading files created by clang with LTO, as reported by
Peter Jung and narrowed down by Nathan Chancellor.

If we use INIT_LIST_HEAD() in cu__new() to initialize cu->node, which is
what we do with other lists and nodes there, then the unconditional
removal using list_del_init() will be a no-op and removing something not
on the cus list of cu instances will not cause problems, just keep an
unconsistent cus->nr_entries field.

So lets just have this fix in first, keeping Nathan's Tested-by and then
do the a bit more involved fix of either adding that cu to the cus list
or checking at removal time if it is there.

  Program received signal SIGSEGV, Segmentation fault.
  0x00007ffff7f1e13e in __list_del (prev=0x0, next=0x0) at /home/acme/git/pahole/list.h:106
  106		next->prev = prev;
  (gdb) bt
  #0  0x00007ffff7f1e13e in __list_del (prev=0x0, next=0x0) at /home/acme/git/pahole/list.h:106
  #1  0x00007ffff7f1e176 in list_del_init (entry=0x417980) at /home/acme/git/pahole/list.h:165
  #2  0x00007ffff7f1f8f9 in __cus__remove (cus=0x4142a0, cu=0x417980) at /home/acme/git/pahole/dwarves.c:527
  #3  0x00007ffff7f1f92b in cus__remove (cus=0x4142a0, cu=0x417980) at /home/acme/git/pahole/dwarves.c:533
  #4  0x00007ffff7f3d01c in cus__finalize (cus=0x4142a0, cu=0x417980, conf=0x4133c0 <conf_load>, thr_data=0x0)
      at /home/acme/git/pahole/dwarf_loader.c:3040
  #5  0x00007ffff7f3e05c in cus__merge_and_process_cu (cus=0x4142a0, conf=0x4133c0 <conf_load>, mod=0x415cf0, dw=0x416110, elf=0x414380,
      filename=0x7fffffffe3f7 "cast_common.ko", build_id=0x416680 "\265D\371U\213\373u|\037\250\242\032\271\365⒜]y\023", build_id_len=20,
      type_dcu=0x0) at /home/acme/git/pahole/dwarf_loader.c:3482
  #6  0x00007ffff7f3e218 in cus__load_module (cus=0x4142a0, conf=0x4133c0 <conf_load>, mod=0x415cf0, dw=0x416110, elf=0x414380,
      filename=0x7fffffffe3f7 "cast_common.ko") at /home/acme/git/pahole/dwarf_loader.c:3521
  #7  0x00007ffff7f3e396 in cus__process_dwflmod (dwflmod=0x415cf0, userdata=0x415d00, name=0x415ea0 "cast_common.ko", base=65536,
      arg=0x7fffffffde40) at /home/acme/git/pahole/dwarf_loader.c:3581
  #8  0x00007ffff7eb4609 in dwfl_getmodules (dwfl=0x414300, callback=0x7ffff7f3e2ec <cus__process_dwflmod>, arg=0x7fffffffde40, offset=0)
      at ../libdwfl/dwfl_getmodules.c:86
  #9  0x00007ffff7f3e4c5 in cus__process_file (cus=0x4142a0, conf=0x4133c0 <conf_load>, fd=3, filename=0x7fffffffe3f7 "cast_common.ko")
      at /home/acme/git/pahole/dwarf_loader.c:3647
  #10 0x00007ffff7f3e5cd in dwarf__load_file (cus=0x4142a0, conf=0x4133c0 <conf_load>, filename=0x7fffffffe3f7 "cast_common.ko")
      at /home/acme/git/pahole/dwarf_loader.c:3684
  #11 0x00007ffff7f232df in cus__load_file (cus=0x4142a0, conf=0x4133c0 <conf_load>, filename=0x7fffffffe3f7 "cast_common.ko")
      at /home/acme/git/pahole/dwarves.c:2134
  #12 0x00007ffff7f23e8b in cus__load_files (cus=0x4142a0, conf=0x4133c0 <conf_load>, filenames=0x7fffffffe0f0)
      at /home/acme/git/pahole/dwarves.c:2637
  #13 0x000000000040aec0 in main (argc=2, argv=0x7fffffffe0e8) at /home/acme/git/pahole/pahole.c:3805
  (gdb) fr 1
  #1  0x00007ffff7f1e176 in list_del_init (entry=0x417980) at /home/acme/git/pahole/list.h:165
  165		__list_del(entry->prev, entry->next);
  (gdb) p entry
  $1 = (struct list_head *) 0x417980
  (gdb) p entry->next
  $2 = (struct list_head *) 0x0
  (gdb) p entry->prev
  $3 = (struct list_head *) 0x0

Closes: #53
Closes: https://gitlab.archlinux.org/archlinux/packaging/packages/pahole/-/issues/1
Tested-by: Nathan Chancellor <nathan@kernel.org>
Link: https://lore.kernel.org/all/20240617210810.GA1877676@thelio-3990X
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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

2 participants