Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
Alexandra Hájková | 35351989b8 | |
Michal Kolar | 2c9320f3f2 | |
Alexandra Hájková | 1bdd88c886 | |
Alexandra Hájková | 0713bd2398 | |
Bruno Larsen | 1f44109aba | |
Bruno Larsen | 037f6d3daf | |
Kevin Buettner | 362037ef22 | |
Kevin Buettner | 1ec1186541 | |
Kevin Buettner | 3f97ff0c4e | |
Kevin Buettner | 6c8ccd626a | |
Kevin Buettner | 1b63420306 | |
Kevin Buettner | d3addba400 | |
Kevin Buettner | 2c180147a2 | |
Keith Seitz | 204d69fb9c | |
Kevin Buettner | 48d9fd9979 | |
Kevin Buettner | 5106a72f71 | |
Kevin Buettner | e710edde2d |
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -1,4 +1,3 @@
|
|||
/binutils-gdb
|
||||
/gdb-libstdc++-v3-python-8.1.1-20180626.tar.xz
|
||||
/gdb-9.2.tar.xz
|
||||
/v2.0.2.tar.gz
|
||||
/v2.0.4.tar.gz
|
||||
/gdb-10.2.tar.xz
|
||||
|
|
|
@ -2,373 +2,300 @@
|
|||
#=fedora
|
||||
Patch001: gdb-6.3-rh-testversion-20041202.patch
|
||||
|
||||
# VLA (Fortran dynamic arrays) from Intel + archer-jankratochvil-vla tests.
|
||||
#=push
|
||||
Patch002: gdb-vla-intel-fortran-strides.patch
|
||||
|
||||
#=push
|
||||
Patch003: gdb-vla-intel-fortran-vla-strings.patch
|
||||
|
||||
#=push+jan
|
||||
Patch004: gdb-vla-intel-stringbt-fix.patch
|
||||
|
||||
# Add a wrapper script to GDB that implements pstack using the
|
||||
# --readnever option.
|
||||
#=push
|
||||
Patch005: gdb-6.3-gstack-20050411.patch
|
||||
|
||||
# VSYSCALL and PIE
|
||||
#=fedoratest
|
||||
Patch006: gdb-6.3-test-pie-20050107.patch
|
||||
|
||||
# Get selftest working with sep-debug-info
|
||||
#=fedoratest
|
||||
Patch007: gdb-6.3-test-self-20050110.patch
|
||||
Patch002: gdb-6.3-gstack-20050411.patch
|
||||
|
||||
# Test support of multiple destructors just like multiple constructors
|
||||
#=fedoratest
|
||||
Patch008: gdb-6.3-test-dtorfix-20050121.patch
|
||||
Patch003: gdb-6.3-test-dtorfix-20050121.patch
|
||||
|
||||
# Fix to support executable moving
|
||||
#=fedoratest
|
||||
Patch009: gdb-6.3-test-movedir-20050125.patch
|
||||
Patch004: gdb-6.3-test-movedir-20050125.patch
|
||||
|
||||
# Test sibling threads to set threaded watchpoints for x86 and x86-64
|
||||
#=fedoratest
|
||||
Patch010: gdb-6.3-threaded-watchpoints2-20050225.patch
|
||||
Patch005: gdb-6.3-threaded-watchpoints2-20050225.patch
|
||||
|
||||
# Notify observers that the inferior has been created
|
||||
#=fedoratest
|
||||
Patch011: gdb-6.3-inferior-notification-20050721.patch
|
||||
Patch006: gdb-6.3-inferior-notification-20050721.patch
|
||||
|
||||
# Verify printing of inherited members test
|
||||
#=fedoratest
|
||||
Patch012: gdb-6.3-inheritancetest-20050726.patch
|
||||
Patch007: gdb-6.3-inheritancetest-20050726.patch
|
||||
|
||||
# Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337).
|
||||
#=push+jan: It should be replaced by Infinity project.
|
||||
Patch013: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch
|
||||
Patch008: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch
|
||||
|
||||
# Fix TLS symbols resolving for shared libraries with a relative pathname.
|
||||
# The testsuite needs `gdb-6.5-tls-of-separate-debuginfo.patch'.
|
||||
#=fedoratest: One should recheck if it is really fixed upstream.
|
||||
Patch014: gdb-6.5-sharedlibrary-path.patch
|
||||
Patch009: gdb-6.5-sharedlibrary-path.patch
|
||||
|
||||
# Improved testsuite results by the testsuite provided by the courtesy of BEA.
|
||||
#=fedoratest: For upstream it should be rewritten as a dejagnu test, the test of no "??" was useful.
|
||||
Patch015: gdb-6.5-BEA-testsuite.patch
|
||||
Patch010: gdb-6.5-BEA-testsuite.patch
|
||||
|
||||
# Testcase for deadlocking on last address space byte; for corrupted backtraces.
|
||||
#=fedoratest
|
||||
Patch016: gdb-6.5-last-address-space-byte-test.patch
|
||||
Patch011: gdb-6.5-last-address-space-byte-test.patch
|
||||
|
||||
# Fix readline segfault on excessively long hand-typed lines.
|
||||
#=fedoratest
|
||||
Patch017: gdb-6.5-readline-long-line-crash-test.patch
|
||||
Patch012: gdb-6.5-readline-long-line-crash-test.patch
|
||||
|
||||
# Test sideeffects of skipping ppc .so libs trampolines (BZ 218379).
|
||||
#=fedoratest
|
||||
Patch018: gdb-6.5-bz218379-ppc-solib-trampoline-test.patch
|
||||
|
||||
# Fix lockup on trampoline vs. its function lookup; unreproducible (BZ 218379).
|
||||
#=fedora
|
||||
Patch019: gdb-6.5-bz218379-solib-trampoline-lookup-lock-fix.patch
|
||||
Patch013: gdb-6.5-bz218379-ppc-solib-trampoline-test.patch
|
||||
|
||||
# Find symbols properly at their original (included) file (BZ 109921).
|
||||
#=fedoratest
|
||||
Patch020: gdb-6.5-bz109921-DW_AT_decl_file-test.patch
|
||||
Patch014: gdb-6.5-bz109921-DW_AT_decl_file-test.patch
|
||||
|
||||
# Update PPC unwinding patches to their upstream variants (BZ 140532).
|
||||
#=fedoratest
|
||||
Patch021: gdb-6.3-bz140532-ppc-unwinding-test.patch
|
||||
Patch015: gdb-6.3-bz140532-ppc-unwinding-test.patch
|
||||
|
||||
# Testcase for exec() from threaded program (BZ 202689).
|
||||
#=fedoratest
|
||||
Patch022: gdb-6.3-bz202689-exec-from-pthread-test.patch
|
||||
Patch016: gdb-6.3-bz202689-exec-from-pthread-test.patch
|
||||
|
||||
# Testcase for PPC Power6/DFP instructions disassembly (BZ 230000).
|
||||
#=fedoratest
|
||||
Patch023: gdb-6.6-bz230000-power6-disassembly-test.patch
|
||||
Patch017: gdb-6.6-bz230000-power6-disassembly-test.patch
|
||||
|
||||
# Allow running `/usr/bin/gcore' with provided but inaccessible tty (BZ 229517).
|
||||
#=fedoratest
|
||||
Patch024: gdb-6.6-bz229517-gcore-without-terminal.patch
|
||||
Patch018: gdb-6.6-bz229517-gcore-without-terminal.patch
|
||||
|
||||
# Avoid too long timeouts on failing cases of "annota1.exp annota3.exp".
|
||||
#=fedoratest
|
||||
Patch025: gdb-6.6-testsuite-timeouts.patch
|
||||
Patch019: gdb-6.6-testsuite-timeouts.patch
|
||||
|
||||
# Support for stepping over PPC atomic instruction sequences (BZ 237572).
|
||||
#=fedoratest
|
||||
Patch026: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch
|
||||
Patch020: gdb-6.6-bz237572-ppc-atomic-sequence-test.patch
|
||||
|
||||
# Test kernel VDSO decoding while attaching to an i386 process.
|
||||
#=fedoratest
|
||||
Patch027: gdb-6.3-attach-see-vdso-test.patch
|
||||
Patch021: gdb-6.3-attach-see-vdso-test.patch
|
||||
|
||||
# Test leftover zombie process (BZ 243845).
|
||||
#=fedoratest
|
||||
Patch028: gdb-6.5-bz243845-stale-testing-zombie-test.patch
|
||||
Patch022: gdb-6.5-bz243845-stale-testing-zombie-test.patch
|
||||
|
||||
# New locating of the matching binaries from the pure core file (build-id).
|
||||
#=push+jan
|
||||
Patch029: gdb-6.6-buildid-locate.patch
|
||||
Patch023: gdb-6.6-buildid-locate.patch
|
||||
|
||||
# Fix loading of core files without build-ids but with build-ids in executables.
|
||||
# Load strictly build-id-checked core files only if no executable is specified
|
||||
# (Jan Kratochvil, RH BZ 1339862).
|
||||
#=push+jan
|
||||
Patch030: gdb-6.6-buildid-locate-solib-missing-ids.patch
|
||||
Patch024: gdb-6.6-buildid-locate-solib-missing-ids.patch
|
||||
|
||||
#=push+jan
|
||||
Patch031: gdb-6.6-buildid-locate-rpm.patch
|
||||
Patch025: gdb-6.6-buildid-locate-rpm.patch
|
||||
|
||||
# Fix displaying of numeric char arrays as strings (BZ 224128).
|
||||
#=fedoratest: But it is failing anyway, one should check the behavior more.
|
||||
Patch032: gdb-6.7-charsign-test.patch
|
||||
Patch026: gdb-6.7-charsign-test.patch
|
||||
|
||||
# Test PPC hiding of call-volatile parameter register.
|
||||
#=fedoratest
|
||||
Patch033: gdb-6.7-ppc-clobbered-registers-O2-test.patch
|
||||
Patch027: gdb-6.7-ppc-clobbered-registers-O2-test.patch
|
||||
|
||||
# Testsuite fixes for more stable/comparable results.
|
||||
#=fedoratest
|
||||
Patch034: gdb-6.7-testsuite-stable-results.patch
|
||||
Patch028: gdb-6.7-testsuite-stable-results.patch
|
||||
|
||||
# Test ia64 memory leaks of the code using libunwind.
|
||||
#=fedoratest
|
||||
Patch035: gdb-6.5-ia64-libunwind-leak-test.patch
|
||||
Patch029: gdb-6.5-ia64-libunwind-leak-test.patch
|
||||
|
||||
# Test hiding unexpected breakpoints on intentional step commands.
|
||||
#=fedoratest
|
||||
Patch036: gdb-6.5-missed-trap-on-step-test.patch
|
||||
Patch030: gdb-6.5-missed-trap-on-step-test.patch
|
||||
|
||||
# Test gcore memory and time requirements for large inferiors.
|
||||
#=fedoratest
|
||||
Patch037: gdb-6.5-gcore-buffer-limit-test.patch
|
||||
Patch031: gdb-6.5-gcore-buffer-limit-test.patch
|
||||
|
||||
# Test GCORE for shmid 0 shared memory mappings.
|
||||
#=fedoratest: But it is broken anyway, sometimes the case being tested is not reproducible.
|
||||
Patch038: gdb-6.3-mapping-zero-inode-test.patch
|
||||
Patch032: gdb-6.3-mapping-zero-inode-test.patch
|
||||
|
||||
# Test a crash on `focus cmd', `focus prev' commands.
|
||||
#=fedoratest
|
||||
Patch039: gdb-6.3-focus-cmd-prev-test.patch
|
||||
Patch033: gdb-6.3-focus-cmd-prev-test.patch
|
||||
|
||||
# Test various forms of threads tracking across exec() (BZ 442765).
|
||||
#=fedoratest
|
||||
Patch040: gdb-6.8-bz442765-threaded-exec-test.patch
|
||||
Patch034: gdb-6.8-bz442765-threaded-exec-test.patch
|
||||
|
||||
# Test a crash on libraries missing the .text section.
|
||||
#=fedoratest
|
||||
Patch041: gdb-6.5-section-num-fixup-test.patch
|
||||
Patch035: gdb-6.5-section-num-fixup-test.patch
|
||||
|
||||
# Fix resolving of variables at locations lists in prelinked libs (BZ 466901).
|
||||
#=fedoratest
|
||||
Patch042: gdb-6.8-bz466901-backtrace-full-prelinked.patch
|
||||
Patch036: gdb-6.8-bz466901-backtrace-full-prelinked.patch
|
||||
|
||||
# New test for step-resume breakpoint placed in multiple threads at once.
|
||||
#=fedoratest
|
||||
Patch043: gdb-simultaneous-step-resume-breakpoint-test.patch
|
||||
Patch037: gdb-simultaneous-step-resume-breakpoint-test.patch
|
||||
|
||||
# Fix GNU/Linux core open: Can't read pathname for load map: Input/output error.
|
||||
# Fix regression of undisplayed missing shared libraries caused by a fix for.
|
||||
#=fedoratest: It should be in glibc: libc-alpha: <20091004161706.GA27450@.*>
|
||||
Patch044: gdb-core-open-vdso-warning.patch
|
||||
|
||||
# Fix stepping with OMP parallel Fortran sections (BZ 533176).
|
||||
#=push+jan: It requires some better DWARF annotations.
|
||||
Patch045: gdb-bz533176-fortran-omp-step.patch
|
||||
Patch038: gdb-core-open-vdso-warning.patch
|
||||
|
||||
# Workaround ccache making lineno non-zero for command-line definitions.
|
||||
#=fedoratest: ccache is rarely used and it is even fixed now.
|
||||
Patch046: gdb-ccache-workaround.patch
|
||||
|
||||
#=push+jan: May get obsoleted by Tom's unrelocated objfiles patch.
|
||||
Patch047: gdb-archer-pie-addons.patch
|
||||
|
||||
#=push+jan: Breakpoints disabling matching should not be based on address.
|
||||
Patch048: gdb-archer-pie-addons-keep-disabled.patch
|
||||
Patch039: gdb-ccache-workaround.patch
|
||||
|
||||
# Testcase for "Do not make up line information" fix by Daniel Jacobowitz.
|
||||
#=fedoratest
|
||||
Patch049: gdb-lineno-makeup-test.patch
|
||||
Patch040: gdb-lineno-makeup-test.patch
|
||||
|
||||
# Test power7 ppc disassembly.
|
||||
#=fedoratest
|
||||
Patch050: gdb-ppc-power7-test.patch
|
||||
|
||||
# Workaround non-stop moribund locations exploited by kernel utrace (BZ 590623).
|
||||
#=push+jan: Currently it is still not fully safe.
|
||||
Patch051: gdb-moribund-utrace-workaround.patch
|
||||
Patch041: gdb-ppc-power7-test.patch
|
||||
|
||||
# Fix follow-exec for C++ programs (bugreported by Martin Stransky).
|
||||
#=fedoratest
|
||||
Patch052: gdb-archer-next-over-throw-cxx-exec.patch
|
||||
Patch042: gdb-archer-next-over-throw-cxx-exec.patch
|
||||
|
||||
# Backport DWARF-4 support (BZ 601887, Tom Tromey).
|
||||
#=fedoratest
|
||||
Patch053: gdb-bz601887-dwarf4-rh-test.patch
|
||||
|
||||
#=push+jan
|
||||
Patch054: gdb-6.6-buildid-locate-core-as-arg.patch
|
||||
Patch043: gdb-bz601887-dwarf4-rh-test.patch
|
||||
|
||||
# Workaround librpm BZ 643031 due to its unexpected exit() calls (BZ 642879).
|
||||
#=push+jan
|
||||
Patch055: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch
|
||||
Patch044: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch
|
||||
|
||||
# [delayed-symfile] Test a backtrace regression on CFIs without DIE (BZ 614604).
|
||||
#=fedoratest
|
||||
Patch056: gdb-test-bt-cfi-without-die.patch
|
||||
Patch045: gdb-test-bt-cfi-without-die.patch
|
||||
|
||||
# Verify GDB Python built-in function gdb.solib_address exists (BZ # 634108).
|
||||
#=fedoratest
|
||||
Patch057: gdb-bz634108-solib_address.patch
|
||||
Patch046: gdb-bz634108-solib_address.patch
|
||||
|
||||
# New test gdb.arch/x86_64-pid0-core.exp for kernel PID 0 cores (BZ 611435).
|
||||
#=fedoratest
|
||||
Patch058: gdb-test-pid0-core.patch
|
||||
Patch047: gdb-test-pid0-core.patch
|
||||
|
||||
# [archer-tromey-delayed-symfile] New test gdb.dwarf2/dw2-aranges.exp.
|
||||
#=fedoratest
|
||||
Patch059: gdb-test-dw2-aranges.patch
|
||||
Patch048: gdb-test-dw2-aranges.patch
|
||||
|
||||
# [archer-keiths-expr-cumulative+upstream] Import C++ testcases.
|
||||
#=fedoratest
|
||||
Patch060: gdb-test-expr-cumulative-archer.patch
|
||||
Patch049: gdb-test-expr-cumulative-archer.patch
|
||||
|
||||
# Fix regressions on C++ names resolving (PR 11734, PR 12273, Keith Seitz).
|
||||
#=fedoratest
|
||||
Patch061: gdb-physname-pr11734-test.patch
|
||||
Patch050: gdb-physname-pr11734-test.patch
|
||||
|
||||
# Fix regressions on C++ names resolving (PR 11734, PR 12273, Keith Seitz).
|
||||
#=fedoratest
|
||||
Patch062: gdb-physname-pr12273-test.patch
|
||||
Patch051: gdb-physname-pr12273-test.patch
|
||||
|
||||
# Test GDB opcodes/ disassembly of Intel Ivy Bridge instructions (BZ 696890).
|
||||
#=fedoratest
|
||||
Patch063: gdb-test-ivy-bridge.patch
|
||||
Patch052: gdb-test-ivy-bridge.patch
|
||||
|
||||
# Hack for proper PIE run of the testsuite.
|
||||
#=fedoratest
|
||||
Patch064: gdb-runtest-pie-override.patch
|
||||
|
||||
# Print reasons for failed attach/spawn incl. SELinux deny_ptrace (BZ 786878).
|
||||
#=push+jan
|
||||
Patch065: gdb-attach-fail-reasons-5of5.patch
|
||||
Patch053: gdb-runtest-pie-override.patch
|
||||
|
||||
# Workaround PR libc/14166 for inferior calls of strstr.
|
||||
#=fedoratest: Compatibility with RHELs (unchecked which ones).
|
||||
Patch066: gdb-glibc-strstr-workaround.patch
|
||||
Patch054: gdb-glibc-strstr-workaround.patch
|
||||
|
||||
# Include testcase for `Unable to see a variable inside a module (XLF)' (BZ 823789).
|
||||
#=fedoratest
|
||||
Patch067: gdb-rhel5.9-testcase-xlf-var-inside-mod.patch
|
||||
Patch055: gdb-rhel5.9-testcase-xlf-var-inside-mod.patch
|
||||
|
||||
# Testcase for `Setting solib-absolute-prefix breaks vDSO' (BZ 818343).
|
||||
#=fedoratest
|
||||
Patch068: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch
|
||||
Patch056: gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch
|
||||
|
||||
# Import regression test for `gdb/findvar.c:417: internal-error:
|
||||
# read_var_value: Assertion `frame' failed.' (RH BZ 947564) from RHEL 6.5.
|
||||
#=fedoratest
|
||||
Patch069: gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch
|
||||
|
||||
# Fix crash of -readnow /usr/lib/debug/usr/bin/gnatbind.debug (BZ 1069211).
|
||||
#=push+jan
|
||||
Patch070: gdb-gnat-dwarf-crash-3of3.patch
|
||||
Patch057: gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch
|
||||
|
||||
# Fix 'memory leak in infpy_read_memory()' (RH BZ 1007614)
|
||||
#=fedoratest
|
||||
Patch071: gdb-rhbz1007614-memleak-infpy_read_memory-test.patch
|
||||
Patch058: gdb-rhbz1007614-memleak-infpy_read_memory-test.patch
|
||||
|
||||
# Fix 'gdb gives highly misleading error when debuginfo pkg is present,
|
||||
# but not corresponding binary pkg' (RH BZ 981154).
|
||||
#=push+jan
|
||||
Patch072: gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch
|
||||
|
||||
#=fedoratest
|
||||
Patch073: gdb-archer-vla-tests.patch
|
||||
|
||||
#=fedoratest
|
||||
Patch074: gdb-vla-intel-tests.patch
|
||||
|
||||
# Continue backtrace even if a frame filter throws an exception (Phil Muldoon).
|
||||
#=push
|
||||
Patch075: gdb-btrobust.patch
|
||||
Patch059: gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch
|
||||
|
||||
# Display Fortran strings in backtraces.
|
||||
#=fedoratest
|
||||
Patch076: gdb-fortran-frame-string.patch
|
||||
Patch060: gdb-fortran-frame-string.patch
|
||||
|
||||
# Testcase for '[SAP] Recursive dlopen causes SAP HANA installer to
|
||||
# crash.' (RH BZ 1156192).
|
||||
#=fedoratest
|
||||
Patch077: gdb-rhbz1156192-recursive-dlopen-test.patch
|
||||
|
||||
# Fix jit-reader.h for multi-lib.
|
||||
#=push+jan
|
||||
Patch078: gdb-jit-reader-multilib.patch
|
||||
Patch061: gdb-rhbz1156192-recursive-dlopen-test.patch
|
||||
|
||||
# Fix '`catch syscall' doesn't work for parent after `fork' is called'
|
||||
# (Philippe Waroquiers, RH BZ 1149205).
|
||||
#=fedoratest
|
||||
Patch079: gdb-rhbz1149205-catch-syscall-after-fork-test.patch
|
||||
Patch062: gdb-rhbz1149205-catch-syscall-after-fork-test.patch
|
||||
|
||||
# Fix 'backport GDB 7.4 fix to RHEL 6.6 GDB' [Original Sourceware bug
|
||||
# description: 'C++ (and objc): Internal error on unqualified name
|
||||
# re-set', PR 11657] (RH BZ 1186476).
|
||||
#=fedoratest
|
||||
Patch080: gdb-rhbz1186476-internal-error-unqualified-name-re-set-test.patch
|
||||
Patch063: gdb-rhbz1186476-internal-error-unqualified-name-re-set-test.patch
|
||||
|
||||
# Test 'info type-printers' Python error (RH BZ 1350436).
|
||||
#=fedoratest
|
||||
Patch081: gdb-rhbz1350436-type-printers-error.patch
|
||||
Patch064: gdb-rhbz1350436-type-printers-error.patch
|
||||
|
||||
# Fix '[ppc64] and [s390x] wrong prologue skip on -O2 -g code' (Jan
|
||||
# Kratochvil, RH BZ 1084404).
|
||||
#=fedoratest
|
||||
Patch082: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
|
||||
|
||||
# Never kill PID on: gdb exec PID (Jan Kratochvil, RH BZ 1219747).
|
||||
#=push+jan
|
||||
Patch083: gdb-bz1219747-attach-kills.patch
|
||||
Patch065: gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
|
||||
|
||||
# Force libncursesw over libncurses to match the includes (RH BZ 1270534).
|
||||
#=push+jan
|
||||
Patch084: gdb-fedora-libncursesw.patch
|
||||
Patch066: gdb-fedora-libncursesw.patch
|
||||
|
||||
# Test clflushopt instruction decode (for RH BZ 1262471).
|
||||
#=fedoratest
|
||||
Patch085: gdb-opcodes-clflushopt-test.patch
|
||||
|
||||
# [rhel6] DTS backward Python compatibility API (BZ 1020004, Phil Muldoon).
|
||||
#=fedora
|
||||
Patch086: gdb-dts-rhel6-python-compat.patch
|
||||
Patch067: gdb-opcodes-clflushopt-test.patch
|
||||
|
||||
# [SCL] Skip deprecated .gdb_index warning for Red Hat built files (BZ 953585).
|
||||
#=push+jan
|
||||
Patch087: gdb-6.6-buildid-locate-rpm-scl.patch
|
||||
|
||||
# Make the GDB quit processing non-abortable to cleanup everything properly.
|
||||
#=fedora: It was useful only after gdb-6.8-attach-signalled-detach-stopped.patch .
|
||||
Patch088: gdb-6.8-quit-never-aborts.patch
|
||||
Patch068: gdb-6.6-buildid-locate-rpm-scl.patch
|
||||
|
||||
# [aarch64] Fix hardware watchpoints (RH BZ 1261564).
|
||||
#=fedoratest
|
||||
Patch089: gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch
|
||||
Patch069: gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch
|
||||
|
||||
# Add messages suggesting more recent RHEL gdbserver (RH BZ 1321114).
|
||||
#=fedora
|
||||
Patch090: gdb-container-rh-pkg.patch
|
||||
Patch070: gdb-container-rh-pkg.patch
|
||||
|
||||
# New test for Python "Cannot locate object file for block" (for RH BZ 1325795).
|
||||
#=fedoratest
|
||||
Patch091: gdb-rhbz1325795-framefilters-test.patch
|
||||
Patch071: gdb-rhbz1325795-framefilters-test.patch
|
||||
|
||||
# [dts+el7] [x86*] Bundle linux_perf.h for libipt (RH BZ 1256513).
|
||||
#=fedora
|
||||
Patch092: gdb-linux_perf-bundle.patch
|
||||
Patch072: gdb-linux_perf-bundle.patch
|
||||
|
||||
# Fix gdb-headless /usr/bin/ executables (BZ 1390251).
|
||||
#
|
||||
|
@ -377,38 +304,78 @@ Patch092: gdb-linux_perf-bundle.patch
|
|||
#
|
||||
# https://fedoraproject.org/wiki/Changes/Minimal_GDB_in_buildroot
|
||||
#=fedora
|
||||
Patch093: gdb-libexec-add-index.patch
|
||||
Patch073: gdb-libexec-add-index.patch
|
||||
|
||||
# New testcase for: Fix <tab>-completion crash (Gary Benson, RH BZ 1398387).
|
||||
#=fedoratest
|
||||
Patch094: gdb-rhbz1398387-tab-crash-test.patch
|
||||
|
||||
# Python patches of: http://sourceware.org/gdb/wiki/ProjectArcher
|
||||
#=push
|
||||
Patch095: gdb-archer.patch
|
||||
|
||||
# Revert upstream commit 469412dd9ccc4de5874fd3299b105833f36b34cd
|
||||
Patch096: gdb-vla-intel-fix-print-char-array.patch
|
||||
Patch074: gdb-rhbz1398387-tab-crash-test.patch
|
||||
|
||||
# [s390x] Backport arch12 instructions decoding (RH BZ 1553104).
|
||||
# =fedoratest
|
||||
Patch097: gdb-rhbz1553104-s390x-arch12-test.patch
|
||||
Patch075: gdb-rhbz1553104-s390x-arch12-test.patch
|
||||
|
||||
# Fix int conversion error from bfd/elf.c when compiling with gcc 10
|
||||
Patch098: gdb-rhbz1818011-bfd-gcc10-error.patch
|
||||
# Backport fix for frame_id_p assertion failure (RH BZ 1909902).
|
||||
Patch076: gdb-rhbz1909902-frame_id_p-assert-1.patch
|
||||
|
||||
# Backport fix for deprecation of PyEval_InitThreads in Python 3.9.
|
||||
Patch099: gdb-rhbz1822715-fix-python-deprecation.patch
|
||||
# Backport patch #2 which fixes a frame_id_p assertion failure (RH BZ 1909902).
|
||||
Patch077: gdb-rhbz1909902-frame_id_p-assert-2.patch
|
||||
|
||||
# Backport "Fix Python 3.9 related runtime problems"
|
||||
# Kevin Buettner <kevinb@redhat.com> and Keith Seitz <keiths@redhat.com>
|
||||
Patch100: gdb-rhbz1829702-fix-python39.patch
|
||||
# [fortran] Backport Andrew Burgess's commit which cleans up
|
||||
# array/string expression evaluation.
|
||||
Patch078: gdb-rhbz1964167-fortran-clean-up-array-expression-evaluation.patch
|
||||
|
||||
# Fix fput?_unfiltered functions
|
||||
# RH BZ 1844458 (Sergio Durigan Junior and Tom Tromey)
|
||||
Patch101: gdb-rhbz1844458-use-fputX_unfiltered.patch
|
||||
# [fortran] Backport Andrew Burgess's commit which moves Fortran
|
||||
# expression handling to f-lang.c.
|
||||
Patch079: gdb-rhbz1964167-move-fortran-expr-handling.patch
|
||||
|
||||
# Backport debuginofd support.
|
||||
# (Aaron Merey, RH BZ 183877)
|
||||
Patch102: gdb-rhbz1838777-debuginfod.patch
|
||||
# [fortran] Backport Andrew Burgess's commit which eliminates undesirable
|
||||
# whitespace when printing arrays.
|
||||
Patch080: gdb-rhbz1964167-fortran-whitespace_array.patch
|
||||
|
||||
# [fortran] Backport Andrew Burgess's commit which changes enum
|
||||
# range_type into a bit field enum.
|
||||
Patch081: gdb-rhbz1964167-convert-enum-range_type.patch
|
||||
|
||||
# [fortran] Backport Andrew Burgess's commit which renames enum
|
||||
# range_type to enum range_flag.
|
||||
Patch082: gdb-rhbz1964167-fortran-range_type-to-range_flag.patch
|
||||
|
||||
# [fortran] Backport Andrew Burgess's commit which adds support
|
||||
# for array strides in expressions.
|
||||
Patch083: gdb-rhbz1964167-fortran-array-strides-in-expressions.patch
|
||||
|
||||
# [fortran] Backport Andrew Burgess's commit for Fortran array
|
||||
# slice support
|
||||
Patch084: gdb-rhbz1964167-fortran-array-slices-at-prompt.patch
|
||||
|
||||
# [fortran] Backport Simon Marchi's commit which fixes a 32-bit build
|
||||
# problem in gdb/f-lang.c.
|
||||
Patch085: gdb-rhbz1964167-fortran-fix-type-format-mismatch-in-f-lang.c.patch
|
||||
|
||||
# Backport of "Exclude debuginfo files from 'outside of ELF segments'
|
||||
# warning" (Keith Seitz)
|
||||
Patch086: gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch
|
||||
|
||||
# Backport "Fix crash when expanding partial symtabs with DW_TAG_imported_unit"
|
||||
# (Tom Tromey, gdb/27743)
|
||||
Patch087: gdb-gdb27743-psymtab-imported-unit.patch
|
||||
|
||||
# Backport "[gdb/server] Don't overwrite fs/gs_base with -m32"
|
||||
# (Tom de Vries)
|
||||
Patch088: gdb-dont-overwrite-fsgsbase-m32.patch
|
||||
|
||||
#[gdb/cli] Don't assert on empty string for core-file
|
||||
#(Tom de Vries)
|
||||
Patch089: gdb-rhbz1916516-pathstuff.cc132-internal-error.patch
|
||||
|
||||
#[gdb] Improve early exits for env var in debuginfod-support.c
|
||||
#(Tom de Vries)
|
||||
Patch090: gdb-rhbz1970741-early-exit-for-empty-debuginfod-url.patch
|
||||
|
||||
#Backport upstream patch which fixes internal-error: Unexpected
|
||||
# type field location kind (RHBZ 1976887).
|
||||
Patch091: gdb-rhbz1976887-field-location-kind.patch
|
||||
|
||||
|
||||
Patch092: gdb-test-for-rhbz1976887.patch
|
||||
|
||||
|
|
|
@ -90,13 +90,3 @@
|
|||
%patch090 -p1
|
||||
%patch091 -p1
|
||||
%patch092 -p1
|
||||
%patch093 -p1
|
||||
%patch094 -p1
|
||||
%patch095 -p1
|
||||
%patch096 -p1
|
||||
%patch097 -p1
|
||||
%patch098 -p1
|
||||
%patch099 -p1
|
||||
%patch100 -p1
|
||||
%patch101 -p1
|
||||
%patch102 -p1
|
||||
|
|
|
@ -1 +1 @@
|
|||
e7fe0803b6427d3906e991bbb3b7fd2f0fd05e00
|
||||
ce35d7163e779b1321058b22f005c70ce1524b25
|
||||
|
|
44
_patch_order
44
_patch_order
|
@ -1,10 +1,5 @@
|
|||
gdb-6.3-rh-testversion-20041202.patch
|
||||
gdb-vla-intel-fortran-strides.patch
|
||||
gdb-vla-intel-fortran-vla-strings.patch
|
||||
gdb-vla-intel-stringbt-fix.patch
|
||||
gdb-6.3-gstack-20050411.patch
|
||||
gdb-6.3-test-pie-20050107.patch
|
||||
gdb-6.3-test-self-20050110.patch
|
||||
gdb-6.3-test-dtorfix-20050121.patch
|
||||
gdb-6.3-test-movedir-20050125.patch
|
||||
gdb-6.3-threaded-watchpoints2-20050225.patch
|
||||
|
@ -16,7 +11,6 @@ gdb-6.5-BEA-testsuite.patch
|
|||
gdb-6.5-last-address-space-byte-test.patch
|
||||
gdb-6.5-readline-long-line-crash-test.patch
|
||||
gdb-6.5-bz218379-ppc-solib-trampoline-test.patch
|
||||
gdb-6.5-bz218379-solib-trampoline-lookup-lock-fix.patch
|
||||
gdb-6.5-bz109921-DW_AT_decl_file-test.patch
|
||||
gdb-6.3-bz140532-ppc-unwinding-test.patch
|
||||
gdb-6.3-bz202689-exec-from-pthread-test.patch
|
||||
|
@ -42,16 +36,11 @@ gdb-6.5-section-num-fixup-test.patch
|
|||
gdb-6.8-bz466901-backtrace-full-prelinked.patch
|
||||
gdb-simultaneous-step-resume-breakpoint-test.patch
|
||||
gdb-core-open-vdso-warning.patch
|
||||
gdb-bz533176-fortran-omp-step.patch
|
||||
gdb-ccache-workaround.patch
|
||||
gdb-archer-pie-addons.patch
|
||||
gdb-archer-pie-addons-keep-disabled.patch
|
||||
gdb-lineno-makeup-test.patch
|
||||
gdb-ppc-power7-test.patch
|
||||
gdb-moribund-utrace-workaround.patch
|
||||
gdb-archer-next-over-throw-cxx-exec.patch
|
||||
gdb-bz601887-dwarf4-rh-test.patch
|
||||
gdb-6.6-buildid-locate-core-as-arg.patch
|
||||
gdb-6.6-buildid-locate-rpm-librpm-workaround.patch
|
||||
gdb-test-bt-cfi-without-die.patch
|
||||
gdb-bz634108-solib_address.patch
|
||||
|
@ -62,41 +51,42 @@ gdb-physname-pr11734-test.patch
|
|||
gdb-physname-pr12273-test.patch
|
||||
gdb-test-ivy-bridge.patch
|
||||
gdb-runtest-pie-override.patch
|
||||
gdb-attach-fail-reasons-5of5.patch
|
||||
gdb-glibc-strstr-workaround.patch
|
||||
gdb-rhel5.9-testcase-xlf-var-inside-mod.patch
|
||||
gdb-rhbz-818343-set-solib-absolute-prefix-testcase.patch
|
||||
gdb-rhbz947564-findvar-assertion-frame-failed-testcase.patch
|
||||
gdb-gnat-dwarf-crash-3of3.patch
|
||||
gdb-rhbz1007614-memleak-infpy_read_memory-test.patch
|
||||
gdb-6.6-buildid-locate-misleading-warning-missing-debuginfo-rhbz981154.patch
|
||||
gdb-archer-vla-tests.patch
|
||||
gdb-vla-intel-tests.patch
|
||||
gdb-btrobust.patch
|
||||
gdb-fortran-frame-string.patch
|
||||
gdb-rhbz1156192-recursive-dlopen-test.patch
|
||||
gdb-jit-reader-multilib.patch
|
||||
gdb-rhbz1149205-catch-syscall-after-fork-test.patch
|
||||
gdb-rhbz1186476-internal-error-unqualified-name-re-set-test.patch
|
||||
gdb-rhbz1350436-type-printers-error.patch
|
||||
gdb-rhbz1084404-ppc64-s390x-wrong-prologue-skip-O2-g-3of3.patch
|
||||
gdb-bz1219747-attach-kills.patch
|
||||
gdb-fedora-libncursesw.patch
|
||||
gdb-opcodes-clflushopt-test.patch
|
||||
gdb-dts-rhel6-python-compat.patch
|
||||
gdb-6.6-buildid-locate-rpm-scl.patch
|
||||
gdb-6.8-quit-never-aborts.patch
|
||||
gdb-rhbz1261564-aarch64-hw-watchpoint-test.patch
|
||||
gdb-container-rh-pkg.patch
|
||||
gdb-rhbz1325795-framefilters-test.patch
|
||||
gdb-linux_perf-bundle.patch
|
||||
gdb-libexec-add-index.patch
|
||||
gdb-rhbz1398387-tab-crash-test.patch
|
||||
gdb-archer.patch
|
||||
gdb-vla-intel-fix-print-char-array.patch
|
||||
gdb-rhbz1553104-s390x-arch12-test.patch
|
||||
gdb-rhbz1818011-bfd-gcc10-error.patch
|
||||
gdb-rhbz1822715-fix-python-deprecation.patch
|
||||
gdb-rhbz1829702-fix-python39.patch
|
||||
gdb-rhbz1844458-use-fputX_unfiltered.patch
|
||||
gdb-rhbz1838777-debuginfod.patch
|
||||
gdb-rhbz1909902-frame_id_p-assert-1.patch
|
||||
gdb-rhbz1909902-frame_id_p-assert-2.patch
|
||||
gdb-rhbz1964167-fortran-clean-up-array-expression-evaluation.patch
|
||||
gdb-rhbz1964167-move-fortran-expr-handling.patch
|
||||
gdb-rhbz1964167-fortran-whitespace_array.patch
|
||||
gdb-rhbz1964167-convert-enum-range_type.patch
|
||||
gdb-rhbz1964167-fortran-range_type-to-range_flag.patch
|
||||
gdb-rhbz1964167-fortran-array-strides-in-expressions.patch
|
||||
gdb-rhbz1964167-fortran-array-slices-at-prompt.patch
|
||||
gdb-rhbz1964167-fortran-fix-type-format-mismatch-in-f-lang.c.patch
|
||||
gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch
|
||||
gdb-gdb27743-psymtab-imported-unit.patch
|
||||
gdb-dont-overwrite-fsgsbase-m32.patch
|
||||
gdb-rhbz1916516-pathstuff.cc132-internal-error.patch
|
||||
gdb-rhbz1970741-early-exit-for-empty-debuginfod-url.patch
|
||||
gdb-rhbz1976887-field-location-kind.patch
|
||||
gdb-test-for-rhbz1976887.patch
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
--- !Policy
|
||||
product_versions:
|
||||
- fedora-*
|
||||
decision_context: bodhi_update_push_stable
|
||||
subject_type: koji_build
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
|
||||
- !PassingTestCaseRule {test_case_name: baseos-qe.koji-build.scratch-build.validation}
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-8
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-9
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
|
@ -16,7 +16,7 @@ Subject: gdb-6.3-gstack-20050411.patch
|
|||
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
|
||||
--- a/gdb/Makefile.in
|
||||
+++ b/gdb/Makefile.in
|
||||
@@ -1768,7 +1768,7 @@ info install-info clean-info dvi pdf install-pdf html install-html: force
|
||||
@@ -1726,7 +1726,7 @@ info install-info clean-info dvi pdf install-pdf html install-html: force
|
||||
install: all
|
||||
@$(MAKE) $(FLAGS_TO_PASS) install-only
|
||||
|
||||
|
@ -25,7 +25,7 @@ diff --git a/gdb/Makefile.in b/gdb/Makefile.in
|
|||
transformed_name=`t='$(program_transform_name)'; \
|
||||
echo gdb | sed -e "$$t"` ; \
|
||||
if test "x$$transformed_name" = x; then \
|
||||
@@ -1817,7 +1817,25 @@ install-guile:
|
||||
@@ -1775,7 +1775,25 @@ install-guile:
|
||||
install-python:
|
||||
$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb
|
||||
|
||||
|
@ -52,7 +52,7 @@ diff --git a/gdb/Makefile.in b/gdb/Makefile.in
|
|||
transformed_name=`t='$(program_transform_name)'; \
|
||||
echo gdb | sed -e $$t` ; \
|
||||
if test "x$$transformed_name" = x; then \
|
||||
@@ -1840,6 +1858,18 @@ uninstall: force $(CONFIG_UNINSTALL)
|
||||
@@ -1798,6 +1816,18 @@ uninstall: force $(CONFIG_UNINSTALL)
|
||||
fi
|
||||
@$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest
|
|||
diff --git a/gdb/top.c b/gdb/top.c
|
||||
--- a/gdb/top.c
|
||||
+++ b/gdb/top.c
|
||||
@@ -2096,7 +2096,7 @@ init_gdb_version_vars (void)
|
||||
@@ -2163,7 +2163,7 @@ init_gdb_version_vars (void)
|
||||
struct internalvar *major_version_var = create_internalvar ("_gdb_major");
|
||||
struct internalvar *minor_version_var = create_internalvar ("_gdb_minor");
|
||||
int vmajor = 0, vminor = 0, vrevision = 0;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,42 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Elena Zannoni <ezannoni@redhat.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-6.3-test-self-20050110.patch
|
||||
|
||||
;; Get selftest working with sep-debug-info
|
||||
;;=fedoratest
|
||||
|
||||
2004-02-23 Elena Zannoni <ezannoni@redhat.com>
|
||||
|
||||
* gdb.gdb/selftest.exp: Make sure that the debug directory is
|
||||
set up properly.
|
||||
* gdb.gdb/complaints.exp: Ditto.
|
||||
* gdb.gdb/xfullpath.exp: Ditto.
|
||||
* gdb.gdb/observer.exp: Ditto.
|
||||
|
||||
diff --git a/gdb/testsuite/lib/selftest-support.exp b/gdb/testsuite/lib/selftest-support.exp
|
||||
--- a/gdb/testsuite/lib/selftest-support.exp
|
||||
+++ b/gdb/testsuite/lib/selftest-support.exp
|
||||
@@ -151,18 +151,18 @@ proc do_self_tests {function body} {
|
||||
}
|
||||
|
||||
# Remove any old copy lying around.
|
||||
- remote_file host delete $xgdb
|
||||
+ #remote_file host delete $xgdb
|
||||
|
||||
gdb_start
|
||||
- set file [remote_download host $GDB_FULLPATH $xgdb]
|
||||
+ #set file [remote_download host $GDB_FULLPATH $xgdb]
|
||||
|
||||
- set result [selftest_setup $file $function]
|
||||
+ set result [selftest_setup $GDB_FULLPATH $function]
|
||||
if {$result == 0} then {
|
||||
set result [uplevel $body]
|
||||
}
|
||||
|
||||
gdb_exit
|
||||
- catch "remote_file host delete $file"
|
||||
+ #catch "remote_file host delete $file"
|
||||
|
||||
if {$result < 0} then {
|
||||
warning "Couldn't test self"
|
|
@ -44,7 +44,7 @@ glibc-debuginfo-2.7-2.x86_64: /usr/lib/debug/lib64/libc.so.6.debug:
|
|||
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
|
||||
--- a/gdb/printcmd.c
|
||||
+++ b/gdb/printcmd.c
|
||||
@@ -1214,6 +1214,10 @@ print_command_1 (const char *args, int voidprint)
|
||||
@@ -1210,6 +1210,10 @@ print_command_1 (const char *args, int voidprint)
|
||||
|
||||
if (exp != nullptr && *exp)
|
||||
{
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-6.5-bz218379-solib-trampoline-lookup-lock-fix.patch
|
||||
|
||||
;; Fix lockup on trampoline vs. its function lookup; unreproducible (BZ 218379).
|
||||
;;=fedora
|
||||
|
||||
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=218379
|
||||
|
||||
diff --git a/gdb/symtab.c b/gdb/symtab.c
|
||||
--- a/gdb/symtab.c
|
||||
+++ b/gdb/symtab.c
|
||||
@@ -3166,6 +3166,13 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent)
|
||||
msymbol->linkage_name ()); */
|
||||
;
|
||||
/* fall through */
|
||||
+ /* `msymbol' trampoline may be located before its .text symbol
|
||||
+ but this text symbol may be the address we were looking for.
|
||||
+ Avoid `find_pc_sect_line'<->`find_pc_line' infinite loop.
|
||||
+ Red Hat Bug 218379. */
|
||||
+ else if (BMSYMBOL_VALUE_ADDRESS (mfunsym) == pc)
|
||||
+ warning ("In stub for %s (0x%s); interlocked, please submit the binary to http://bugzilla.redhat.com", msymbol.minsym->linkage_name (), paddress (target_gdbarch (), pc));
|
||||
+ /* fall through */
|
||||
else
|
||||
return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0);
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-6.6-buildid-locate-core-as-arg.patch
|
||||
|
||||
;;=push+jan
|
||||
|
||||
http://sourceware.org/ml/gdb-patches/2010-01/msg00558.html
|
||||
|
||||
[ Fixed up since the mail. ]
|
||||
|
||||
On Thu, 21 Jan 2010 18:17:15 +0100, Doug Evans wrote:
|
||||
> Not an exhaustive list, but if we go down the path of converting "gdb
|
||||
> corefile" to "gdb -c corefile", then we also need to think about "file
|
||||
> corefile" being converted to "core corefile" [or "target core
|
||||
> corefile", "core" is apparently deprecated in favor of "target core"]
|
||||
> and "target exec corefile" -> "target core corefile". Presumably
|
||||
> "file corefile" (and "target exec corefile") would discard the
|
||||
> currently selected executable. But maybe not. Will that be confusing
|
||||
> for users? I don't know.
|
||||
|
||||
While thinking about it overriding some GDB _commands_ was not my intention.
|
||||
|
||||
There is a general assumption if I have a shell COMMAND and some FILE I can do
|
||||
$ COMMAND FILE
|
||||
and COMMAND will appropriately load the FILE.
|
||||
|
||||
FSF GDB currently needs to specify also the executable file for core files
|
||||
which already inhibits this intuitive expectation. OTOH with the build-id
|
||||
locating patch which could allow such intuitive start notneeding the
|
||||
executable file. Still it currently did not work due to the required "-c":
|
||||
$ COMMAND -c COREFILE
|
||||
|
||||
Entering "file", "core-file" or "attach" commands is already explicit enough
|
||||
so that it IMO should do what the command name says without any
|
||||
autodetections. The second command line argument
|
||||
(captured_main->pid_or_core_arg) is also autodetected (for PID or CORE) but
|
||||
neither "attach" accepts a core file nor "core-file" accepts a PID.
|
||||
|
||||
The patch makes sense only with the build-id patchset so this is not submit
|
||||
for FSF GDB inclusion yet. I am fine with your patch (+/- Hui Zhu's pending
|
||||
bfd_check_format_matches) as the patch below is its natural extension.
|
||||
|
||||
Sorry for the delay,
|
||||
Jan
|
||||
|
||||
2010-01-25 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* exceptions.h (enum errors <IS_CORE_ERROR>): New.
|
||||
* exec.c: Include exceptions.h.
|
||||
(exec_file_attach <bfd_core>): Call throw_error (IS_CORE_ERROR, ...).
|
||||
* main.c (exec_or_core_file_attach): New.
|
||||
(captured_main <optind < argc>): Set also corearg.
|
||||
(captured_main <strcmp (execarg, symarg) == 0>): New variable func.
|
||||
Call exec_or_core_file_attach if COREARG matches EXECARG. Call
|
||||
symbol_file_add_main only if CORE_BFD remained NULL.
|
||||
|
||||
Http://sourceware.org/ml/gdb-patches/2010-01/msg00517.html
|
||||
2010-01-20 Doug Evans <dje@google.com>
|
||||
|
||||
* exec.c (exec_file_attach): Print a more useful error message if the
|
||||
user did "gdb core".
|
||||
|
||||
diff --git a/gdb/exec.c b/gdb/exec.c
|
||||
--- a/gdb/exec.c
|
||||
+++ b/gdb/exec.c
|
||||
@@ -18,6 +18,8 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "defs.h"
|
||||
+#include "arch-utils.h"
|
||||
+#include "exceptions.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "target.h"
|
||||
@@ -345,12 +347,27 @@ exec_file_attach (const char *filename, int from_tty)
|
||||
|
||||
if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
|
||||
{
|
||||
+ int is_core;
|
||||
+
|
||||
+ /* If the user accidentally did "gdb core", print a useful
|
||||
+ error message. Check it only after bfd_object has been checked as
|
||||
+ a valid executable may get recognized for example also as
|
||||
+ "trad-core". */
|
||||
+ is_core = bfd_check_format (exec_bfd, bfd_core);
|
||||
+
|
||||
/* Make sure to close exec_bfd, or else "run" might try to use
|
||||
it. */
|
||||
exec_close ();
|
||||
- error (_("\"%s\": not in executable format: %s"),
|
||||
- scratch_pathname,
|
||||
- gdb_bfd_errmsg (bfd_get_error (), matching).c_str ());
|
||||
+
|
||||
+ if (is_core != 0)
|
||||
+ throw_error (IS_CORE_ERROR,
|
||||
+ _("\"%s\" is a core file.\n"
|
||||
+ "Please specify an executable to debug."),
|
||||
+ scratch_pathname);
|
||||
+ else
|
||||
+ error (_("\"%ss\": not in executable format: %s"),
|
||||
+ scratch_pathname,
|
||||
+ gdb_bfd_errmsg (bfd_get_error (), matching).c_str ());
|
||||
}
|
||||
|
||||
if (build_section_table (exec_bfd, §ions, §ions_end))
|
||||
diff --git a/gdb/gdbsupport/common-exceptions.h b/gdb/gdbsupport/common-exceptions.h
|
||||
--- a/gdb/gdbsupport/common-exceptions.h
|
||||
+++ b/gdb/gdbsupport/common-exceptions.h
|
||||
@@ -106,6 +106,9 @@ enum errors {
|
||||
"_ERROR" is appended to the name. */
|
||||
MAX_COMPLETIONS_REACHED_ERROR,
|
||||
|
||||
+ /* Attempt to load a core file as executable. */
|
||||
+ IS_CORE_ERROR,
|
||||
+
|
||||
/* Add more errors here. */
|
||||
NR_ERRORS
|
||||
};
|
||||
diff --git a/gdb/main.c b/gdb/main.c
|
||||
--- a/gdb/main.c
|
||||
+++ b/gdb/main.c
|
||||
@@ -467,6 +467,34 @@ struct cmdarg
|
||||
char *string;
|
||||
};
|
||||
|
||||
+/* Call exec_file_attach. If it detected FILENAME is a core file call
|
||||
+ core_file_command. Print the original exec_file_attach error only if
|
||||
+ core_file_command failed to find a matching executable. */
|
||||
+
|
||||
+static void
|
||||
+exec_or_core_file_attach (const char *filename, int from_tty)
|
||||
+{
|
||||
+ gdb_assert (exec_bfd == NULL);
|
||||
+
|
||||
+ try
|
||||
+ {
|
||||
+ exec_file_attach (filename, from_tty);
|
||||
+ }
|
||||
+ catch (gdb_exception_error &e)
|
||||
+ {
|
||||
+ if (e.error == IS_CORE_ERROR)
|
||||
+ {
|
||||
+ core_file_command ((char *) filename, from_tty);
|
||||
+
|
||||
+ /* Iff the core file found its executable suppress the error message
|
||||
+ from exec_file_attach. */
|
||||
+ if (exec_bfd != NULL)
|
||||
+ return;
|
||||
+ }
|
||||
+ throw_exception (std::move (e));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
captured_main_1 (struct captured_main_args *context)
|
||||
{
|
||||
@@ -907,6 +935,8 @@ captured_main_1 (struct captured_main_args *context)
|
||||
{
|
||||
symarg = argv[optind];
|
||||
execarg = argv[optind];
|
||||
+ if (optind + 1 == argc && corearg == NULL)
|
||||
+ corearg = argv[optind];
|
||||
optind++;
|
||||
}
|
||||
|
||||
@@ -1063,12 +1093,25 @@ captured_main_1 (struct captured_main_args *context)
|
||||
&& symarg != NULL
|
||||
&& strcmp (execarg, symarg) == 0)
|
||||
{
|
||||
+ catch_command_errors_const_ftype *func;
|
||||
+
|
||||
+ /* Call exec_or_core_file_attach only if the file was specified as
|
||||
+ a command line argument (and not an a command line option). */
|
||||
+ if (corearg != NULL && strcmp (corearg, execarg) == 0)
|
||||
+ {
|
||||
+ func = exec_or_core_file_attach;
|
||||
+ corearg = NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ func = exec_file_attach;
|
||||
+
|
||||
/* The exec file and the symbol-file are the same. If we can't
|
||||
open it, better only print one error message.
|
||||
- catch_command_errors returns non-zero on success! */
|
||||
- ret = catch_command_errors (exec_file_attach, execarg,
|
||||
- !batch_flag);
|
||||
- if (ret != 0)
|
||||
+ catch_command_errors returns non-zero on success!
|
||||
+ Do not load EXECARG as a symbol file if it has been already processed
|
||||
+ as a core file. */
|
||||
+ ret = catch_command_errors (func, execarg, !batch_flag);
|
||||
+ if (ret != 0 && core_bfd == NULL)
|
||||
ret = catch_command_errors (symbol_file_add_main_adapter,
|
||||
symarg, !batch_flag);
|
||||
}
|
|
@ -9,7 +9,7 @@ Subject: gdb-6.6-buildid-locate-rpm-librpm-workaround.patch
|
|||
diff --git a/gdb/build-id.c b/gdb/build-id.c
|
||||
--- a/gdb/build-id.c
|
||||
+++ b/gdb/build-id.c
|
||||
@@ -709,6 +709,19 @@ build_id_to_filename (const struct bfd_build_id *build_id, char **link_return)
|
||||
@@ -708,6 +708,19 @@ build_id_to_filename (const struct bfd_build_id *build_id, char **link_return)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=953585
|
|||
diff --git a/gdb/build-id.c b/gdb/build-id.c
|
||||
--- a/gdb/build-id.c
|
||||
+++ b/gdb/build-id.c
|
||||
@@ -743,7 +743,11 @@ static int missing_rpm_list_entries;
|
||||
@@ -742,7 +742,11 @@ static int missing_rpm_list_entries;
|
||||
/* Returns the count of newly added rpms. */
|
||||
|
||||
static int
|
||||
|
@ -24,7 +24,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
{
|
||||
static int rpm_init_done = 0;
|
||||
rpmts ts;
|
||||
@@ -850,7 +854,11 @@ missing_rpm_enlist (const char *filename)
|
||||
@@ -849,7 +853,11 @@ missing_rpm_enlist (const char *filename)
|
||||
mi = rpmtsInitIterator_p (ts, RPMTAG_BASENAMES, filename, 0);
|
||||
if (mi != NULL)
|
||||
{
|
||||
|
@ -36,7 +36,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
{
|
||||
Header h;
|
||||
char *debuginfo, **slot, *s, *s2;
|
||||
@@ -968,6 +976,37 @@ missing_rpm_enlist (const char *filename)
|
||||
@@ -967,6 +975,37 @@ missing_rpm_enlist (const char *filename)
|
||||
xfree (debuginfo);
|
||||
count++;
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
|
||||
rpmdbFreeIterator_p (mi);
|
||||
}
|
||||
@@ -977,6 +1016,20 @@ missing_rpm_enlist (const char *filename)
|
||||
@@ -976,6 +1015,20 @@ missing_rpm_enlist (const char *filename)
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -95,10 +95,10 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
static bool
|
||||
missing_rpm_list_compar (const char *ap, const char *bp)
|
||||
{
|
||||
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
|
||||
--- a/gdb/dwarf2read.c
|
||||
+++ b/gdb/dwarf2read.c
|
||||
@@ -3497,6 +3497,16 @@ read_gdb_index_from_buffer (struct objfile *objfile,
|
||||
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
|
||||
--- a/gdb/dwarf2/read.c
|
||||
+++ b/gdb/dwarf2/read.c
|
||||
@@ -3034,6 +3034,16 @@ read_gdb_index_from_buffer (const char *filename,
|
||||
"set use-deprecated-index-sections on". */
|
||||
if (version < 6 && !deprecated_ok)
|
||||
{
|
||||
|
@ -115,7 +115,7 @@ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
|
|||
static int warning_printed = 0;
|
||||
if (!warning_printed)
|
||||
{
|
||||
@@ -3508,6 +3518,10 @@ to use the section anyway."),
|
||||
@@ -3045,6 +3055,10 @@ to use the section anyway."),
|
||||
warning_printed = 1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -240,10 +240,10 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
#include "gdbcmd.h"
|
||||
#include "gdbcore.h"
|
||||
+#include "inferior.h"
|
||||
#include "libbfd.h"
|
||||
#include "objfiles.h"
|
||||
#include "observable.h"
|
||||
@@ -698,8 +699,374 @@ build_id_to_filename (const struct bfd_build_id *build_id, char **link_return)
|
||||
#include "symfile.h"
|
||||
@@ -697,8 +698,374 @@ build_id_to_filename (const struct bfd_build_id *build_id, char **link_return)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -619,7 +619,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
avoidance. */
|
||||
|
||||
struct missing_filepair
|
||||
@@ -753,11 +1120,17 @@ missing_filepair_change (void)
|
||||
@@ -752,11 +1119,17 @@ missing_filepair_change (void)
|
||||
/* All their memory came just from missing_filepair_OBSTACK. */
|
||||
missing_filepair_hash = NULL;
|
||||
}
|
||||
|
@ -637,7 +637,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
missing_filepair_change ();
|
||||
}
|
||||
|
||||
@@ -824,14 +1197,38 @@ debug_print_missing (const char *binary, const char *debug)
|
||||
@@ -823,14 +1196,38 @@ debug_print_missing (const char *binary, const char *debug)
|
||||
|
||||
*slot = missing_filepair;
|
||||
|
||||
|
@ -678,7 +678,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
+#else
|
||||
+ "yum"
|
||||
+#endif
|
||||
+ " --enablerepo='*debug*' install", debug);
|
||||
+ " debuginfo-install", debug);
|
||||
+ }
|
||||
}
|
||||
|
||||
|
@ -686,9 +686,9 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
diff --git a/gdb/config.in b/gdb/config.in
|
||||
--- a/gdb/config.in
|
||||
+++ b/gdb/config.in
|
||||
@@ -36,6 +36,9 @@
|
||||
/* Define to BFD's default target vector. */
|
||||
#undef DEFAULT_BFD_VEC
|
||||
@@ -39,6 +39,9 @@
|
||||
/* Handle .ctf type-info sections */
|
||||
#undef ENABLE_LIBCTF
|
||||
|
||||
+/* librpm version specific library name to dlopen. */
|
||||
+#undef DLOPEN_LIBRPM
|
||||
|
@ -696,7 +696,7 @@ diff --git a/gdb/config.in b/gdb/config.in
|
|||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
#undef ENABLE_NLS
|
||||
@@ -245,6 +248,9 @@
|
||||
@@ -247,6 +250,9 @@
|
||||
/* Define if you have the mpfr library. */
|
||||
#undef HAVE_LIBMPFR
|
||||
|
||||
|
@ -709,7 +709,7 @@ diff --git a/gdb/config.in b/gdb/config.in
|
|||
diff --git a/gdb/configure b/gdb/configure
|
||||
--- a/gdb/configure
|
||||
+++ b/gdb/configure
|
||||
@@ -761,6 +761,11 @@ CODESIGN_CERT
|
||||
@@ -769,6 +769,11 @@ PKG_CONFIG
|
||||
HAVE_NATIVE_GCORE_TARGET
|
||||
TARGET_OBS
|
||||
subdirs
|
||||
|
@ -721,7 +721,7 @@ diff --git a/gdb/configure b/gdb/configure
|
|||
GDB_DATADIR
|
||||
DEBUGDIR
|
||||
MAKEINFO_EXTRA_FLAGS
|
||||
@@ -864,6 +869,7 @@ with_gdb_datadir
|
||||
@@ -873,6 +878,7 @@ with_gdb_datadir
|
||||
with_relocated_sources
|
||||
with_auto_load_dir
|
||||
with_auto_load_safe_path
|
||||
|
@ -729,42 +729,34 @@ diff --git a/gdb/configure b/gdb/configure
|
|||
enable_targets
|
||||
enable_64_bit_bfd
|
||||
enable_gdbmi
|
||||
@@ -926,6 +932,11 @@ CCC
|
||||
CPP
|
||||
MAKEINFO
|
||||
MAKEINFOFLAGS
|
||||
+PKG_CONFIG
|
||||
+PKG_CONFIG_PATH
|
||||
+PKG_CONFIG_LIBDIR
|
||||
@@ -949,6 +955,8 @@ PKG_CONFIG_PATH
|
||||
PKG_CONFIG_LIBDIR
|
||||
DEBUGINFOD_CFLAGS
|
||||
DEBUGINFOD_LIBS
|
||||
+RPM_CFLAGS
|
||||
+RPM_LIBS
|
||||
YACC
|
||||
YFLAGS
|
||||
XMKMF'
|
||||
@@ -1598,6 +1609,8 @@ Optional Packages:
|
||||
[--with-auto-load-dir]
|
||||
--without-auto-load-safe-path
|
||||
@@ -1621,6 +1629,8 @@ Optional Packages:
|
||||
do not restrict auto-loaded files locations
|
||||
--with-debuginfod Enable debuginfo lookups with debuginfod
|
||||
(auto/yes/no)
|
||||
+ --with-rpm query rpm database for missing debuginfos (yes/no,
|
||||
+ def. auto=librpm.so)
|
||||
--with-libunwind-ia64 use libunwind frame unwinding for ia64 targets
|
||||
--with-curses use the curses library instead of the termcap
|
||||
library
|
||||
@@ -1661,6 +1674,13 @@ Some influential environment variables:
|
||||
MAKEINFO Parent configure detects if it is of sufficient version.
|
||||
MAKEINFOFLAGS
|
||||
Parameters for MAKEINFO.
|
||||
+ PKG_CONFIG path to pkg-config utility
|
||||
+ PKG_CONFIG_PATH
|
||||
+ directories to add to pkg-config's search path
|
||||
+ PKG_CONFIG_LIBDIR
|
||||
+ path overriding pkg-config's built-in search path
|
||||
@@ -1702,6 +1712,8 @@ Some influential environment variables:
|
||||
C compiler flags for DEBUGINFOD, overriding pkg-config
|
||||
DEBUGINFOD_LIBS
|
||||
linker flags for DEBUGINFOD, overriding pkg-config
|
||||
+ RPM_CFLAGS C compiler flags for RPM, overriding pkg-config
|
||||
+ RPM_LIBS linker flags for RPM, overriding pkg-config
|
||||
YACC The `Yet Another Compiler Compiler' implementation to use.
|
||||
Defaults to the first program found out of: `bison -y', `byacc',
|
||||
`yacc'.
|
||||
@@ -6587,6 +6607,494 @@ _ACEOF
|
||||
@@ -6666,6 +6678,494 @@ _ACEOF
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_auto_load_safe_path" >&5
|
||||
$as_echo "$with_auto_load_safe_path" >&6; }
|
||||
|
||||
|
@ -1262,7 +1254,7 @@ diff --git a/gdb/configure b/gdb/configure
|
|||
diff --git a/gdb/configure.ac b/gdb/configure.ac
|
||||
--- a/gdb/configure.ac
|
||||
+++ b/gdb/configure.ac
|
||||
@@ -144,6 +144,199 @@ AC_DEFINE_DIR(AUTO_LOAD_SAFE_PATH, escape_dir,
|
||||
@@ -143,6 +143,199 @@ AC_DEFINE_DIR(AUTO_LOAD_SAFE_PATH, escape_dir,
|
||||
[Directories safe to hold auto-loaded files.])
|
||||
AC_MSG_RESULT([$with_auto_load_safe_path])
|
||||
|
||||
|
@ -1465,15 +1457,15 @@ diff --git a/gdb/configure.ac b/gdb/configure.ac
|
|||
diff --git a/gdb/event-top.c b/gdb/event-top.c
|
||||
--- a/gdb/event-top.c
|
||||
+++ b/gdb/event-top.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "ser-event.h"
|
||||
#include "gdb_select.h"
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "gdbsupport/gdb_select.h"
|
||||
#include "gdbsupport/gdb-sigmask.h"
|
||||
#include "async-event.h"
|
||||
+#include "symfile.h"
|
||||
|
||||
/* readline include files. */
|
||||
#include "readline/readline.h"
|
||||
@@ -363,6 +364,8 @@ display_gdb_prompt (const char *new_prompt)
|
||||
@@ -364,6 +365,8 @@ display_gdb_prompt (const char *new_prompt)
|
||||
/* Reset the nesting depth used when trace-commands is set. */
|
||||
reset_command_nest_depth ();
|
||||
|
||||
|
@ -1482,7 +1474,7 @@ diff --git a/gdb/event-top.c b/gdb/event-top.c
|
|||
/* Do not call the python hook on an explicit prompt change as
|
||||
passed to this function, as this forms a secondary/local prompt,
|
||||
IE, displayed but not set. */
|
||||
@@ -772,7 +775,10 @@ command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
|
||||
@@ -773,7 +776,10 @@ command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl)
|
||||
command_handler (cmd);
|
||||
|
||||
if (ui->prompt_state != PROMPTED)
|
||||
|
@ -1497,12 +1489,11 @@ diff --git a/gdb/event-top.c b/gdb/event-top.c
|
|||
diff --git a/gdb/symfile.h b/gdb/symfile.h
|
||||
--- a/gdb/symfile.h
|
||||
+++ b/gdb/symfile.h
|
||||
@@ -542,6 +542,8 @@ extern void generic_load (const char *args, int from_tty);
|
||||
@@ -560,6 +560,7 @@ extern void generic_load (const char *args, int from_tty);
|
||||
/* build-id support. */
|
||||
extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr);
|
||||
extern void debug_print_missing (const char *binary, const char *debug);
|
||||
+extern void debug_flush_missing (void);
|
||||
+#define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file")
|
||||
#define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file")
|
||||
|
||||
/* From dwarf2read.c */
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1339862
|
|||
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
|
||||
--- a/gdb/solib-svr4.c
|
||||
+++ b/gdb/solib-svr4.c
|
||||
@@ -1346,14 +1346,27 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
|
||||
@@ -1340,14 +1340,27 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -44,7 +44,7 @@ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
|
|||
if (build_id != NULL)
|
||||
{
|
||||
char *name, *build_id_filename;
|
||||
@@ -1368,23 +1381,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
|
||||
@@ -1362,23 +1375,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
|
||||
xfree (name);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -9,7 +9,7 @@ Subject: gdb-6.6-buildid-locate.patch
|
|||
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
|
||||
--- a/bfd/libbfd-in.h
|
||||
+++ b/bfd/libbfd-in.h
|
||||
@@ -127,7 +127,7 @@ static inline char *
|
||||
@@ -121,7 +121,7 @@ static inline char *
|
||||
bfd_strdup (const char *str)
|
||||
{
|
||||
size_t len = strlen (str) + 1;
|
||||
|
@ -21,7 +21,7 @@ diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
|
|||
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
|
||||
--- a/bfd/libbfd.h
|
||||
+++ b/bfd/libbfd.h
|
||||
@@ -132,7 +132,7 @@ static inline char *
|
||||
@@ -126,7 +126,7 @@ static inline char *
|
||||
bfd_strdup (const char *str)
|
||||
{
|
||||
size_t len = strlen (str) + 1;
|
||||
|
@ -33,7 +33,7 @@ diff --git a/bfd/libbfd.h b/bfd/libbfd.h
|
|||
diff --git a/gdb/build-id.c b/gdb/build-id.c
|
||||
--- a/gdb/build-id.c
|
||||
+++ b/gdb/build-id.c
|
||||
@@ -24,13 +24,71 @@
|
||||
@@ -24,13 +24,70 @@
|
||||
#include "gdbsupport/gdb_vecs.h"
|
||||
#include "symfile.h"
|
||||
#include "objfiles.h"
|
||||
|
@ -46,7 +46,6 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
+#include "gdb_bfd.h"
|
||||
+#include "gdbcmd.h"
|
||||
#include "gdbcore.h"
|
||||
+#include "libbfd.h"
|
||||
+#include "objfiles.h"
|
||||
+#include "observable.h"
|
||||
+#include "symfile.h"
|
||||
|
@ -106,7 +105,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
{
|
||||
if (!bfd_check_format (abfd, bfd_object)
|
||||
&& !bfd_check_format (abfd, bfd_core))
|
||||
@@ -43,6 +101,348 @@ build_id_bfd_get (bfd *abfd)
|
||||
@@ -43,6 +100,348 @@ build_id_bfd_get (bfd *abfd)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -455,7 +454,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
/* See build-id.h. */
|
||||
|
||||
int
|
||||
@@ -51,7 +451,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
|
||||
@@ -51,7 +450,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
|
||||
const struct bfd_build_id *found;
|
||||
int retval = 0;
|
||||
|
||||
|
@ -464,7 +463,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
|
||||
if (found == NULL)
|
||||
warning (_("File \"%s\" has no build-id, file skipped"),
|
||||
@@ -66,56 +466,159 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
|
||||
@@ -66,56 +465,159 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -543,7 +542,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
+ files may not be installed. */
|
||||
|
||||
- /* We expect to be silent on the non-existing files. */
|
||||
- gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename.get (), gnutarget, -1);
|
||||
- gdb_bfd_ref_ptr debug_bfd = gdb_bfd_open (filename.get (), gnutarget);
|
||||
+ string_appendf (link, ".%u", seqno);
|
||||
+ }
|
||||
|
||||
|
@ -651,7 +650,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
}
|
||||
|
||||
/* Common code for finding BFDs of a given build-id. This function
|
||||
@@ -124,7 +627,7 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len,
|
||||
@@ -124,7 +626,7 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len,
|
||||
|
||||
static gdb_bfd_ref_ptr
|
||||
build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
|
||||
|
@ -660,7 +659,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
{
|
||||
/* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
|
||||
cause "/.build-id/..." lookups. */
|
||||
@@ -147,16 +650,17 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
|
||||
@@ -147,16 +649,17 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
|
||||
if (size > 0)
|
||||
{
|
||||
size--;
|
||||
|
@ -681,7 +680,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
if (debug_bfd != NULL)
|
||||
return debug_bfd;
|
||||
|
||||
@@ -170,7 +674,8 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
|
||||
@@ -170,7 +673,8 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
|
||||
if (strcmp (gdb_sysroot, TARGET_SYSROOT_PREFIX) != 0)
|
||||
{
|
||||
link = gdb_sysroot + link;
|
||||
|
@ -691,7 +690,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
if (debug_bfd != NULL)
|
||||
return debug_bfd;
|
||||
}
|
||||
@@ -179,38 +684,208 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
|
||||
@@ -179,38 +683,208 @@ build_id_to_bfd_suffix (size_t build_id_len, const bfd_byte *build_id,
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -907,7 +906,7 @@ diff --git a/gdb/build-id.c b/gdb/build-id.c
|
|||
/* Prevent looping on a stripped .debug file. */
|
||||
if (abfd != NULL
|
||||
&& filename_cmp (bfd_get_filename (abfd.get ()),
|
||||
@@ -223,3 +898,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile)
|
||||
@@ -223,3 +897,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile)
|
||||
|
||||
return std::string ();
|
||||
}
|
||||
|
@ -1003,8 +1002,8 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
|
|||
#include "inferior.h"
|
||||
#include "infrun.h"
|
||||
#include "symtab.h"
|
||||
@@ -322,6 +326,8 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
|
||||
inferior_ptid = ptid; /* Yes, make it current. */
|
||||
@@ -362,6 +366,8 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
|
||||
switch_to_thread (thr); /* Yes, make it current. */
|
||||
}
|
||||
|
||||
+static bool build_id_core_loads = true;
|
||||
|
@ -1012,7 +1011,7 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
|
|||
/* Issue a message saying we have no core to debug, if FROM_TTY. */
|
||||
|
||||
static void
|
||||
@@ -358,19 +364,25 @@ core_file_command (const char *filename, int from_tty)
|
||||
@@ -398,19 +404,25 @@ core_file_command (const char *filename, int from_tty)
|
||||
static void
|
||||
locate_exec_from_corefile_build_id (bfd *abfd, int from_tty)
|
||||
{
|
||||
|
@ -1040,10 +1039,10 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
|
|||
}
|
||||
|
||||
/* See gdbcore.h. */
|
||||
@@ -998,4 +1010,11 @@ void
|
||||
_initialize_corelow (void)
|
||||
{
|
||||
add_target (core_target_info, core_target_open, filename_completer);
|
||||
@@ -1189,4 +1201,11 @@ _initialize_corelow ()
|
||||
maintenance_print_core_file_backed_mappings,
|
||||
_("Print core file's file-backed mappings."),
|
||||
&maintenanceprintlist);
|
||||
+
|
||||
+ add_setshow_boolean_cmd ("build-id-core-loads", class_files,
|
||||
+ &build_id_core_loads, _("\
|
||||
|
@ -1055,7 +1054,7 @@ diff --git a/gdb/corelow.c b/gdb/corelow.c
|
|||
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
|
||||
--- a/gdb/doc/gdb.texinfo
|
||||
+++ b/gdb/doc/gdb.texinfo
|
||||
@@ -20862,6 +20862,27 @@ information files.
|
||||
@@ -21074,6 +21074,27 @@ information files.
|
||||
|
||||
@end table
|
||||
|
||||
|
@ -1083,10 +1082,10 @@ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
|
|||
@cindex @code{.gnu_debuglink} sections
|
||||
@cindex debug link sections
|
||||
A debug link is a special section of the executable file named
|
||||
diff --git a/gdb/dwarf-index-cache.c b/gdb/dwarf-index-cache.c
|
||||
--- a/gdb/dwarf-index-cache.c
|
||||
+++ b/gdb/dwarf-index-cache.c
|
||||
@@ -94,7 +94,7 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
|
||||
diff --git a/gdb/dwarf2/index-cache.c b/gdb/dwarf2/index-cache.c
|
||||
--- a/gdb/dwarf2/index-cache.c
|
||||
+++ b/gdb/dwarf2/index-cache.c
|
||||
@@ -95,7 +95,7 @@ index_cache::store (dwarf2_per_objfile *per_objfile)
|
||||
return;
|
||||
|
||||
/* Get build id of objfile. */
|
||||
|
@ -1095,7 +1094,7 @@ diff --git a/gdb/dwarf-index-cache.c b/gdb/dwarf-index-cache.c
|
|||
if (build_id == nullptr)
|
||||
{
|
||||
if (debug_index_cache)
|
||||
@@ -112,7 +112,8 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile)
|
||||
@@ -113,7 +113,8 @@ index_cache::store (dwarf2_per_objfile *per_objfile)
|
||||
|
||||
if (dwz != nullptr)
|
||||
{
|
||||
|
@ -1105,28 +1104,28 @@ diff --git a/gdb/dwarf-index-cache.c b/gdb/dwarf-index-cache.c
|
|||
|
||||
if (dwz_build_id == nullptr)
|
||||
{
|
||||
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
|
||||
--- a/gdb/dwarf2read.c
|
||||
+++ b/gdb/dwarf2read.c
|
||||
@@ -2718,7 +2718,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
|
||||
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
|
||||
--- a/gdb/dwarf2/read.c
|
||||
+++ b/gdb/dwarf2/read.c
|
||||
@@ -2225,7 +2225,7 @@ dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
|
||||
}
|
||||
|
||||
if (dwz_bfd == NULL)
|
||||
- dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid);
|
||||
+ dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid, NULL);
|
||||
|
||||
if (dwz_bfd == NULL)
|
||||
error (_("could not find '.gnu_debugaltlink' file for %s"),
|
||||
@@ -6276,7 +6276,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
|
||||
if (dwz_bfd == nullptr)
|
||||
{
|
||||
@@ -5989,7 +5989,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
|
||||
static gdb::array_view<const gdb_byte>
|
||||
get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
|
||||
get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
|
||||
{
|
||||
- const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
|
||||
+ const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd);
|
||||
if (build_id == nullptr)
|
||||
return {};
|
||||
|
||||
@@ -6289,7 +6289,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
|
||||
@@ -6002,7 +6002,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
|
||||
static gdb::array_view<const gdb_byte>
|
||||
get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz)
|
||||
{
|
||||
|
@ -1138,7 +1137,7 @@ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
|
|||
diff --git a/gdb/elfread.c b/gdb/elfread.c
|
||||
--- a/gdb/elfread.c
|
||||
+++ b/gdb/elfread.c
|
||||
@@ -1299,7 +1299,9 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
|
||||
@@ -1298,7 +1298,9 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
|
||||
&& objfile->separate_debug_objfile == NULL
|
||||
&& objfile->separate_debug_objfile_backlink == NULL)
|
||||
{
|
||||
|
@ -1149,35 +1148,61 @@ diff --git a/gdb/elfread.c b/gdb/elfread.c
|
|||
|
||||
if (debugfile.empty ())
|
||||
debugfile = find_separate_debug_file_by_debuglink (objfile);
|
||||
@@ -1311,8 +1313,12 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
|
||||
symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (),
|
||||
symfile_flags, objfile);
|
||||
}
|
||||
- else
|
||||
- has_dwarf2 = false;
|
||||
+ /* Check if any separate debug info has been extracted out. */
|
||||
+ else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink")
|
||||
+ != NULL)
|
||||
+ debug_print_missing (objfile_name (objfile), build_id_filename.get ());
|
||||
+ else
|
||||
+ has_dwarf2 = false;
|
||||
}
|
||||
@@ -1313,7 +1315,7 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
|
||||
else
|
||||
{
|
||||
has_dwarf2 = false;
|
||||
- const struct bfd_build_id *build_id = build_id_bfd_get (objfile->obfd);
|
||||
+ const struct bfd_build_id *build_id = build_id_bfd_shdr_get (objfile->obfd);
|
||||
|
||||
/* Read the CTF section only if there is no DWARF info. */
|
||||
if (build_id != nullptr)
|
||||
{
|
||||
@@ -1338,6 +1340,10 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
|
||||
has_dwarf2 = true;
|
||||
}
|
||||
}
|
||||
+ /* Check if any separate debug info has been extracted out. */
|
||||
+ else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink")
|
||||
+ != NULL)
|
||||
+ debug_print_missing (objfile_name (objfile), build_id_filename.get ());
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/gdb/exec.c b/gdb/exec.c
|
||||
--- a/gdb/exec.c
|
||||
+++ b/gdb/exec.c
|
||||
@@ -264,7 +264,7 @@ validate_exec_file (int from_tty)
|
||||
reopen_exec_file ();
|
||||
current_exec_file = get_exec_file (0);
|
||||
|
||||
- const bfd_build_id *exec_file_build_id = build_id_bfd_get (exec_bfd);
|
||||
+ const bfd_build_id *exec_file_build_id = build_id_bfd_shdr_get (exec_bfd);
|
||||
if (exec_file_build_id != nullptr)
|
||||
{
|
||||
/* Prepend the target prefix, to force gdb_bfd_open to open the
|
||||
@@ -277,7 +277,7 @@ validate_exec_file (int from_tty)
|
||||
if (abfd != nullptr)
|
||||
{
|
||||
const bfd_build_id *target_exec_file_build_id
|
||||
- = build_id_bfd_get (abfd.get ());
|
||||
+ = build_id_bfd_shdr_get (abfd.get ());
|
||||
|
||||
if (target_exec_file_build_id != nullptr)
|
||||
{
|
||||
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
|
||||
--- a/gdb/objfiles.h
|
||||
+++ b/gdb/objfiles.h
|
||||
@@ -627,6 +627,10 @@ struct objfile
|
||||
htab_up static_links;
|
||||
@@ -714,6 +714,10 @@ struct objfile
|
||||
bool skip_jit_symbol_lookup = false;
|
||||
};
|
||||
|
||||
+/* This file was loaded according to the BUILD_ID_CORE_LOADS rules. */
|
||||
+
|
||||
+#define OBJF_BUILD_ID_CORE_LOADED static_cast<enum objfile_flag>(1 << 12)
|
||||
+
|
||||
/* Declarations for functions defined in objfiles.c */
|
||||
/* A deleter for objfile. */
|
||||
|
||||
extern struct gdbarch *get_objfile_arch (const struct objfile *);
|
||||
struct objfile_deleter
|
||||
diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c
|
||||
--- a/gdb/python/py-objfile.c
|
||||
+++ b/gdb/python/py-objfile.c
|
||||
|
@ -1210,7 +1235,7 @@ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
|
|||
|
||||
static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
|
||||
static int svr4_have_link_map_offsets (void);
|
||||
@@ -1344,9 +1345,51 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
|
||||
@@ -1338,9 +1339,51 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1265,10 +1290,22 @@ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
|
|||
|
||||
/* If this entry has no name, or its name matches the name
|
||||
for the main executable, don't include it in the list. */
|
||||
diff --git a/gdb/source.c b/gdb/source.c
|
||||
--- a/gdb/source.c
|
||||
+++ b/gdb/source.c
|
||||
@@ -1165,7 +1165,7 @@ open_source_file (struct symtab *s)
|
||||
srcpath += s->filename;
|
||||
}
|
||||
|
||||
- const struct bfd_build_id *build_id = build_id_bfd_get (ofp->obfd);
|
||||
+ const struct bfd_build_id *build_id = build_id_bfd_shdr_get (ofp->obfd);
|
||||
|
||||
/* Query debuginfod for the source file. */
|
||||
if (build_id != nullptr && !srcpath.empty ())
|
||||
diff --git a/gdb/symfile.h b/gdb/symfile.h
|
||||
--- a/gdb/symfile.h
|
||||
+++ b/gdb/symfile.h
|
||||
@@ -532,12 +532,17 @@ void expand_symtabs_matching
|
||||
@@ -550,12 +550,18 @@ void expand_symtabs_matching
|
||||
void map_symbol_filenames (symbol_filename_ftype *fun, void *data,
|
||||
int need_fullname);
|
||||
|
||||
|
@ -1282,6 +1319,7 @@ diff --git a/gdb/symfile.h b/gdb/symfile.h
|
|||
+/* build-id support. */
|
||||
+extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr);
|
||||
+extern void debug_print_missing (const char *binary, const char *debug);
|
||||
+#define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file")
|
||||
+
|
||||
/* From dwarf2read.c */
|
||||
|
||||
|
@ -1289,7 +1327,7 @@ diff --git a/gdb/symfile.h b/gdb/symfile.h
|
|||
diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp
|
||||
--- a/gdb/testsuite/gdb.base/corefile.exp
|
||||
+++ b/gdb/testsuite/gdb.base/corefile.exp
|
||||
@@ -311,3 +311,33 @@ gdb_test_multiple "core-file $corefile" $test {
|
||||
@@ -343,3 +343,33 @@ gdb_test_multiple "core-file $corefile" $test {
|
||||
pass $test
|
||||
}
|
||||
}
|
||||
|
@ -1337,7 +1375,7 @@ diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.exp b/gdb/testsuite/gdb
|
|||
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
|
||||
--- a/gdb/testsuite/lib/gdb.exp
|
||||
+++ b/gdb/testsuite/lib/gdb.exp
|
||||
@@ -1891,6 +1891,17 @@ proc default_gdb_start { } {
|
||||
@@ -2011,6 +2011,17 @@ proc default_gdb_start { } {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1358,7 +1396,7 @@ diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
|
|||
diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp
|
||||
--- a/gdb/testsuite/lib/mi-support.exp
|
||||
+++ b/gdb/testsuite/lib/mi-support.exp
|
||||
@@ -309,6 +309,16 @@ proc default_mi_gdb_start { args } {
|
||||
@@ -308,6 +308,16 @@ proc default_mi_gdb_start { args } {
|
||||
warning "Couldn't set the width to 0."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ frames-invalid can happen asynchronously.
|
|||
diff --git a/gdb/testsuite/gdb.base/fileio.c b/gdb/testsuite/gdb.base/fileio.c
|
||||
--- a/gdb/testsuite/gdb.base/fileio.c
|
||||
+++ b/gdb/testsuite/gdb.base/fileio.c
|
||||
@@ -560,6 +560,28 @@ strerrno (int err)
|
||||
@@ -559,6 +559,28 @@ strerrno (int err)
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-6.8-quit-never-aborts.patch
|
||||
|
||||
;; Make the GDB quit processing non-abortable to cleanup everything properly.
|
||||
;;=fedora: It was useful only after gdb-6.8-attach-signalled-detach-stopped.patch .
|
||||
|
||||
We may abort the process of detaching threads with multiple SIGINTs - which are
|
||||
being sent during a testcase terminating its child GDB.
|
||||
|
||||
Some of the threads may not be properly PTRACE_DETACHed which hurts if they
|
||||
should have been detached with SIGSTOP (as they are accidentally left running
|
||||
on the debugger termination).
|
||||
|
||||
diff --git a/gdb/defs.h b/gdb/defs.h
|
||||
--- a/gdb/defs.h
|
||||
+++ b/gdb/defs.h
|
||||
@@ -168,6 +168,10 @@ extern void default_quit_handler (void);
|
||||
/* Flag that function quit should call quit_force. */
|
||||
extern volatile int sync_quit_force_run;
|
||||
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+extern int quit_flag_cleanup;
|
||||
+#endif
|
||||
+
|
||||
extern void quit (void);
|
||||
|
||||
/* Helper for the QUIT macro. */
|
||||
diff --git a/gdb/extension.c b/gdb/extension.c
|
||||
--- a/gdb/extension.c
|
||||
+++ b/gdb/extension.c
|
||||
@@ -823,6 +823,11 @@ check_quit_flag (void)
|
||||
int i, result = 0;
|
||||
const struct extension_language_defn *extlang;
|
||||
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+ if (quit_flag_cleanup)
|
||||
+ return 0;
|
||||
+#endif
|
||||
+
|
||||
ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang)
|
||||
{
|
||||
if (extlang->ops->check_quit_flag != NULL)
|
||||
diff --git a/gdb/top.c b/gdb/top.c
|
||||
--- a/gdb/top.c
|
||||
+++ b/gdb/top.c
|
||||
@@ -1703,7 +1703,13 @@ quit_force (int *exit_arg, int from_tty)
|
||||
|
||||
qt.from_tty = from_tty;
|
||||
|
||||
+#ifndef NEED_DETACH_SIGSTOP
|
||||
/* We want to handle any quit errors and exit regardless. */
|
||||
+#else
|
||||
+ /* We want to handle any quit errors and exit regardless but we should never
|
||||
+ get user-interrupted to properly detach the inferior. */
|
||||
+ quit_flag_cleanup = 1;
|
||||
+#endif
|
||||
|
||||
/* Get out of tfind mode, and kill or detach all inferiors. */
|
||||
try
|
||||
diff --git a/gdb/utils.c b/gdb/utils.c
|
||||
--- a/gdb/utils.c
|
||||
+++ b/gdb/utils.c
|
||||
@@ -102,6 +102,13 @@ static std::chrono::steady_clock::duration prompt_for_continue_wait_time;
|
||||
|
||||
static bool debug_timestamp = false;
|
||||
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+/* Nonzero means we are already processing the quitting cleanups and we should
|
||||
+ no longer get aborted. */
|
||||
+
|
||||
+int quit_flag_cleanup;
|
||||
+#endif
|
||||
+
|
||||
/* True means that strings with character values >0x7F should be printed
|
||||
as octal escapes. False means just print the value (e.g. it's an
|
||||
international character, and the terminal or window can cope.) */
|
|
@ -1,102 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-archer-pie-addons-keep-disabled.patch
|
||||
|
||||
;;=push+jan: Breakpoints disabling matching should not be based on address.
|
||||
|
||||
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
|
||||
--- a/gdb/breakpoint.c
|
||||
+++ b/gdb/breakpoint.c
|
||||
@@ -15396,6 +15396,51 @@ static struct cmd_list_element *enablebreaklist = NULL;
|
||||
|
||||
cmd_list_element *commands_cmd_element = nullptr;
|
||||
|
||||
+void
|
||||
+breakpoints_relocate (struct objfile *objfile, struct section_offsets *delta)
|
||||
+{
|
||||
+ struct bp_location *bl, **blp_tmp;
|
||||
+ int changed = 0;
|
||||
+
|
||||
+ gdb_assert (objfile->separate_debug_objfile_backlink == NULL);
|
||||
+
|
||||
+ ALL_BP_LOCATIONS (bl, blp_tmp)
|
||||
+ {
|
||||
+ struct obj_section *osect;
|
||||
+
|
||||
+ /* BL->SECTION can be correctly NULL for breakpoints with multiple
|
||||
+ locations expanded through symtab. */
|
||||
+
|
||||
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
|
||||
+ {
|
||||
+ CORE_ADDR relocated_address;
|
||||
+ CORE_ADDR delta_offset;
|
||||
+
|
||||
+ delta_offset = ANOFFSET (delta, osect->the_bfd_section->index);
|
||||
+ if (delta_offset == 0)
|
||||
+ continue;
|
||||
+ relocated_address = bl->address + delta_offset;
|
||||
+
|
||||
+ if (obj_section_addr (osect) <= relocated_address
|
||||
+ && relocated_address < obj_section_endaddr (osect))
|
||||
+ {
|
||||
+ if (bl->inserted)
|
||||
+ remove_breakpoint (bl);
|
||||
+
|
||||
+ bl->address += delta_offset;
|
||||
+ bl->requested_address += delta_offset;
|
||||
+
|
||||
+ changed = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (changed)
|
||||
+ std::sort (bp_locations, bp_locations + bp_locations_count,
|
||||
+ bp_location_is_less_than);
|
||||
+}
|
||||
+
|
||||
+void _initialize_breakpoint (void);
|
||||
void
|
||||
_initialize_breakpoint (void)
|
||||
{
|
||||
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
|
||||
--- a/gdb/breakpoint.h
|
||||
+++ b/gdb/breakpoint.h
|
||||
@@ -1696,6 +1696,9 @@ extern const char *ep_parse_optional_if_clause (const char **arg);
|
||||
UIOUT iff debugging multiple threads. */
|
||||
extern void maybe_print_thread_hit_breakpoint (struct ui_out *uiout);
|
||||
|
||||
+extern void breakpoints_relocate (struct objfile *objfile,
|
||||
+ struct section_offsets *delta);
|
||||
+
|
||||
/* Print the specified breakpoint. */
|
||||
extern void print_breakpoint (breakpoint *bp);
|
||||
|
||||
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
|
||||
--- a/gdb/objfiles.c
|
||||
+++ b/gdb/objfiles.c
|
||||
@@ -816,6 +816,11 @@ objfile_relocate1 (struct objfile *objfile,
|
||||
obj_section_addr (s));
|
||||
}
|
||||
|
||||
+ /* Final call of breakpoint_re_set can keep breakpoint locations disabled if
|
||||
+ their addresses match. */
|
||||
+ if (objfile->separate_debug_objfile_backlink == NULL)
|
||||
+ breakpoints_relocate (objfile, delta);
|
||||
+
|
||||
/* Data changed. */
|
||||
return 1;
|
||||
}
|
||||
diff --git a/gdb/value.c b/gdb/value.c
|
||||
--- a/gdb/value.c
|
||||
+++ b/gdb/value.c
|
||||
@@ -2840,7 +2840,7 @@ value_static_field (struct type *type, int fieldno)
|
||||
case FIELD_LOC_KIND_PHYSADDR:
|
||||
retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno),
|
||||
TYPE_FIELD_STATIC_PHYSADDR (type, fieldno)
|
||||
- + (TYPE_OBJFILE (type) == NULL ? 0 : TYPE_OBJFILE (type)->section_offsets[SECT_OFF_TEXT (TYPE_OBJFILE (type))]));
|
||||
+ + (TYPE_OBJFILE (type) == NULL ? 0 : ANOFFSET (TYPE_OBJFILE (type)->section_offsets, SECT_OFF_TEXT (TYPE_OBJFILE (type)))));
|
||||
break;
|
||||
case FIELD_LOC_KIND_PHYSNAME:
|
||||
{
|
|
@ -1,63 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-archer-pie-addons.patch
|
||||
|
||||
;;=push+jan: May get obsoleted by Tom's unrelocated objfiles patch.
|
||||
|
||||
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
|
||||
--- a/gdb/gdbtypes.h
|
||||
+++ b/gdb/gdbtypes.h
|
||||
@@ -516,6 +516,7 @@ enum field_loc_kind
|
||||
{
|
||||
FIELD_LOC_KIND_BITPOS, /**< bitpos */
|
||||
FIELD_LOC_KIND_ENUMVAL, /**< enumval */
|
||||
+ /* This address is unrelocated by the objfile's ANOFFSET. */
|
||||
FIELD_LOC_KIND_PHYSADDR, /**< physaddr */
|
||||
FIELD_LOC_KIND_PHYSNAME, /**< physname */
|
||||
FIELD_LOC_KIND_DWARF_BLOCK /**< dwarf_block */
|
||||
@@ -566,6 +567,7 @@ union field_location
|
||||
field. Otherwise, physname is the mangled label of the
|
||||
static field. */
|
||||
|
||||
+ /* This address is unrelocated by the objfile's ANOFFSET. */
|
||||
CORE_ADDR physaddr;
|
||||
const char *physname;
|
||||
|
||||
@@ -1474,6 +1476,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
|
||||
#define FIELD_ENUMVAL_LVAL(thisfld) ((thisfld).loc.enumval)
|
||||
#define FIELD_ENUMVAL(thisfld) (FIELD_ENUMVAL_LVAL (thisfld) + 0)
|
||||
#define FIELD_STATIC_PHYSNAME(thisfld) ((thisfld).loc.physname)
|
||||
+/* This address is unrelocated by the objfile's ANOFFSET. */
|
||||
#define FIELD_STATIC_PHYSADDR(thisfld) ((thisfld).loc.physaddr)
|
||||
#define FIELD_DWARF_BLOCK(thisfld) ((thisfld).loc.dwarf_block)
|
||||
#define SET_FIELD_BITPOS(thisfld, bitpos) \
|
||||
@@ -1485,6 +1488,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
|
||||
#define SET_FIELD_PHYSNAME(thisfld, name) \
|
||||
(FIELD_LOC_KIND (thisfld) = FIELD_LOC_KIND_PHYSNAME, \
|
||||
FIELD_STATIC_PHYSNAME (thisfld) = (name))
|
||||
+/* This address is unrelocated by the objfile's ANOFFSET. */
|
||||
#define SET_FIELD_PHYSADDR(thisfld, addr) \
|
||||
(FIELD_LOC_KIND (thisfld) = FIELD_LOC_KIND_PHYSADDR, \
|
||||
FIELD_STATIC_PHYSADDR (thisfld) = (addr))
|
||||
@@ -1501,6 +1505,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *);
|
||||
#define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS (TYPE_FIELD (thistype, n))
|
||||
#define TYPE_FIELD_ENUMVAL(thistype, n) FIELD_ENUMVAL (TYPE_FIELD (thistype, n))
|
||||
#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_STATIC_PHYSNAME (TYPE_FIELD (thistype, n))
|
||||
+/* This address is unrelocated by the objfile's ANOFFSET. */
|
||||
#define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_STATIC_PHYSADDR (TYPE_FIELD (thistype, n))
|
||||
#define TYPE_FIELD_DWARF_BLOCK(thistype, n) FIELD_DWARF_BLOCK (TYPE_FIELD (thistype, n))
|
||||
#define TYPE_FIELD_ARTIFICIAL(thistype, n) FIELD_ARTIFICIAL(TYPE_FIELD(thistype,n))
|
||||
diff --git a/gdb/value.c b/gdb/value.c
|
||||
--- a/gdb/value.c
|
||||
+++ b/gdb/value.c
|
||||
@@ -2839,7 +2839,8 @@ value_static_field (struct type *type, int fieldno)
|
||||
{
|
||||
case FIELD_LOC_KIND_PHYSADDR:
|
||||
retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno),
|
||||
- TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
|
||||
+ TYPE_FIELD_STATIC_PHYSADDR (type, fieldno)
|
||||
+ + (TYPE_OBJFILE (type) == NULL ? 0 : TYPE_OBJFILE (type)->section_offsets[SECT_OFF_TEXT (TYPE_OBJFILE (type))]));
|
||||
break;
|
||||
case FIELD_LOC_KIND_PHYSNAME:
|
||||
{
|
File diff suppressed because it is too large
Load Diff
187
gdb-archer.patch
187
gdb-archer.patch
|
@ -1,187 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-archer.patch
|
||||
|
||||
;; Python patches of: http://sourceware.org/gdb/wiki/ProjectArcher
|
||||
;;=push
|
||||
|
||||
http://sourceware.org/gdb/wiki/ProjectArcher
|
||||
http://sourceware.org/gdb/wiki/ArcherBranchManagement
|
||||
|
||||
GIT snapshot:
|
||||
commit 718a1618b2f691a7f407213bb50f100ac59f91c3
|
||||
|
||||
tromey/python
|
||||
|
||||
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
|
||||
--- a/gdb/data-directory/Makefile.in
|
||||
+++ b/gdb/data-directory/Makefile.in
|
||||
@@ -80,6 +80,7 @@ PYTHON_FILE_LIST = \
|
||||
gdb/unwinder.py \
|
||||
gdb/xmethod.py \
|
||||
gdb/command/__init__.py \
|
||||
+ gdb/command/ignore_errors.py \
|
||||
gdb/command/explore.py \
|
||||
gdb/command/backtrace.py \
|
||||
gdb/command/frame_filters.py \
|
||||
@@ -92,6 +93,7 @@ PYTHON_FILE_LIST = \
|
||||
gdb/function/as_string.py \
|
||||
gdb/function/caller_is.py \
|
||||
gdb/function/strfns.py \
|
||||
+ gdb/function/in_scope.py \
|
||||
gdb/printer/__init__.py \
|
||||
gdb/printer/bound_registers.py
|
||||
|
||||
diff --git a/gdb/gdb-gdb.gdb.in b/gdb/gdb-gdb.gdb.in
|
||||
--- a/gdb/gdb-gdb.gdb.in
|
||||
+++ b/gdb/gdb-gdb.gdb.in
|
||||
@@ -1,5 +1,15 @@
|
||||
echo Setting up the environment for debugging gdb.\n
|
||||
|
||||
+# Set up the Python library and "require" command.
|
||||
+python
|
||||
+from os.path import abspath
|
||||
+gdb.datadir = abspath ('@srcdir@/python/lib')
|
||||
+gdb.pythonlibdir = gdb.datadir
|
||||
+gdb.__path__ = [gdb.datadir + '/gdb']
|
||||
+sys.path.insert(0, gdb.datadir)
|
||||
+end
|
||||
+source @srcdir@/python/lib/gdb/__init__.py
|
||||
+
|
||||
if !$gdb_init_done
|
||||
set variable $gdb_init_done = 1
|
||||
|
||||
diff --git a/gdb/python/lib/gdb/command/ignore_errors.py b/gdb/python/lib/gdb/command/ignore_errors.py
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/python/lib/gdb/command/ignore_errors.py
|
||||
@@ -0,0 +1,37 @@
|
||||
+# Ignore errors in user commands.
|
||||
+
|
||||
+# Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import gdb
|
||||
+
|
||||
+class IgnoreErrorsCommand (gdb.Command):
|
||||
+ """Execute a single command, ignoring all errors.
|
||||
+Only one-line commands are supported.
|
||||
+This is primarily useful in scripts."""
|
||||
+
|
||||
+ def __init__ (self):
|
||||
+ super (IgnoreErrorsCommand, self).__init__ ("ignore-errors",
|
||||
+ gdb.COMMAND_OBSCURE,
|
||||
+ # FIXME...
|
||||
+ gdb.COMPLETE_COMMAND)
|
||||
+
|
||||
+ def invoke (self, arg, from_tty):
|
||||
+ try:
|
||||
+ gdb.execute (arg, from_tty)
|
||||
+ except:
|
||||
+ pass
|
||||
+
|
||||
+IgnoreErrorsCommand ()
|
||||
diff --git a/gdb/python/lib/gdb/function/in_scope.py b/gdb/python/lib/gdb/function/in_scope.py
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/python/lib/gdb/function/in_scope.py
|
||||
@@ -0,0 +1,47 @@
|
||||
+# In-scope function.
|
||||
+
|
||||
+# Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import gdb
|
||||
+
|
||||
+class InScope (gdb.Function):
|
||||
+ """Return True if all the given variables or macros are in scope.
|
||||
+Takes one argument for each variable name to be checked."""
|
||||
+
|
||||
+ def __init__ (self):
|
||||
+ super (InScope, self).__init__ ("in_scope")
|
||||
+
|
||||
+ def invoke (self, *vars):
|
||||
+ if len (vars) == 0:
|
||||
+ raise (TypeError, "in_scope takes at least one argument")
|
||||
+
|
||||
+ # gdb.Value isn't hashable so it can't be put in a map.
|
||||
+ # Convert to string first.
|
||||
+ wanted = set (map (lambda x: x.string (), vars))
|
||||
+ found = set ()
|
||||
+ block = gdb.selected_frame ().block ()
|
||||
+ while block:
|
||||
+ for sym in block:
|
||||
+ if (sym.is_argument or sym.is_constant
|
||||
+ or sym.is_function or sym.is_variable):
|
||||
+ if sym.name in wanted:
|
||||
+ found.add (sym.name)
|
||||
+
|
||||
+ block = block.superblock
|
||||
+
|
||||
+ return wanted == found
|
||||
+
|
||||
+InScope ()
|
||||
diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp
|
||||
--- a/gdb/testsuite/gdb.python/py-frame.exp
|
||||
+++ b/gdb/testsuite/gdb.python/py-frame.exp
|
||||
@@ -95,6 +95,8 @@ gdb_test "python print ('result = %s' % f0.read_var ('a'))" " = 1" "test Frame.r
|
||||
|
||||
gdb_test "python print ('result = %s' % (gdb.selected_frame () == f1))" " = True" "test gdb.selected_frame"
|
||||
|
||||
+gdb_test "python print ('result = %s' % (f0.block ()))" "<gdb.Block object at 0x\[\[:xdigit:\]\]+>" "test Frame.block"
|
||||
+
|
||||
# Can read SP register.
|
||||
gdb_test "python print ('result = %s' % (gdb.selected_frame ().read_register ('sp') == gdb.parse_and_eval ('\$sp')))" \
|
||||
" = True" \
|
||||
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
|
||||
--- a/gdb/testsuite/gdb.python/py-value.exp
|
||||
+++ b/gdb/testsuite/gdb.python/py-value.exp
|
||||
@@ -419,6 +419,15 @@ proc test_value_after_death {} {
|
||||
"print value's type"
|
||||
}
|
||||
|
||||
+# Regression test for a cast failure. The bug was that if we cast a
|
||||
+# value to its own type, gdb could crash. This happened because we
|
||||
+# could end up double-freeing a struct value.
|
||||
+proc test_cast_regression {} {
|
||||
+ gdb_test "python v = gdb.Value(5)" "" "create value for cast test"
|
||||
+ gdb_test "python v = v.cast(v.type)" "" "cast value for cast test"
|
||||
+ gdb_test "python print(v)" "5" "print value for cast test"
|
||||
+}
|
||||
+
|
||||
# Regression test for invalid subscript operations. The bug was that
|
||||
# the type of the value was not being checked before allowing a
|
||||
# subscript operation to proceed.
|
||||
@@ -606,6 +615,7 @@ test_value_in_inferior
|
||||
test_value_from_buffer
|
||||
test_inferior_function_call
|
||||
test_value_after_death
|
||||
+test_cast_regression
|
||||
|
||||
# Test either C or C++ values.
|
||||
|
|
@ -1,356 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-attach-fail-reasons-5of5.patch
|
||||
|
||||
;; Print reasons for failed attach/spawn incl. SELinux deny_ptrace (BZ 786878).
|
||||
;;=push+jan
|
||||
|
||||
http://sourceware.org/ml/gdb-patches/2012-03/msg00171.html
|
||||
|
||||
Hi,
|
||||
|
||||
and here is the last bit for new SELinux 'deny_ptrace':
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=786878
|
||||
|
||||
As even PTRACE_TRACEME fails in such case it needs to install hook for even
|
||||
that event.
|
||||
|
||||
Thanks,
|
||||
Jan
|
||||
|
||||
gdb/
|
||||
2012-03-06 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* common/linux-ptrace.c [HAVE_SELINUX_SELINUX_H]: include
|
||||
selinux/selinux.h.
|
||||
(linux_ptrace_attach_warnings): Call linux_ptrace_create_warnings.
|
||||
(linux_ptrace_create_warnings): New.
|
||||
* common/linux-ptrace.h (linux_ptrace_create_warnings): New declaration.
|
||||
* config.in: Regenerate.
|
||||
* configure: Regenerate.
|
||||
* configure.ac: Check selinux/selinux.h and the selinux library.
|
||||
* inf-ptrace.c (inf_ptrace_me): Check the ptrace result.
|
||||
* linux-nat.c (linux_nat_create_inferior): New variable ex. Wrap
|
||||
to_create_inferior into TRY_CATCH, call linux_ptrace_create_warnings.
|
||||
|
||||
gdb/gdbserver/
|
||||
* config.in: Regenerate.
|
||||
* configure: Regenerate.
|
||||
* configure.ac: Check selinux/selinux.h and the selinux library.
|
||||
* linux-low.c (linux_traceme): New function.
|
||||
(linux_create_inferior, linux_tracefork_child): Call it instead of
|
||||
direct ptrace.
|
||||
|
||||
diff --git a/gdb/config.in b/gdb/config.in
|
||||
--- a/gdb/config.in
|
||||
+++ b/gdb/config.in
|
||||
@@ -251,6 +251,9 @@
|
||||
/* Define if librpm library is being used. */
|
||||
#undef HAVE_LIBRPM
|
||||
|
||||
+/* Define to 1 if you have the `selinux' library (-lselinux). */
|
||||
+#undef HAVE_LIBSELINUX
|
||||
+
|
||||
/* Define to 1 if you have the <libunwind-ia64.h> header file. */
|
||||
#undef HAVE_LIBUNWIND_IA64_H
|
||||
|
||||
@@ -386,6 +389,9 @@
|
||||
/* Define to 1 if you have the `scm_new_smob' function. */
|
||||
#undef HAVE_SCM_NEW_SMOB
|
||||
|
||||
+/* Define to 1 if you have the <selinux/selinux.h> header file. */
|
||||
+#undef HAVE_SELINUX_SELINUX_H
|
||||
+
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#undef HAVE_SETLOCALE
|
||||
|
||||
diff --git a/gdb/configure b/gdb/configure
|
||||
--- a/gdb/configure
|
||||
+++ b/gdb/configure
|
||||
@@ -16434,6 +16434,64 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
+for ac_header in selinux/selinux.h
|
||||
+do :
|
||||
+ ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default"
|
||||
+if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define HAVE_SELINUX_SELINUX_H 1
|
||||
+_ACEOF
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+done
|
||||
+
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for security_get_boolean_active in -lselinux" >&5
|
||||
+$as_echo_n "checking for security_get_boolean_active in -lselinux... " >&6; }
|
||||
+if test "${ac_cv_lib_selinux_security_get_boolean_active+set}" = set; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ ac_check_lib_save_LIBS=$LIBS
|
||||
+LIBS="-lselinux $LIBS"
|
||||
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+
|
||||
+/* Override any GCC internal prototype to avoid an error.
|
||||
+ Use char because int might match the return type of a GCC
|
||||
+ builtin and then its argument prototype would still apply. */
|
||||
+#ifdef __cplusplus
|
||||
+extern "C"
|
||||
+#endif
|
||||
+char security_get_boolean_active ();
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+return security_get_boolean_active ();
|
||||
+ ;
|
||||
+ return 0;
|
||||
+}
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_link "$LINENO"; then :
|
||||
+ ac_cv_lib_selinux_security_get_boolean_active=yes
|
||||
+else
|
||||
+ ac_cv_lib_selinux_security_get_boolean_active=no
|
||||
+fi
|
||||
+rm -f core conftest.err conftest.$ac_objext \
|
||||
+ conftest$ac_exeext conftest.$ac_ext
|
||||
+LIBS=$ac_check_lib_save_LIBS
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_security_get_boolean_active" >&5
|
||||
+$as_echo "$ac_cv_lib_selinux_security_get_boolean_active" >&6; }
|
||||
+if test "x$ac_cv_lib_selinux_security_get_boolean_active" = x""yes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define HAVE_LIBSELINUX 1
|
||||
+_ACEOF
|
||||
+
|
||||
+ LIBS="-lselinux $LIBS"
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+
|
||||
|
||||
# Support for --with-sysroot is a copy of GDB_AC_WITH_DIR,
|
||||
# except that the argument to --with-sysroot is optional.
|
||||
diff --git a/gdb/configure.ac b/gdb/configure.ac
|
||||
--- a/gdb/configure.ac
|
||||
+++ b/gdb/configure.ac
|
||||
@@ -1964,6 +1964,10 @@ case $host_os in
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED(GDBINIT,"$gdbinit",[The .gdbinit filename.])
|
||||
|
||||
+dnl Check security_get_boolean_active availability.
|
||||
+AC_CHECK_HEADERS(selinux/selinux.h)
|
||||
+AC_CHECK_LIB(selinux, security_get_boolean_active)
|
||||
+
|
||||
dnl Handle optional features that can be enabled.
|
||||
|
||||
# Support for --with-sysroot is a copy of GDB_AC_WITH_DIR,
|
||||
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
|
||||
--- a/gdb/gdbserver/config.in
|
||||
+++ b/gdb/gdbserver/config.in
|
||||
@@ -125,6 +125,9 @@
|
||||
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||
#undef HAVE_LIBDL
|
||||
|
||||
+/* Define to 1 if you have the `selinux' library (-lselinux). */
|
||||
+#undef HAVE_LIBSELINUX
|
||||
+
|
||||
/* Define if the target supports branch tracing. */
|
||||
#undef HAVE_LINUX_BTRACE
|
||||
|
||||
@@ -210,6 +213,9 @@
|
||||
/* Define to 1 if you have the `pwrite' function. */
|
||||
#undef HAVE_PWRITE
|
||||
|
||||
+/* Define to 1 if you have the <selinux/selinux.h> header file. */
|
||||
+#undef HAVE_SELINUX_SELINUX_H
|
||||
+
|
||||
/* Define to 1 if you have the `setns' function. */
|
||||
#undef HAVE_SETNS
|
||||
|
||||
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
|
||||
--- a/gdb/gdbserver/configure
|
||||
+++ b/gdb/gdbserver/configure
|
||||
@@ -9398,6 +9398,64 @@ if $want_ipa ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
+for ac_header in selinux/selinux.h
|
||||
+do :
|
||||
+ ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default"
|
||||
+if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define HAVE_SELINUX_SELINUX_H 1
|
||||
+_ACEOF
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+done
|
||||
+
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for security_get_boolean_active in -lselinux" >&5
|
||||
+$as_echo_n "checking for security_get_boolean_active in -lselinux... " >&6; }
|
||||
+if test "${ac_cv_lib_selinux_security_get_boolean_active+set}" = set; then :
|
||||
+ $as_echo_n "(cached) " >&6
|
||||
+else
|
||||
+ ac_check_lib_save_LIBS=$LIBS
|
||||
+LIBS="-lselinux $LIBS"
|
||||
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
+/* end confdefs.h. */
|
||||
+
|
||||
+/* Override any GCC internal prototype to avoid an error.
|
||||
+ Use char because int might match the return type of a GCC
|
||||
+ builtin and then its argument prototype would still apply. */
|
||||
+#ifdef __cplusplus
|
||||
+extern "C"
|
||||
+#endif
|
||||
+char security_get_boolean_active ();
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+return security_get_boolean_active ();
|
||||
+ ;
|
||||
+ return 0;
|
||||
+}
|
||||
+_ACEOF
|
||||
+if ac_fn_c_try_link "$LINENO"; then :
|
||||
+ ac_cv_lib_selinux_security_get_boolean_active=yes
|
||||
+else
|
||||
+ ac_cv_lib_selinux_security_get_boolean_active=no
|
||||
+fi
|
||||
+rm -f core conftest.err conftest.$ac_objext \
|
||||
+ conftest$ac_exeext conftest.$ac_ext
|
||||
+LIBS=$ac_check_lib_save_LIBS
|
||||
+fi
|
||||
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_security_get_boolean_active" >&5
|
||||
+$as_echo "$ac_cv_lib_selinux_security_get_boolean_active" >&6; }
|
||||
+if test "x$ac_cv_lib_selinux_security_get_boolean_active" = x""yes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define HAVE_LIBSELINUX 1
|
||||
+_ACEOF
|
||||
+
|
||||
+ LIBS="-lselinux $LIBS"
|
||||
+
|
||||
+fi
|
||||
+
|
||||
+
|
||||
|
||||
|
||||
|
||||
diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac
|
||||
--- a/gdb/gdbserver/configure.ac
|
||||
+++ b/gdb/gdbserver/configure.ac
|
||||
@@ -465,6 +465,10 @@ if $want_ipa ; then
|
||||
fi
|
||||
fi
|
||||
|
||||
+dnl Check security_get_boolean_active availability.
|
||||
+AC_CHECK_HEADERS(selinux/selinux.h)
|
||||
+AC_CHECK_LIB(selinux, security_get_boolean_active)
|
||||
+
|
||||
AC_SUBST(GDBSERVER_DEPFILES)
|
||||
AC_SUBST(GDBSERVER_LIBS)
|
||||
AC_SUBST(srv_xmlbuiltin)
|
||||
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
|
||||
--- a/gdb/gdbserver/linux-low.c
|
||||
+++ b/gdb/gdbserver/linux-low.c
|
||||
@@ -968,7 +968,16 @@ linux_ptrace_fun ()
|
||||
{
|
||||
if (ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0,
|
||||
(PTRACE_TYPE_ARG4) 0) < 0)
|
||||
- trace_start_error_with_name ("ptrace");
|
||||
+ {
|
||||
+ int save_errno = errno;
|
||||
+
|
||||
+ std::string msg (linux_ptrace_create_warnings ());
|
||||
+
|
||||
+ msg += _("Cannot trace created process");
|
||||
+
|
||||
+ errno = save_errno;
|
||||
+ trace_start_error_with_name (msg.c_str ());
|
||||
+ }
|
||||
|
||||
if (setpgid (0, 0) < 0)
|
||||
trace_start_error_with_name ("setpgid");
|
||||
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
|
||||
--- a/gdb/linux-nat.c
|
||||
+++ b/gdb/linux-nat.c
|
||||
@@ -1092,7 +1092,16 @@ linux_nat_target::create_inferior (const char *exec_file,
|
||||
/* Make sure we report all signals during startup. */
|
||||
pass_signals ({});
|
||||
|
||||
- inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
|
||||
+ try
|
||||
+ {
|
||||
+ inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
|
||||
+ }
|
||||
+ catch (const gdb_exception_error &ex)
|
||||
+ {
|
||||
+ std::string result = linux_ptrace_create_warnings ();
|
||||
+
|
||||
+ throw_error (ex.error, "%s%s", result.c_str (), ex.message->c_str ());
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Callback for linux_proc_attach_tgid_threads. Attach to PTID if not
|
||||
diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c
|
||||
--- a/gdb/nat/linux-ptrace.c
|
||||
+++ b/gdb/nat/linux-ptrace.c
|
||||
@@ -25,6 +25,10 @@
|
||||
#include <sys/procfs.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SELINUX_SELINUX_H
|
||||
+# include <selinux/selinux.h>
|
||||
+#endif /* HAVE_SELINUX_SELINUX_H */
|
||||
+
|
||||
/* Stores the ptrace options supported by the running kernel.
|
||||
A value of -1 means we did not check for features yet. A value
|
||||
of 0 means there are no supported features. */
|
||||
@@ -50,6 +54,8 @@ linux_ptrace_attach_fail_reason (pid_t pid)
|
||||
"terminated"),
|
||||
(int) pid);
|
||||
|
||||
+ result += linux_ptrace_create_warnings ();
|
||||
+
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -586,6 +592,25 @@ linux_ptrace_init_warnings (void)
|
||||
linux_ptrace_test_ret_to_nx ();
|
||||
}
|
||||
|
||||
+/* Print all possible reasons we could fail to create a traced process. */
|
||||
+
|
||||
+std::string
|
||||
+linux_ptrace_create_warnings ()
|
||||
+{
|
||||
+ std::string result;
|
||||
+
|
||||
+#ifdef HAVE_LIBSELINUX
|
||||
+ /* -1 is returned for errors, 0 if it has no effect, 1 if PTRACE_ATTACH is
|
||||
+ forbidden. */
|
||||
+ if (security_get_boolean_active ("deny_ptrace") == 1)
|
||||
+ string_appendf (result,
|
||||
+ _("the SELinux boolean 'deny_ptrace' is enabled, "
|
||||
+ "you can disable this process attach protection by: "
|
||||
+ "(gdb) shell sudo setsebool deny_ptrace=0\n"));
|
||||
+#endif /* HAVE_LIBSELINUX */
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
/* Extract extended ptrace event from wait status. */
|
||||
|
||||
int
|
||||
diff --git a/gdb/nat/linux-ptrace.h b/gdb/nat/linux-ptrace.h
|
||||
--- a/gdb/nat/linux-ptrace.h
|
||||
+++ b/gdb/nat/linux-ptrace.h
|
||||
@@ -184,6 +184,7 @@ extern std::string linux_ptrace_attach_fail_reason (pid_t pid);
|
||||
extern std::string linux_ptrace_attach_fail_reason_string (ptid_t ptid, int err);
|
||||
|
||||
extern void linux_ptrace_init_warnings (void);
|
||||
+extern std::string linux_ptrace_create_warnings ();
|
||||
extern void linux_check_ptrace_features (void);
|
||||
extern void linux_enable_event_reporting (pid_t pid, int attached);
|
||||
extern void linux_disable_event_reporting (pid_t pid);
|
|
@ -1,45 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-btrobust.patch
|
||||
|
||||
;; Continue backtrace even if a frame filter throws an exception (Phil Muldoon).
|
||||
;;=push
|
||||
|
||||
This should fix the error with glib. An error message will still be
|
||||
printed, but a default backtrace will occur in this case.
|
||||
|
||||
--
|
||||
|
||||
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
|
||||
--- a/gdb/python/py-framefilter.c
|
||||
+++ b/gdb/python/py-framefilter.c
|
||||
@@ -1204,6 +1204,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
|
||||
htab_eq_pointer,
|
||||
NULL));
|
||||
|
||||
+ int count_printed = 0;
|
||||
while (true)
|
||||
{
|
||||
gdbpy_ref<> item (PyIter_Next (iterable.get ()));
|
||||
@@ -1212,8 +1213,8 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
|
||||
{
|
||||
if (PyErr_Occurred ())
|
||||
{
|
||||
- gdbpy_print_stack_or_quit ();
|
||||
- return EXT_LANG_BT_ERROR;
|
||||
+ gdbpy_print_stack ();
|
||||
+ return count_printed > 0 ? EXT_LANG_BT_ERROR : EXT_LANG_BT_NO_FILTERS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1245,7 +1246,8 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang,
|
||||
/* Do not exit on error printing a single frame. Print the
|
||||
error and continue with other frames. */
|
||||
if (success == EXT_LANG_BT_ERROR)
|
||||
- gdbpy_print_stack_or_quit ();
|
||||
+ gdbpy_print_stack ();
|
||||
+ count_printed++;
|
||||
}
|
||||
|
||||
return success;
|
|
@ -1,178 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-bz1219747-attach-kills.patch
|
||||
|
||||
;; Never kill PID on: gdb exec PID (Jan Kratochvil, RH BZ 1219747).
|
||||
;;=push+jan
|
||||
|
||||
http://sourceware.org/ml/gdb-patches/2015-10/msg00301.html
|
||||
|
||||
Hi,
|
||||
|
||||
in some cases with deleted main executable GDB will want to kill the inferior.
|
||||
|
||||
$ cp /bin/sleep /tmp/sleep;/tmp/sleep 1h&p=$!
|
||||
$ rm /tmp/sleep
|
||||
$ gdb /tmp/sleep $p
|
||||
GNU gdb (GDB) 7.10.50.20151016-cvs
|
||||
/tmp/sleep: No such file or directory.
|
||||
Attaching to process 9694
|
||||
/tmp/sleep (deleted): No such file or directory.
|
||||
A program is being debugged already. Kill it? (y or n) _
|
||||
|
||||
The first attachment of "/tmp/sleep" commandline argument errors at:
|
||||
|
||||
267 if (scratch_chan < 0)
|
||||
268 perror_with_name (filename);
|
||||
1051 if (catch_command_errors_const (exec_file_attach, execarg,
|
||||
1052 !batch_flag))
|
||||
|
||||
Then GDB tries to attach to the process $p:
|
||||
|
||||
1082 if (catch_command_errors (attach_command, pid_or_core_arg,
|
||||
1083 !batch_flag) == 0)
|
||||
|
||||
This succeeds and since this moment GDB has a valid inferior. But despite that
|
||||
the lines
|
||||
1082 if (catch_command_errors (attach_command, pid_or_core_arg,
|
||||
1083 !batch_flag) == 0)
|
||||
still fail because consequently attach_command() fails to find the associated
|
||||
executable file:
|
||||
|
||||
267 if (scratch_chan < 0)
|
||||
268 perror_with_name (filename);
|
||||
1082 if (catch_command_errors (attach_command, pid_or_core_arg,
|
||||
1083 !batch_flag) == 0)
|
||||
|
||||
and therefore GDB executes the following:
|
||||
|
||||
(gdb) bt
|
||||
2179 if (have_inferiors ())
|
||||
2180 {
|
||||
2181 if (!from_tty
|
||||
2182 || !have_live_inferiors ()
|
||||
2183 || query (_("A program is being debugged already. Kill it? ")))
|
||||
2184 iterate_over_inferiors (dispose_inferior, NULL);
|
||||
2185 else
|
||||
2186 error (_("Program not killed."));
|
||||
2187 }
|
||||
1084 catch_command_errors (core_file_command, pid_or_core_arg,
|
||||
1085 !batch_flag);
|
||||
|
||||
No regressions on {x86_64,x86_64-m32,i686}-fedora24pre-linux-gnu.
|
||||
|
||||
Thanks,
|
||||
Jan
|
||||
|
||||
gdb/ChangeLog
|
||||
2015-10-16 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* main.c (captured_main): Run core_file_command for pid_or_core_arg
|
||||
only if not have_inferiors ().
|
||||
|
||||
gdb/testsuite/ChangeLog
|
||||
2015-10-16 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.base/attach-kills.c: New.
|
||||
* gdb.base/attach-kills.exp: New.
|
||||
|
||||
diff --git a/gdb/main.c b/gdb/main.c
|
||||
--- a/gdb/main.c
|
||||
+++ b/gdb/main.c
|
||||
@@ -1148,7 +1148,10 @@ captured_main_1 (struct captured_main_args *context)
|
||||
{
|
||||
ret = catch_command_errors (attach_command, pid_or_core_arg,
|
||||
!batch_flag);
|
||||
- if (ret == 0)
|
||||
+ if (ret == 0
|
||||
+ /* attach_command could succeed partially and core_file_command
|
||||
+ would try to kill it. */
|
||||
+ && !have_inferiors ())
|
||||
ret = catch_command_errors (core_file_command,
|
||||
pid_or_core_arg,
|
||||
!batch_flag);
|
||||
diff --git a/gdb/testsuite/gdb.base/attach-kills.c b/gdb/testsuite/gdb.base/attach-kills.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.base/attach-kills.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* This testcase is part of GDB, the GNU debugger.
|
||||
+
|
||||
+ Copyright 2015 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ sleep (600);
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/gdb/testsuite/gdb.base/attach-kills.exp b/gdb/testsuite/gdb.base/attach-kills.exp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.base/attach-kills.exp
|
||||
@@ -0,0 +1,49 @@
|
||||
+# Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
+#
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+if { ![can_spawn_for_attach] } {
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+standard_testfile
|
||||
+
|
||||
+if { [build_executable ${testfile}.exp $testfile] == -1 } {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+# Start the program running and then wait for a bit, to be sure
|
||||
+# that it can be attached to.
|
||||
+
|
||||
+set test_spawn_id [spawn_wait_for_attach $binfile]
|
||||
+set testpid [spawn_id_get_pid $test_spawn_id]
|
||||
+
|
||||
+remote_exec target "cp -pf -- $binfile $binfile-copy"
|
||||
+remote_exec target "rm -f -- $binfile"
|
||||
+
|
||||
+set test "start gdb"
|
||||
+set res [gdb_spawn_with_cmdline_opts \
|
||||
+ "-iex \"set height 0\" -iex \"set width 0\" /DoEsNoTeXySt $testpid"]
|
||||
+if { $res != 0} {
|
||||
+ fail "$test (spawn)"
|
||||
+ kill_wait_spawned_process $test_spawn_id
|
||||
+ return -1
|
||||
+}
|
||||
+gdb_test_multiple "" $test {
|
||||
+ -re "\r\nAttaching to .*\r\n$gdb_prompt $" {
|
||||
+ pass $test
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+kill_wait_spawned_process $test_spawn_id
|
|
@ -1,130 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-bz533176-fortran-omp-step.patch
|
||||
|
||||
;; Fix stepping with OMP parallel Fortran sections (BZ 533176).
|
||||
;;=push+jan: It requires some better DWARF annotations.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=533176#c4
|
||||
|
||||
I find it a bug in DWARF and gdb behaves correctly according to it. From the
|
||||
current DWARF's point of view the is a function call which you skip by "next".
|
||||
|
||||
If you hide any /usr/lib/debug such as using:
|
||||
gdb -nx -ex 'set debug-file-directory /qwe' -ex 'file ./tpcommon_gfortran44'
|
||||
and use "step" command instead of "next" there it will work.
|
||||
(You need to hide debuginfo from libgomp as you would step into libgomp sources
|
||||
to maintain the threads for execution.)
|
||||
|
||||
There should be some DWARF extension for it, currently tried to detect
|
||||
substring ".omp_fn." as this function is called "MAIN__.omp_fn.0" and do not
|
||||
consider such sub-function as a skippable by "next".
|
||||
|
||||
Another problem is that with "set scheduler-locking" being "off" (default
|
||||
upstream) or "step" (default in F/RHEL) the simultaneous execution of the
|
||||
threads is inconvenient. Setting it to "on" will lockup the debugging as the
|
||||
threads need to get synchronized at some point. This is a more general
|
||||
debugging problem of GOMP outside of the scope of this Bug.
|
||||
|
||||
diff --git a/gdb/infrun.c b/gdb/infrun.c
|
||||
--- a/gdb/infrun.c
|
||||
+++ b/gdb/infrun.c
|
||||
@@ -6453,6 +6453,16 @@ process_event_stop_test (struct execution_control_state *ecs)
|
||||
|
||||
if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
|
||||
{
|
||||
+ struct symbol *stop_fn = find_pc_function (stop_pc);
|
||||
+ struct minimal_symbol *stopf = lookup_minimal_symbol_by_pc (stop_pc).minsym;
|
||||
+
|
||||
+ if ((stop_fn == NULL
|
||||
+ || strstr (stop_fn->linkage_name (), ".omp_fn.") == NULL)
|
||||
+ /* gcc-4.7.2-9.fc19.x86_64 uses a new format. */
|
||||
+ && (stopf == NULL
|
||||
+ || strstr (stopf->linkage_name (), "._omp_fn.") == NULL))
|
||||
+{ /* ".omp_fn." */
|
||||
+
|
||||
/* We're doing a "next".
|
||||
|
||||
Normal (forward) execution: set a breakpoint at the
|
||||
@@ -6486,6 +6496,7 @@ process_event_stop_test (struct execution_control_state *ecs)
|
||||
|
||||
keep_going (ecs);
|
||||
return;
|
||||
+} /* ".omp_fn." */
|
||||
}
|
||||
|
||||
/* If we are in a function call trampoline (a stub between the
|
||||
diff --git a/gdb/testsuite/gdb.fortran/omp-step.exp b/gdb/testsuite/gdb.fortran/omp-step.exp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/omp-step.exp
|
||||
@@ -0,0 +1,31 @@
|
||||
+# Copyright 2009 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+set testfile "omp-step"
|
||||
+set srcfile ${testfile}.f90
|
||||
+if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug f90 additional_flags=-fopenmp}] } {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+if ![runto [gdb_get_line_number "start-here"]] {
|
||||
+ perror "Couldn't run to start-here"
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+gdb_test "next" {!\$omp parallel} "step closer"
|
||||
+gdb_test "next" {a\(omp_get_thread_num\(\) \+ 1\) = 1} "step into omp"
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "success"]
|
||||
+gdb_continue_to_breakpoint "success" ".*success.*"
|
||||
diff --git a/gdb/testsuite/gdb.fortran/omp-step.f90 b/gdb/testsuite/gdb.fortran/omp-step.f90
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/omp-step.f90
|
||||
@@ -0,0 +1,32 @@
|
||||
+! Copyright 2009 Free Software Foundation, Inc.
|
||||
+
|
||||
+! This program is free software; you can redistribute it and/or modify
|
||||
+! it under the terms of the GNU General Public License as published by
|
||||
+! the Free Software Foundation; either version 3 of the License, or
|
||||
+! (at your option) any later version.
|
||||
+!
|
||||
+! This program is distributed in the hope that it will be useful,
|
||||
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+! GNU General Public License for more details.
|
||||
+!
|
||||
+! You should have received a copy of the GNU General Public License
|
||||
+! along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+ use omp_lib
|
||||
+ integer nthreads, i, a(1000)
|
||||
+ nthreads = omp_get_num_threads()
|
||||
+ if (nthreads .gt. 1000) call abort
|
||||
+
|
||||
+ do i = 1, nthreads
|
||||
+ a(i) = 0
|
||||
+ end do
|
||||
+ print *, "start-here"
|
||||
+!$omp parallel
|
||||
+ a(omp_get_thread_num() + 1) = 1
|
||||
+!$omp end parallel
|
||||
+ do i = 1, nthreads
|
||||
+ if (a(i) .ne. 1) call abort
|
||||
+ end do
|
||||
+ print *, "success"
|
||||
+ end
|
|
@ -9,7 +9,7 @@ Subject: gdb-container-rh-pkg.patch
|
|||
diff --git a/gdb/remote.c b/gdb/remote.c
|
||||
--- a/gdb/remote.c
|
||||
+++ b/gdb/remote.c
|
||||
@@ -13916,7 +13916,17 @@ remote_target::pid_to_exec_file (int pid)
|
||||
@@ -14031,7 +14031,17 @@ remote_target::pid_to_exec_file (int pid)
|
||||
char *annex = NULL;
|
||||
|
||||
if (packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE)
|
||||
|
@ -26,5 +26,5 @@ diff --git a/gdb/remote.c b/gdb/remote.c
|
|||
+ return NULL;
|
||||
+ }
|
||||
|
||||
inf = find_inferior_pid (pid);
|
||||
inferior *inf = find_inferior_pid (this, pid);
|
||||
if (inf == NULL)
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Tue, 1 Jun 2021 10:14:31 -0700
|
||||
Subject: gdb-dont-overwrite-fsgsbase-m32.patch
|
||||
|
||||
;; Backport "[gdb/server] Don't overwrite fs/gs_base with -m32"
|
||||
;; (Tom de Vries)
|
||||
|
||||
Consider a minimal test-case test.c:
|
||||
...
|
||||
int main (void) { return 0; }
|
||||
...
|
||||
compiled with -m32:
|
||||
...
|
||||
$ gcc test.c -m32
|
||||
...
|
||||
|
||||
When running the exec using gdbserver on openSUSE Factory (currently running a
|
||||
linux kernel version 5.10.5):
|
||||
...
|
||||
$ gdbserver localhost:12345 a.out
|
||||
...
|
||||
to which we connect in a gdb session, we run into a segfault in the inferior:
|
||||
...
|
||||
$ gdb -batch -q -ex "target remote localhost:12345" -ex continue
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
0xf7dd8bd2 in init_cacheinfo () at ../sysdeps/x86/cacheinfo.c:761
|
||||
...
|
||||
|
||||
The segfault is caused by gdbserver overwriting $gs_base with 0 using
|
||||
PTRACE_SETREGS. After it is overwritten, the next use of $gs in the inferior
|
||||
will trigger the segfault.
|
||||
|
||||
Before linux kernel version 5.9, the value used by PTRACE_SETREGS for $gs_base
|
||||
was ignored, but starting version 5.9, the linux kernel has support for
|
||||
intel architecture extension FSGSBASE, which allows users to modify $gs_base,
|
||||
and consequently PTRACE_SETREGS can no longer ignore the $gs_base value.
|
||||
|
||||
The overwrite of $gs_base with 0 is done by a memset in x86_fill_gregset,
|
||||
which was added in commit 9e0aa64f551 "Fix gdbserver qGetTLSAddr for
|
||||
x86_64 -m32". The memset intends to zero-extend 32-bit registers that are
|
||||
tracked in the regcache to 64-bit when writing them into the PTRACE_SETREGS
|
||||
data argument. But in addition, it overwrites other registers that are
|
||||
not tracked in the regcache, such as $gs_base.
|
||||
|
||||
Fix the segfault by redoing the fix from commit 9e0aa64f551 in minimal form.
|
||||
|
||||
Tested on x86_64-linux:
|
||||
- openSUSE Leap 15.2 (using kernel version 5.3.18):
|
||||
- native
|
||||
- gdbserver -m32
|
||||
- -m32
|
||||
- openSUSE Factory (using kernel version 5.10.5):
|
||||
- native
|
||||
- m32
|
||||
|
||||
gdbserver/ChangeLog:
|
||||
|
||||
2021-01-20 Tom de Vries <tdevries@suse.de>
|
||||
|
||||
* linux-x86-low.cc (collect_register_i386): New function.
|
||||
(x86_fill_gregset): Remove memset. Use collect_register_i386.
|
||||
|
||||
diff --git a/gdbserver/linux-x86-low.cc b/gdbserver/linux-x86-low.cc
|
||||
--- a/gdbserver/linux-x86-low.cc
|
||||
+++ b/gdbserver/linux-x86-low.cc
|
||||
@@ -397,6 +397,35 @@ x86_target::low_cannot_fetch_register (int regno)
|
||||
return regno >= I386_NUM_REGS;
|
||||
}
|
||||
|
||||
+static void
|
||||
+collect_register_i386 (struct regcache *regcache, int regno, void *buf)
|
||||
+{
|
||||
+ collect_register (regcache, regno, buf);
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ /* In case of x86_64 -m32, collect_register only writes 4 bytes, but the
|
||||
+ space reserved in buf for the register is 8 bytes. Make sure the entire
|
||||
+ reserved space is initialized. */
|
||||
+
|
||||
+ gdb_assert (register_size (regcache->tdesc, regno) == 4);
|
||||
+
|
||||
+ if (regno == RAX)
|
||||
+ {
|
||||
+ /* Sign extend EAX value to avoid potential syscall restart
|
||||
+ problems.
|
||||
+
|
||||
+ See amd64_linux_collect_native_gregset() in
|
||||
+ gdb/amd64-linux-nat.c for a detailed explanation. */
|
||||
+ *(int64_t *) buf = *(int32_t *) buf;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Zero-extend. */
|
||||
+ *(uint64_t *) buf = *(uint32_t *) buf;
|
||||
+ }
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static void
|
||||
x86_fill_gregset (struct regcache *regcache, void *buf)
|
||||
{
|
||||
@@ -411,32 +440,14 @@ x86_fill_gregset (struct regcache *regcache, void *buf)
|
||||
|
||||
return;
|
||||
}
|
||||
-
|
||||
- /* 32-bit inferior registers need to be zero-extended.
|
||||
- Callers would read uninitialized memory otherwise. */
|
||||
- memset (buf, 0x00, X86_64_USER_REGS * 8);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < I386_NUM_REGS; i++)
|
||||
- collect_register (regcache, i, ((char *) buf) + i386_regmap[i]);
|
||||
-
|
||||
- collect_register_by_name (regcache, "orig_eax",
|
||||
- ((char *) buf) + ORIG_EAX * REGSIZE);
|
||||
+ collect_register_i386 (regcache, i, ((char *) buf) + i386_regmap[i]);
|
||||
|
||||
-#ifdef __x86_64__
|
||||
- /* Sign extend EAX value to avoid potential syscall restart
|
||||
- problems.
|
||||
-
|
||||
- See amd64_linux_collect_native_gregset() in gdb/amd64-linux-nat.c
|
||||
- for a detailed explanation. */
|
||||
- if (register_size (regcache->tdesc, 0) == 4)
|
||||
- {
|
||||
- void *ptr = ((gdb_byte *) buf
|
||||
- + i386_regmap[find_regno (regcache->tdesc, "eax")]);
|
||||
-
|
||||
- *(int64_t *) ptr = *(int32_t *) ptr;
|
||||
- }
|
||||
-#endif
|
||||
+ /* Handle ORIG_EAX, which is not in i386_regmap. */
|
||||
+ collect_register_i386 (regcache, find_regno (regcache->tdesc, "orig_eax"),
|
||||
+ ((char *) buf) + ORIG_EAX * REGSIZE);
|
||||
}
|
||||
|
||||
static void
|
|
@ -1,315 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-dts-rhel6-python-compat.patch
|
||||
|
||||
;; [rhel6] DTS backward Python compatibility API (BZ 1020004, Phil Muldoon).
|
||||
;;=fedora
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1020004
|
||||
|
||||
diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in
|
||||
--- a/gdb/data-directory/Makefile.in
|
||||
+++ b/gdb/data-directory/Makefile.in
|
||||
@@ -71,6 +71,8 @@ PYTHON_FILE_LIST = \
|
||||
gdb/__init__.py \
|
||||
gdb/FrameDecorator.py \
|
||||
gdb/FrameIterator.py \
|
||||
+ gdb/FrameWrapper.py \
|
||||
+ gdb/backtrace.py \
|
||||
gdb/frames.py \
|
||||
gdb/printing.py \
|
||||
gdb/prompt.py \
|
||||
@@ -79,6 +81,7 @@ PYTHON_FILE_LIST = \
|
||||
gdb/xmethod.py \
|
||||
gdb/command/__init__.py \
|
||||
gdb/command/explore.py \
|
||||
+ gdb/command/backtrace.py \
|
||||
gdb/command/frame_filters.py \
|
||||
gdb/command/pretty_printers.py \
|
||||
gdb/command/prompt.py \
|
||||
diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/python/lib/gdb/FrameWrapper.py
|
||||
@@ -0,0 +1,122 @@
|
||||
+# Wrapper API for frames.
|
||||
+
|
||||
+# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import gdb
|
||||
+
|
||||
+# FIXME: arguably all this should be on Frame somehow.
|
||||
+class FrameWrapper:
|
||||
+ def __init__ (self, frame):
|
||||
+ self.frame = frame;
|
||||
+
|
||||
+ def write_symbol (self, stream, sym, block):
|
||||
+ if len (sym.linkage_name):
|
||||
+ nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block)
|
||||
+ if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER:
|
||||
+ sym = nsym
|
||||
+
|
||||
+ stream.write (sym.print_name + "=")
|
||||
+ try:
|
||||
+ val = self.read_var (sym)
|
||||
+ if val != None:
|
||||
+ val = str (val)
|
||||
+ # FIXME: would be nice to have a more precise exception here.
|
||||
+ except RuntimeError as text:
|
||||
+ val = text
|
||||
+ if val == None:
|
||||
+ stream.write ("???")
|
||||
+ else:
|
||||
+ stream.write (str (val))
|
||||
+
|
||||
+ def print_frame_locals (self, stream, func):
|
||||
+
|
||||
+ try:
|
||||
+ block = self.frame.block()
|
||||
+ except RuntimeError:
|
||||
+ block = None
|
||||
+
|
||||
+ while block != None:
|
||||
+ if block.is_global or block.is_static:
|
||||
+ break
|
||||
+
|
||||
+ for sym in block:
|
||||
+ if sym.is_argument:
|
||||
+ continue;
|
||||
+
|
||||
+ self.write_symbol (stream, sym, block)
|
||||
+ stream.write ('\n')
|
||||
+
|
||||
+ def print_frame_args (self, stream, func):
|
||||
+
|
||||
+ try:
|
||||
+ block = self.frame.block()
|
||||
+ except RuntimeError:
|
||||
+ block = None
|
||||
+
|
||||
+ while block != None:
|
||||
+ if block.function != None:
|
||||
+ break
|
||||
+ block = block.superblock
|
||||
+
|
||||
+ first = True
|
||||
+ for sym in block:
|
||||
+ if not sym.is_argument:
|
||||
+ continue;
|
||||
+
|
||||
+ if not first:
|
||||
+ stream.write (", ")
|
||||
+
|
||||
+ self.write_symbol (stream, sym, block)
|
||||
+ first = False
|
||||
+
|
||||
+ # FIXME: this should probably just be a method on gdb.Frame.
|
||||
+ # But then we need stream wrappers.
|
||||
+ def describe (self, stream, full):
|
||||
+ if self.type () == gdb.DUMMY_FRAME:
|
||||
+ stream.write (" <function called from gdb>\n")
|
||||
+ elif self.type () == gdb.SIGTRAMP_FRAME:
|
||||
+ stream.write (" <signal handler called>\n")
|
||||
+ else:
|
||||
+ sal = self.find_sal ()
|
||||
+ pc = self.pc ()
|
||||
+ name = self.name ()
|
||||
+ if not name:
|
||||
+ name = "??"
|
||||
+ if pc != sal.pc or not sal.symtab:
|
||||
+ stream.write (" 0x%08x in" % pc)
|
||||
+ stream.write (" " + name + " (")
|
||||
+
|
||||
+ func = self.function ()
|
||||
+ self.print_frame_args (stream, func)
|
||||
+
|
||||
+ stream.write (")")
|
||||
+
|
||||
+ if sal.symtab and sal.symtab.filename:
|
||||
+ stream.write (" at " + sal.symtab.filename)
|
||||
+ stream.write (":" + str (sal.line))
|
||||
+
|
||||
+ if not self.name () or (not sal.symtab or not sal.symtab.filename):
|
||||
+ lib = gdb.solib_name (pc)
|
||||
+ if lib:
|
||||
+ stream.write (" from " + lib)
|
||||
+
|
||||
+ stream.write ("\n")
|
||||
+
|
||||
+ if full:
|
||||
+ self.print_frame_locals (stream, func)
|
||||
+
|
||||
+ def __getattr__ (self, name):
|
||||
+ return getattr (self.frame, name)
|
||||
diff --git a/gdb/python/lib/gdb/backtrace.py b/gdb/python/lib/gdb/backtrace.py
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/python/lib/gdb/backtrace.py
|
||||
@@ -0,0 +1,42 @@
|
||||
+# Filtering backtrace.
|
||||
+
|
||||
+# Copyright (C) 2008, 2011 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import gdb
|
||||
+import itertools
|
||||
+
|
||||
+# Our only exports.
|
||||
+__all__ = ['push_frame_filter', 'create_frame_filter']
|
||||
+
|
||||
+old_frame_filter = None
|
||||
+
|
||||
+def push_frame_filter (constructor):
|
||||
+ """Register a new backtrace filter class with the 'backtrace' command.
|
||||
+The filter will be passed an iterator as an argument. The iterator
|
||||
+will return gdb.Frame-like objects. The filter should in turn act as
|
||||
+an iterator returning such objects."""
|
||||
+ global old_frame_filter
|
||||
+ if old_frame_filter == None:
|
||||
+ old_frame_filter = constructor
|
||||
+ else:
|
||||
+ old_frame_filter = lambda iterator, filter = frame_filter: constructor (filter(iterator))
|
||||
+
|
||||
+def create_frame_filter (iter):
|
||||
+ global old_frame_filter
|
||||
+ if old_frame_filter is None:
|
||||
+ return iter
|
||||
+ return old_frame_filter (iter)
|
||||
+
|
||||
diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/python/lib/gdb/command/backtrace.py
|
||||
@@ -0,0 +1,106 @@
|
||||
+# New backtrace command.
|
||||
+
|
||||
+# Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+import gdb
|
||||
+import gdb.backtrace
|
||||
+import itertools
|
||||
+from gdb.FrameIterator import FrameIterator
|
||||
+from gdb.FrameWrapper import FrameWrapper
|
||||
+import sys
|
||||
+
|
||||
+class ReverseBacktraceParameter (gdb.Parameter):
|
||||
+ """The new-backtrace command can show backtraces in 'reverse' order.
|
||||
+This means that the innermost frame will be printed last.
|
||||
+Note that reverse backtraces are more expensive to compute."""
|
||||
+
|
||||
+ set_doc = "Enable or disable reverse backtraces."
|
||||
+ show_doc = "Show whether backtraces will be printed in reverse order."
|
||||
+
|
||||
+ def __init__(self):
|
||||
+ gdb.Parameter.__init__ (self, "reverse-backtrace",
|
||||
+ gdb.COMMAND_STACK, gdb.PARAM_BOOLEAN)
|
||||
+ # Default to compatibility with gdb.
|
||||
+ self.value = False
|
||||
+
|
||||
+class FilteringBacktrace (gdb.Command):
|
||||
+ """Print backtrace of all stack frames, or innermost COUNT frames.
|
||||
+With a negative argument, print outermost -COUNT frames.
|
||||
+Use of the 'full' qualifier also prints the values of the local variables.
|
||||
+Use of the 'raw' qualifier avoids any filtering by loadable modules.
|
||||
+"""
|
||||
+
|
||||
+ def __init__ (self):
|
||||
+ # FIXME: this is not working quite well enough to replace
|
||||
+ # "backtrace" yet.
|
||||
+ gdb.Command.__init__ (self, "new-backtrace", gdb.COMMAND_STACK)
|
||||
+ self.reverse = ReverseBacktraceParameter()
|
||||
+
|
||||
+ def reverse_iter (self, iter):
|
||||
+ result = []
|
||||
+ for item in iter:
|
||||
+ result.append (item)
|
||||
+ result.reverse()
|
||||
+ return result
|
||||
+
|
||||
+ def final_n (self, iter, x):
|
||||
+ result = []
|
||||
+ for item in iter:
|
||||
+ result.append (item)
|
||||
+ return result[x:]
|
||||
+
|
||||
+ def invoke (self, arg, from_tty):
|
||||
+ i = 0
|
||||
+ count = 0
|
||||
+ filter = True
|
||||
+ full = False
|
||||
+
|
||||
+ for word in arg.split (" "):
|
||||
+ if word == '':
|
||||
+ continue
|
||||
+ elif word == 'raw':
|
||||
+ filter = False
|
||||
+ elif word == 'full':
|
||||
+ full = True
|
||||
+ else:
|
||||
+ count = int (word)
|
||||
+
|
||||
+ # FIXME: provide option to start at selected frame
|
||||
+ # However, should still number as if starting from newest
|
||||
+ newest_frame = gdb.newest_frame()
|
||||
+ iter = itertools.imap (FrameWrapper,
|
||||
+ FrameIterator (newest_frame))
|
||||
+ if filter:
|
||||
+ iter = gdb.backtrace.create_frame_filter (iter)
|
||||
+
|
||||
+ # Now wrap in an iterator that numbers the frames.
|
||||
+ iter = itertools.izip (itertools.count (0), iter)
|
||||
+
|
||||
+ # Reverse if the user wanted that.
|
||||
+ if self.reverse.value:
|
||||
+ iter = self.reverse_iter (iter)
|
||||
+
|
||||
+ # Extract sub-range user wants.
|
||||
+ if count < 0:
|
||||
+ iter = self.final_n (iter, count)
|
||||
+ elif count > 0:
|
||||
+ iter = itertools.islice (iter, 0, count)
|
||||
+
|
||||
+ for pair in iter:
|
||||
+ sys.stdout.write ("#%-2d" % pair[0])
|
||||
+ pair[1].describe (sys.stdout, full)
|
||||
+
|
||||
+FilteringBacktrace()
|
|
@ -12,7 +12,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1270534
|
|||
diff --git a/gdb/configure b/gdb/configure
|
||||
--- a/gdb/configure
|
||||
+++ b/gdb/configure
|
||||
@@ -9375,6 +9375,7 @@ if test x"$prefer_curses" = xyes; then
|
||||
@@ -9649,6 +9649,7 @@ if test x"$prefer_curses" = xyes; then
|
||||
# search /usr/local/include, if ncurses is installed in /usr/local. A
|
||||
# default installation of ncurses on alpha*-dec-osf* will lead to such
|
||||
# a situation.
|
||||
|
@ -20,7 +20,7 @@ diff --git a/gdb/configure b/gdb/configure
|
|||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing waddstr" >&5
|
||||
$as_echo_n "checking for library containing waddstr... " >&6; }
|
||||
if ${ac_cv_search_waddstr+:} false; then :
|
||||
@@ -9399,7 +9400,7 @@ return waddstr ();
|
||||
@@ -9673,7 +9674,7 @@ return waddstr ();
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
|
@ -29,7 +29,7 @@ diff --git a/gdb/configure b/gdb/configure
|
|||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
@@ -9473,6 +9474,7 @@ case $host_os in
|
||||
@@ -9747,6 +9748,7 @@ case $host_os in
|
||||
esac
|
||||
|
||||
# These are the libraries checked by Readline.
|
||||
|
@ -37,7 +37,7 @@ diff --git a/gdb/configure b/gdb/configure
|
|||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5
|
||||
$as_echo_n "checking for library containing tgetent... " >&6; }
|
||||
if ${ac_cv_search_tgetent+:} false; then :
|
||||
@@ -9497,7 +9499,7 @@ return tgetent ();
|
||||
@@ -9771,7 +9773,7 @@ return tgetent ();
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
|
@ -49,7 +49,7 @@ diff --git a/gdb/configure b/gdb/configure
|
|||
diff --git a/gdb/configure.ac b/gdb/configure.ac
|
||||
--- a/gdb/configure.ac
|
||||
+++ b/gdb/configure.ac
|
||||
@@ -717,7 +717,8 @@ if test x"$prefer_curses" = xyes; then
|
||||
@@ -712,7 +712,8 @@ if test x"$prefer_curses" = xyes; then
|
||||
# search /usr/local/include, if ncurses is installed in /usr/local. A
|
||||
# default installation of ncurses on alpha*-dec-osf* will lead to such
|
||||
# a situation.
|
||||
|
@ -59,7 +59,7 @@ diff --git a/gdb/configure.ac b/gdb/configure.ac
|
|||
|
||||
if test "$ac_cv_search_waddstr" != no; then
|
||||
curses_found=yes
|
||||
@@ -759,7 +760,8 @@ case $host_os in
|
||||
@@ -754,7 +755,8 @@ case $host_os in
|
||||
esac
|
||||
|
||||
# These are the libraries checked by Readline.
|
||||
|
|
|
@ -0,0 +1,281 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Tom Tromey <tromey@adacore.com>
|
||||
Date: Fri, 23 Apr 2021 11:28:48 -0600
|
||||
Subject: gdb-gdb27743-psymtab-imported-unit.patch
|
||||
|
||||
;; Backport "Fix crash when expanding partial symtabs with DW_TAG_imported_unit"
|
||||
;; (Tom Tromey, gdb/27743)
|
||||
|
||||
From e7d77ce0c408e7019f9885b8be64c9cdb46dd312 Mon Sep 17 00:00:00 2001
|
||||
Subject: [PATCH] Fix crash when expanding partial symtabs with
|
||||
DW_TAG_imported_unit
|
||||
|
||||
PR gdb/27743 points out a gdb crash when expanding partial symtabs,
|
||||
where one of the compilation units uses DW_TAG_imported_unit.
|
||||
|
||||
The bug is that partial_map_expand_apply expects only to be called for
|
||||
the outermost psymtab. However, filename searching doesn't (and
|
||||
probably shouldn't) guarantee this. The fix is to walk upward to find
|
||||
the outermost CU.
|
||||
|
||||
A new test case is included. It is mostly copied from other test
|
||||
cases, which really sped up the effort.
|
||||
|
||||
This bug does not occur on trunk. There,
|
||||
psym_map_symtabs_matching_filename is gone, replaced by
|
||||
psymbol_functions::expand_symtabs_matching. When this find a match,
|
||||
it calls psymtab_to_symtab, which does this same upward walk.
|
||||
|
||||
Tested on x86-64 Fedora 32.
|
||||
|
||||
I propose checking in this patch on the gdb-10 branch, and just the
|
||||
new test case on trunk.
|
||||
|
||||
gdb/ChangeLog
|
||||
2021-04-23 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR gdb/27743:
|
||||
* psymtab.c (partial_map_expand_apply): Expand outermost psymtab.
|
||||
|
||||
gdb/testsuite/ChangeLog
|
||||
2021-04-23 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
PR gdb/27743:
|
||||
* gdb.dwarf2/imported-unit-bp.exp: New file.
|
||||
* gdb.dwarf2/imported-unit-bp-main.c: New file.
|
||||
* gdb.dwarf2/imported-unit-bp-alt.c: New file.
|
||||
|
||||
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
|
||||
--- a/gdb/psymtab.c
|
||||
+++ b/gdb/psymtab.c
|
||||
@@ -127,9 +127,10 @@ partial_map_expand_apply (struct objfile *objfile,
|
||||
{
|
||||
struct compunit_symtab *last_made = objfile->compunit_symtabs;
|
||||
|
||||
- /* Shared psymtabs should never be seen here. Instead they should
|
||||
- be handled properly by the caller. */
|
||||
- gdb_assert (pst->user == NULL);
|
||||
+ /* We may see a shared psymtab here, but we want to expand the
|
||||
+ outermost symtab. */
|
||||
+ while (pst->user != nullptr)
|
||||
+ pst = pst->user;
|
||||
|
||||
/* Don't visit already-expanded psymtabs. */
|
||||
if (pst->readin_p (objfile))
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp-alt.c b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-alt.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-alt.c
|
||||
@@ -0,0 +1,50 @@
|
||||
+/* Copyright 2020-2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+/* Used to insert labels with which we can build a fake line table. */
|
||||
+#define LL(N) asm ("line_label_" #N ": .globl line_label_" #N)
|
||||
+
|
||||
+volatile int var;
|
||||
+volatile int bar;
|
||||
+
|
||||
+/* Generate some code to take up some space. */
|
||||
+#define FILLER do { \
|
||||
+ var = 99; \
|
||||
+} while (0)
|
||||
+
|
||||
+int
|
||||
+func (void)
|
||||
+{ /* func prologue */
|
||||
+ asm ("func_label: .globl func_label");
|
||||
+ LL (1); // F1, Ln 16
|
||||
+ FILLER;
|
||||
+ LL (2); // F1, Ln 17
|
||||
+ FILLER;
|
||||
+ LL (3); // F2, Ln 21
|
||||
+ FILLER;
|
||||
+ LL (4); // F2, Ln 22 // F1, Ln 18, !S
|
||||
+ FILLER;
|
||||
+ LL (5); // F1, Ln 19 !S
|
||||
+ FILLER;
|
||||
+ LL (6); // F1, Ln 20
|
||||
+ FILLER;
|
||||
+ LL (7);
|
||||
+ FILLER;
|
||||
+ return 0; /* func end */
|
||||
+}
|
||||
+
|
||||
+#ifdef WITHMAIN
|
||||
+int main () { return 0; }
|
||||
+#endif
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp-main.c b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-main.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp-main.c
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* This testcase is part of GDB, the GNU debugger.
|
||||
+
|
||||
+ Copyright 2004-2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+extern int func (void);
|
||||
+
|
||||
+int
|
||||
+main()
|
||||
+{
|
||||
+ return func ();
|
||||
+}
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/imported-unit-bp.exp
|
||||
@@ -0,0 +1,128 @@
|
||||
+# Copyright 2020-2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+# Test that "break /absolute/file:line" works ok with imported CUs.
|
||||
+
|
||||
+load_lib dwarf.exp
|
||||
+
|
||||
+# This test can only be run on targets which support DWARF-2 and use gas.
|
||||
+if {![dwarf2_support]} {
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+# The .c files use __attribute__.
|
||||
+if [get_compiler_info] {
|
||||
+ return -1
|
||||
+}
|
||||
+if !$gcc_compiled {
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+standard_testfile imported-unit-bp-alt.c .S imported-unit-bp-main.c
|
||||
+
|
||||
+set build_options {nodebug optimize=-O1}
|
||||
+
|
||||
+set asm_file [standard_output_file $srcfile2]
|
||||
+Dwarf::assemble $asm_file {
|
||||
+ global srcdir subdir srcfile srcfile
|
||||
+ global build_options
|
||||
+ declare_labels lines_label callee_subprog_label cu_label
|
||||
+
|
||||
+ get_func_info func "$build_options additional_flags=-DWITHMAIN"
|
||||
+
|
||||
+ cu {} {
|
||||
+ compile_unit {
|
||||
+ {language @DW_LANG_C}
|
||||
+ {name "<artificial>"}
|
||||
+ } {
|
||||
+ imported_unit {
|
||||
+ {import %$cu_label}
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cu {} {
|
||||
+ cu_label: compile_unit {
|
||||
+ {producer "gcc"}
|
||||
+ {language @DW_LANG_C}
|
||||
+ {name ${srcfile}}
|
||||
+ {comp_dir "/tmp"}
|
||||
+ {low_pc 0 addr}
|
||||
+ {stmt_list ${lines_label} DW_FORM_sec_offset}
|
||||
+ } {
|
||||
+ callee_subprog_label: subprogram {
|
||||
+ {external 1 flag}
|
||||
+ {name callee}
|
||||
+ {inline 3 data1}
|
||||
+ }
|
||||
+ subprogram {
|
||||
+ {external 1 flag}
|
||||
+ {name func}
|
||||
+ {low_pc $func_start addr}
|
||||
+ {high_pc "$func_start + $func_len" addr}
|
||||
+ } {
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ lines {version 2 default_is_stmt 1} lines_label {
|
||||
+ include_dir "/tmp"
|
||||
+ file_name "$srcfile" 1
|
||||
+
|
||||
+ program {
|
||||
+ {DW_LNE_set_address line_label_1}
|
||||
+ {DW_LNS_advance_line 15}
|
||||
+ {DW_LNS_copy}
|
||||
+
|
||||
+ {DW_LNE_set_address line_label_2}
|
||||
+ {DW_LNS_advance_line 1}
|
||||
+ {DW_LNS_copy}
|
||||
+
|
||||
+ {DW_LNE_set_address line_label_3}
|
||||
+ {DW_LNS_advance_line 4}
|
||||
+ {DW_LNS_copy}
|
||||
+
|
||||
+ {DW_LNE_set_address line_label_4}
|
||||
+ {DW_LNS_advance_line 1}
|
||||
+ {DW_LNS_copy}
|
||||
+
|
||||
+ {DW_LNS_advance_line -4}
|
||||
+ {DW_LNS_negate_stmt}
|
||||
+ {DW_LNS_copy}
|
||||
+
|
||||
+ {DW_LNE_set_address line_label_5}
|
||||
+ {DW_LNS_advance_line 1}
|
||||
+ {DW_LNS_copy}
|
||||
+
|
||||
+ {DW_LNE_set_address line_label_6}
|
||||
+ {DW_LNS_advance_line 1}
|
||||
+ {DW_LNS_negate_stmt}
|
||||
+ {DW_LNS_copy}
|
||||
+
|
||||
+ {DW_LNE_set_address line_label_7}
|
||||
+ {DW_LNE_end_sequence}
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+if { [prepare_for_testing "failed to prepare" ${testfile} \
|
||||
+ [list $srcfile $asm_file $srcfile3] $build_options] } {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+gdb_reinitialize_dir /tmp
|
||||
+
|
||||
+# Using an absolute path is important to see the bug.
|
||||
+gdb_test "break /tmp/${srcfile}:19" "Breakpoint .* file $srcfile, line .*"
|
|
@ -1,236 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-gnat-dwarf-crash-3of3.patch
|
||||
|
||||
;; Fix crash of -readnow /usr/lib/debug/usr/bin/gnatbind.debug (BZ 1069211).
|
||||
;;=push+jan
|
||||
|
||||
http://sourceware.org/ml/gdb-patches/2014-02/msg00731.html
|
||||
|
||||
--6TrnltStXW4iwmi0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Disposition: inline
|
||||
|
||||
Hi,
|
||||
|
||||
PR 16581:
|
||||
GDB crash on inherit_abstract_dies infinite recursion
|
||||
https://sourceware.org/bugzilla/show_bug.cgi?id=16581
|
||||
|
||||
fixed crash from an infinite recursion. But in rare cases the new code can
|
||||
now gdb_assert() due to weird DWARF file.
|
||||
|
||||
I do not yet fully understand why the DWARF is as it is but just GDB should
|
||||
never crash due to invalid DWARF anyway. The "invalid" DWARF I see only in
|
||||
Fedora GCC build, not in FSF GCC build, more info at:
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1069382
|
||||
http://people.redhat.com/jkratoch/gcc-debuginfo-4.8.2-7.fc20.x86_64-gnatbind.debug
|
||||
|
||||
Thanks,
|
||||
Jan
|
||||
|
||||
--6TrnltStXW4iwmi0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Disposition: inline; filename="complaint.patch"
|
||||
|
||||
gdb/
|
||||
2014-02-24 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* dwarf2read.c (process_die): Change gdb_assert to complaint.
|
||||
|
||||
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
|
||||
--- a/gdb/dwarf2read.c
|
||||
+++ b/gdb/dwarf2read.c
|
||||
@@ -10657,6 +10657,13 @@ private:
|
||||
static void
|
||||
process_die (struct die_info *die, struct dwarf2_cu *cu)
|
||||
{
|
||||
+ if (die->in_process)
|
||||
+ {
|
||||
+ complaint (_("DIE at 0x%s attempted to be processed twice"),
|
||||
+ sect_offset_str (die->sect_off));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
process_die_scope scope (die, cu);
|
||||
|
||||
switch (die->tag)
|
||||
diff --git a/gdb/infrun.c b/gdb/infrun.c
|
||||
--- a/gdb/infrun.c
|
||||
+++ b/gdb/infrun.c
|
||||
@@ -601,6 +601,13 @@ holding the child stopped. Try \"set detach-on-fork\" or \
|
||||
target_pid_to_str (process_ptid).c_str ());
|
||||
}
|
||||
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+ /* We should check PID_WAS_STOPPED and detach it stopped accordingly.
|
||||
+ In this point of code it cannot be 1 as we would not get FORK
|
||||
+ executed without CONTINUE first which resets PID_WAS_STOPPED.
|
||||
+ We would have to first TARGET_STOP and WAITPID it as with running
|
||||
+ inferior PTRACE_DETACH, SIGSTOP will ignore the signal. */
|
||||
+#endif
|
||||
target_detach (parent_inf, 0);
|
||||
}
|
||||
|
||||
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
|
||||
--- a/gdb/linux-nat.c
|
||||
+++ b/gdb/linux-nat.c
|
||||
@@ -189,6 +189,12 @@ struct linux_nat_target *linux_target;
|
||||
/* Does the current host support PTRACE_GETREGSET? */
|
||||
enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN;
|
||||
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+/* PID of the inferior stopped by SIGSTOP before attaching (or zero). */
|
||||
+static pid_t pid_was_stopped;
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static unsigned int debug_linux_nat;
|
||||
static void
|
||||
show_debug_linux_nat (struct ui_file *file, int from_tty,
|
||||
@@ -1030,6 +1036,9 @@ linux_nat_post_attach_wait (ptid_t ptid, int *signalled)
|
||||
if (debug_linux_nat)
|
||||
fprintf_unfiltered (gdb_stdlog,
|
||||
"LNPAW: Attaching to a stopped process\n");
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+ pid_was_stopped = ptid.pid ();
|
||||
+#endif
|
||||
|
||||
/* The process is definitely stopped. It is in a job control
|
||||
stop, unless the kernel predates the TASK_STOPPED /
|
||||
@@ -1361,6 +1370,25 @@ get_detach_signal (struct lwp_info *lp)
|
||||
return gdb_signal_to_host (signo);
|
||||
}
|
||||
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+ /* Workaround RHEL-5 kernel which has unreliable PTRACE_DETACH, SIGSTOP (that
|
||||
+ many TIDs are left unstopped). See RH Bug 496732. */
|
||||
+ if (lp->ptid.pid () == pid_was_stopped)
|
||||
+ {
|
||||
+ int err;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ err = kill_lwp (lp->ptid.lwp (), SIGSTOP);
|
||||
+ if (debug_linux_nat)
|
||||
+ {
|
||||
+ fprintf_unfiltered (gdb_stdlog,
|
||||
+ "SC: lwp kill %d %s\n",
|
||||
+ err,
|
||||
+ errno ? safe_strerror (errno) : "ERRNO-OK");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1509,6 +1537,10 @@ linux_nat_target::detach (inferior *inf, int from_tty)
|
||||
detach_one_lwp (main_lwp, &signo);
|
||||
|
||||
detach_success (inf);
|
||||
+
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+ pid_was_stopped = 0;
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1766,6 +1798,16 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
|
||||
return;
|
||||
}
|
||||
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+ /* At this point, we are going to resume the inferior and if we
|
||||
+ have attached to a stopped process, we no longer should leave
|
||||
+ it as stopped if the user detaches. PTID variable has PID set to LWP
|
||||
+ while we need to check the real PID here. */
|
||||
+
|
||||
+ if (!step && lp && pid_was_stopped == lp->ptid.pid ())
|
||||
+ pid_was_stopped = 0;
|
||||
+
|
||||
+#endif
|
||||
if (resume_many)
|
||||
iterate_over_lwps (ptid, [=] (struct lwp_info *info)
|
||||
{
|
||||
@@ -3770,6 +3812,10 @@ linux_nat_target::mourn_inferior ()
|
||||
|
||||
/* Let the arch-specific native code know this process is gone. */
|
||||
linux_target->low_forget_process (pid);
|
||||
+#ifdef NEED_DETACH_SIGSTOP
|
||||
+
|
||||
+ pid_was_stopped = 0;
|
||||
+#endif
|
||||
}
|
||||
|
||||
/* Convert a native/host siginfo object, into/from the siginfo in the
|
||||
diff --git a/gdb/testsuite/gdb.threads/attach-stopped.exp b/gdb/testsuite/gdb.threads/attach-stopped.exp
|
||||
--- a/gdb/testsuite/gdb.threads/attach-stopped.exp
|
||||
+++ b/gdb/testsuite/gdb.threads/attach-stopped.exp
|
||||
@@ -56,7 +56,65 @@ proc corefunc { threadtype } {
|
||||
gdb_reinitialize_dir $srcdir/$subdir
|
||||
gdb_load ${binfile}
|
||||
|
||||
- # Verify that we can attach to the stopped process.
|
||||
+ # Verify that we can attach to the process by first giving its
|
||||
+ # executable name via the file command, and using attach with the
|
||||
+ # process ID.
|
||||
+
|
||||
+ set test "$threadtype: set file, before attach1 to stopped process"
|
||||
+ gdb_test_multiple "file $binfile" "$test" {
|
||||
+ -re "Load new symbol table from.*y or n. $" {
|
||||
+ gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \
|
||||
+ "$test (re-read)"
|
||||
+ }
|
||||
+ -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" {
|
||||
+ pass "$test"
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ set test "$threadtype: attach1 to stopped, after setting file"
|
||||
+ gdb_test_multiple "attach $testpid" "$test" {
|
||||
+ -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
|
||||
+ pass "$test"
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ # ".*sleep.*clone.*" would fail on s390x as bt stops at START_THREAD there.
|
||||
+ if {[string equal $threadtype threaded]} {
|
||||
+ gdb_test "thread apply all bt" ".*sleep.*start_thread.*" "$threadtype: attach1 to stopped bt"
|
||||
+ } else {
|
||||
+ gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach1 to stopped bt"
|
||||
+ }
|
||||
+
|
||||
+ # Exit and detach the process.
|
||||
+
|
||||
+ gdb_exit
|
||||
+
|
||||
+ # Avoid some race:
|
||||
+ sleep 2
|
||||
+
|
||||
+ if [catch {open /proc/${testpid}/status r} fileid] {
|
||||
+ set line2 "NOTFOUND"
|
||||
+ } else {
|
||||
+ gets $fileid line1;
|
||||
+ gets $fileid line2;
|
||||
+ close $fileid;
|
||||
+ }
|
||||
+
|
||||
+ set test "$threadtype: attach1, exit leaves process stopped"
|
||||
+ if {[string match "*(stopped)*" $line2]} {
|
||||
+ pass $test
|
||||
+ } else {
|
||||
+ fail $test
|
||||
+ }
|
||||
+
|
||||
+ # At this point, the process should still be stopped
|
||||
+
|
||||
+ gdb_start
|
||||
+ gdb_reinitialize_dir $srcdir/$subdir
|
||||
+ gdb_load ${binfile}
|
||||
+
|
||||
+ # Verify that we can attach to the process just by giving the
|
||||
+ # process ID.
|
||||
|
||||
set test "$threadtype: attach2 to stopped, after setting file"
|
||||
gdb_test_multiple "attach $testpid" "$test" {
|
|
@ -1,46 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-jit-reader-multilib.patch
|
||||
|
||||
;; Fix jit-reader.h for multi-lib.
|
||||
;;=push+jan
|
||||
|
||||
diff --git a/gdb/configure b/gdb/configure
|
||||
--- a/gdb/configure
|
||||
+++ b/gdb/configure
|
||||
@@ -9694,10 +9694,12 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
-if test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then
|
||||
- TARGET_PTR="unsigned long"
|
||||
-elif test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then
|
||||
+# Try to keep TARGET_PTR the same across archs so that jit-reader.h file
|
||||
+# content is the same for multilib distributions.
|
||||
+if test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then
|
||||
TARGET_PTR="unsigned long long"
|
||||
+elif test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then
|
||||
+ TARGET_PTR="unsigned long"
|
||||
elif test "x${ac_cv_sizeof_unsigned___int128}" = "x16"; then
|
||||
TARGET_PTR="unsigned __int128"
|
||||
else
|
||||
diff --git a/gdb/configure.ac b/gdb/configure.ac
|
||||
--- a/gdb/configure.ac
|
||||
+++ b/gdb/configure.ac
|
||||
@@ -808,10 +808,12 @@ AC_CHECK_SIZEOF(unsigned long long)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(unsigned __int128)
|
||||
|
||||
-if test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then
|
||||
- TARGET_PTR="unsigned long"
|
||||
-elif test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then
|
||||
+# Try to keep TARGET_PTR the same across archs so that jit-reader.h file
|
||||
+# content is the same for multilib distributions.
|
||||
+if test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then
|
||||
TARGET_PTR="unsigned long long"
|
||||
+elif test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then
|
||||
+ TARGET_PTR="unsigned long"
|
||||
elif test "x${ac_cv_sizeof_unsigned___int128}" = "x16"; then
|
||||
TARGET_PTR="unsigned __int128"
|
||||
else
|
|
@ -6,30 +6,6 @@ Subject: gdb-linux_perf-bundle.patch
|
|||
;; [dts+el7] [x86*] Bundle linux_perf.h for libipt (RH BZ 1256513).
|
||||
;;=fedora
|
||||
|
||||
diff --git a/gdb/configure b/gdb/configure
|
||||
--- a/gdb/configure
|
||||
+++ b/gdb/configure
|
||||
@@ -11905,7 +11905,7 @@ else
|
||||
|
||||
#include <linux/perf_event.h>
|
||||
#ifndef PERF_ATTR_SIZE_VER5
|
||||
-# error
|
||||
+// error // PERF_ATTR_SIZE_VER5_BUNDLE is not available here - Fedora+RHEL
|
||||
#endif
|
||||
|
||||
_ACEOF
|
||||
diff --git a/gdb/configure.ac b/gdb/configure.ac
|
||||
--- a/gdb/configure.ac
|
||||
+++ b/gdb/configure.ac
|
||||
@@ -1414,7 +1414,7 @@ else
|
||||
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <linux/perf_event.h>
|
||||
#ifndef PERF_ATTR_SIZE_VER5
|
||||
-# error
|
||||
+// error // PERF_ATTR_SIZE_VER5_BUNDLE is not available here - Fedora+RHEL
|
||||
#endif
|
||||
]])], [perf_event=yes], [perf_event=no])
|
||||
if test "$perf_event" != yes; then
|
||||
diff --git a/gdb/gdb.c b/gdb/gdb.c
|
||||
--- a/gdb/gdb.c
|
||||
+++ b/gdb/gdb.c
|
||||
|
@ -234,3 +210,15 @@ diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h
|
|||
struct target_ops;
|
||||
|
||||
#if HAVE_LINUX_PERF_EVENT_H
|
||||
diff --git a/gdbsupport/common.m4 b/gdbsupport/common.m4
|
||||
--- a/gdbsupport/common.m4
|
||||
+++ b/gdbsupport/common.m4
|
||||
@@ -145,7 +145,7 @@ AC_DEFUN([GDB_AC_COMMON], [
|
||||
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <linux/perf_event.h>
|
||||
#ifndef PERF_ATTR_SIZE_VER5
|
||||
- # error
|
||||
+ // error // PERF_ATTR_SIZE_VER5_BUNDLE is not available here - Fedora+RHEL
|
||||
#endif
|
||||
]])], [perf_event=yes], [perf_event=no])
|
||||
if test "$perf_event" != yes; then
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-moribund-utrace-workaround.patch
|
||||
|
||||
;; Workaround non-stop moribund locations exploited by kernel utrace (BZ 590623).
|
||||
;;=push+jan: Currently it is still not fully safe.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=590623
|
||||
http://sources.redhat.com/bugzilla/show_bug.cgi?id=11593
|
||||
|
||||
Bug in FSF GDB exploited by the ptrace-on-utrace interaction.
|
||||
|
||||
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
|
||||
--- a/gdb/breakpoint.c
|
||||
+++ b/gdb/breakpoint.c
|
||||
@@ -11904,6 +11904,8 @@ update_global_location_list (enum ugll_insert_mode insert_mode)
|
||||
traps we can no longer explain. */
|
||||
|
||||
old_loc->events_till_retirement = 3 * (thread_count () + 1);
|
||||
+ /* Red Hat Bug 590623. */
|
||||
+ old_loc->events_till_retirement *= 10;
|
||||
old_loc->owner = NULL;
|
||||
|
||||
moribund_locations.push_back (old_loc);
|
|
@ -1,49 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Wed, 8 Apr 2020 16:15:52 -0400
|
||||
Subject: gdb-rhbz1818011-bfd-gcc10-error.patch
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
;; Fix int conversion error from bfd/elf.c when compiling with gcc 10
|
||||
|
||||
Original commit message from H.J. Lu <hjl.tools@gmail.com> is below:
|
||||
|
||||
bfd: Change num_group to unsigned int
|
||||
|
||||
elf.c failed with to with GCC 10 as of
|
||||
|
||||
commit 906b3eb9df6c577d3f6e9c3ea5c9d7e4d1e90536
|
||||
Author: Martin Liska <mliska@suse.cz>
|
||||
Date: Tue Mar 24 11:40:10 2020 +0100
|
||||
|
||||
Improve endianess detection.
|
||||
|
||||
PR lto/94249
|
||||
* plugin-api.h: Add more robust endianess detection.
|
||||
|
||||
binutils-gdb/bfd/elf.c: In function ‘setup_group’:
|
||||
binutils-gdb/bfd/elf.c:740:35: error: overflow in conversion from ‘unsigned int’ to ‘int’ changes value from ‘num_group = 4294967295’ to ‘-1’ [-Werror=overflow]
|
||||
740 | elf_tdata (abfd)->num_group = num_group = -1;
|
||||
| ^~~~~~~~~
|
||||
cc1: all warnings being treated as errors
|
||||
make[2]: *** [Makefile:1608: elf.lo] Error 1
|
||||
|
||||
Change num_group in elf_obj_tdata to unsigned int to compile with GCC 10.
|
||||
|
||||
PR binutils/25717
|
||||
* elf-bfd.h (elf_obj_tdata): Change num_group to unsigned int.
|
||||
|
||||
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
|
||||
--- a/bfd/elf-bfd.h
|
||||
+++ b/bfd/elf-bfd.h
|
||||
@@ -1937,7 +1937,7 @@ struct elf_obj_tdata
|
||||
struct sdt_note *sdt_note_head;
|
||||
|
||||
Elf_Internal_Shdr **group_sect_ptr;
|
||||
- int num_group;
|
||||
+ unsigned int num_group;
|
||||
|
||||
/* Index into group_sect_ptr, updated by setup_group when finding a
|
||||
section's group. Used to optimize subsequent group searches. */
|
|
@ -1,70 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Thu, 16 Apr 2020 05:27:26 -0700
|
||||
Subject: gdb-rhbz1822715-fix-python-deprecation.patch
|
||||
|
||||
;; Backport fix for deprecation of PyEval_InitThreads in Python 3.9.
|
||||
|
||||
Fix compilation of python/python.c for Python 3.9
|
||||
|
||||
This commit fixes a compilation warning/error when building GDB
|
||||
with Python 3.9:
|
||||
|
||||
g++ -x c++ -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -DDNF_DEBUGINFO_INSTALL -I. -I../../gdb -I../../gdb/config -DLOCALEDIR="\"/usr/share/locale\"" -DHAVE_CONFIG_H -I../../gdb/../include/opcode -I../bfd -I../../gdb/../bfd -I../../gdb/../include -I../libdecnumber -I../../gdb/../libdecnumber -I../../gdb/../gnulib/import -I../gnulib/import -DTUI=1 -I/usr/include/guile/2.0 -pthread -I/usr/include/python3.9 -I/usr/include/python3.9 -I../../gdb/.. -pthread -Wall -Wpointer-arith -Wno-unused -Wunused-value -Wunused-variable -Wunused-function -Wno-switch -Wno-char-subscripts -Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable -Wno-sign-compare -Wno-error=maybe-uninitialized -Wno-mismatched-tags -Wsuggest-override -Wimplicit-fallthrough=3 -Wduplicated-cond -Wshadow=local -Wdeprecated-copy -Wdeprecated-copy-dtor -Wredundant-move -Wformat -Wformat-nonliteral -Wno-unused -Werror -c -o ser-tcp.o -MT ser-tcp.o -MMD -MP -MF ./.deps/ser-tcp.Tpo ../../gdb/ser-tcp.c
|
||||
../../gdb/python/python.c: In function 'bool do_start_initialization()':
|
||||
../../gdb/python/python.c:1621:23: error: 'void PyEval_InitThreads()' is deprecated [-Werror=deprecated-declarations]
|
||||
1621 | PyEval_InitThreads ();
|
||||
| ^
|
||||
In file included from /usr/include/python3.9/Python.h:141,
|
||||
from ../../gdb/python/python-internal.h:86,
|
||||
from ../../gdb/python/python.c:92:
|
||||
/usr/include/python3.9/ceval.h:132:37: note: declared here
|
||||
132 | Py_DEPRECATED(3.9) PyAPI_FUNC(void) PyEval_InitThreads(void);
|
||||
| ^~~~~~~~~~~~~~~~~~
|
||||
|
||||
Information about the deprecated function can be found here:
|
||||
|
||||
https://docs.python.org/3.9/whatsnew/3.9.html#deprecated
|
||||
|
||||
Specifically, with regard to PyEval_InitThreads(), it says:
|
||||
|
||||
The PyEval_InitThreads() and PyEval_ThreadsInitialized() functions
|
||||
are now deprecated and will be removed in Python 3.11. Calling
|
||||
PyEval_InitThreads() now does nothing. The GIL is initialized by
|
||||
Py_Initialize() since Python 3.7. (Contributed by Victor Stinner
|
||||
in bpo-39877.)
|
||||
|
||||
I chose to disable the call with a #if test using PY_VERSION_HEX.
|
||||
There is precedent for use of PY_VERSION_HEX; it's used in two places
|
||||
in python-internal.h. I noticed that under certain circumstances
|
||||
python-internal.h defines PyEval_InitThreads to be nothing, which
|
||||
accomplishes the same thing. I considered doing something similar for
|
||||
this case, but decided against it because, at some point in the future,
|
||||
the presence of PyEval_InitThreads() without some explanation will be
|
||||
confusing to a reader who won't be able to find PyEval_InitThreads in
|
||||
the current (future for us) Python API. IMO, use of the #if along
|
||||
with an accompanying comment seemed more straightforward.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* python/python.c (do_start_initialization): Don't call
|
||||
PyEval_InitThreads for Python 3.9 and beyond.
|
||||
|
||||
Change-Id: I0679fc10b6b76761a99538568f13188c6d8014e0
|
||||
|
||||
diff --git a/gdb/python/python.c b/gdb/python/python.c
|
||||
--- a/gdb/python/python.c
|
||||
+++ b/gdb/python/python.c
|
||||
@@ -1618,7 +1618,12 @@ do_start_initialization ()
|
||||
#endif
|
||||
|
||||
Py_Initialize ();
|
||||
+#if PY_VERSION_HEX < 0x03090000
|
||||
+ /* PyEval_InitThreads became deprecated in Python 3.9 and will
|
||||
+ be removed in Python 3.11. Prior to Python 3.7, this call was
|
||||
+ required to initialize the GIL. */
|
||||
PyEval_InitThreads ();
|
||||
+#endif
|
||||
|
||||
#ifdef IS_PY3K
|
||||
gdb_module = PyImport_ImportModule ("_gdb");
|
|
@ -1,224 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Keith Seitz <keiths@redhat.com>
|
||||
Date: Thu, 4 Jun 2020 17:16:48 -0700
|
||||
Subject: gdb-rhbz1829702-fix-python39.patch
|
||||
|
||||
;; Backport "Fix Python 3.9 related runtime problems"
|
||||
;; Kevin Buettner <kevinb@redhat.com> and Keith Seitz <keiths@redhat.com>
|
||||
|
||||
commit c47bae859a5af0d95224d90000df0e529f7c5aa0
|
||||
Author: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Wed May 27 20:05:40 2020 -0700
|
||||
|
||||
Fix Python3.9 related runtime problems
|
||||
|
||||
Python3.9b1 is now available on Rawhide. GDB w/ Python 3.9 support
|
||||
can be built using the configure switch -with-python=/usr/bin/python3.9.
|
||||
|
||||
Attempting to run gdb/Python3.9 segfaults on startup:
|
||||
|
||||
#0 0x00007ffff7b0582c in PyEval_ReleaseLock () from /lib64/libpython3.9
|
||||
.so.1.0
|
||||
#1 0x000000000069ccbf in do_start_initialization ()
|
||||
at worktree-test1/gdb/python/python.c:1789
|
||||
#2 _initialize_python ()
|
||||
at worktree-test1/gdb/python/python.c:1877
|
||||
#3 0x00000000007afb0a in initialize_all_files () at init.c:237
|
||||
...
|
||||
|
||||
Consulting the the documentation...
|
||||
|
||||
https://docs.python.org/3/c-api/init.html
|
||||
|
||||
...we find that PyEval_ReleaseLock() has been deprecated since version
|
||||
3.2. It recommends using PyEval_SaveThread or PyEval_ReleaseThread()
|
||||
instead. In do_start_initialization, in gdb/python/python.c, we
|
||||
can replace the calls to PyThreadState_Swap() and PyEval_ReleaseLock()
|
||||
with a single call to PyEval_SaveThread. (Thanks to Keith Seitz
|
||||
for working this out.)
|
||||
|
||||
With that in place, GDB gets a little bit further. It still dies
|
||||
on startup, but the backtrace is different:
|
||||
|
||||
#0 0x00007ffff7b04306 in PyOS_InterruptOccurred ()
|
||||
from /lib64/libpython3.9.so.1.0
|
||||
#1 0x0000000000576e86 in check_quit_flag ()
|
||||
at worktree-test1/gdb/extension.c:776
|
||||
#2 0x0000000000576f8a in set_active_ext_lang (now_active=now_active@entry=0x983c00 <extension_language_python>)
|
||||
at worktree-test1/gdb/extension.c:705
|
||||
#3 0x000000000069d399 in gdbpy_enter::gdbpy_enter (this=0x7fffffffd2d0,
|
||||
gdbarch=0x0, language=0x0)
|
||||
at worktree-test1/gdb/python/python.c:211
|
||||
#4 0x0000000000686e00 in python_new_inferior (inf=0xddeb10)
|
||||
at worktree-test1/gdb/python/py-inferior.c:251
|
||||
#5 0x00000000005d9fb9 in std::function<void (inferior*)>::operator()(inferior*) const (__args#0=<optimized out>, this=0xccad20)
|
||||
at /usr/include/c++/10/bits/std_function.h:617
|
||||
#6 gdb::observers::observable<inferior*>::notify (args#0=0xddeb10,
|
||||
this=<optimized out>)
|
||||
at worktree-test1/gdb/../gdbsupport/observable.h:106
|
||||
#7 add_inferior_silent (pid=0)
|
||||
at worktree-test1/gdb/inferior.c:113
|
||||
#8 0x00000000005dbcb8 in initialize_inferiors ()
|
||||
at worktree-test1/gdb/inferior.c:947
|
||||
...
|
||||
|
||||
We checked with some Python Developers and were told that we should
|
||||
acquire the GIL prior to calling any Python C API function. We
|
||||
definitely don't have the GIL for calls of PyOS_InterruptOccurred().
|
||||
|
||||
I moved class_gdbpy_gil earlier in the file and use it in
|
||||
gdbpy_check_quit_flag() to acquire (and automatically release) the
|
||||
GIL.
|
||||
|
||||
With those changes in place, I was able to run to a GDB prompt. But,
|
||||
when trying to quit, it segfaulted again due to due to some other
|
||||
problems with gdbpy_check_quit_flag():
|
||||
|
||||
Thread 1 "gdb" received signal SIGSEGV, Segmentation fault.
|
||||
0x00007ffff7bbab0c in new_threadstate () from /lib64/libpython3.9.so.1.0
|
||||
(top-gdb) bt 8
|
||||
#0 0x00007ffff7bbab0c in new_threadstate () from /lib64/libpython3.9.so.1.0
|
||||
#1 0x00007ffff7afa5ea in PyGILState_Ensure.cold ()
|
||||
from /lib64/libpython3.9.so.1.0
|
||||
#2 0x000000000069b58c in gdbpy_gil::gdbpy_gil (this=<synthetic pointer>)
|
||||
at worktree-test1/gdb/python/python.c:278
|
||||
#3 gdbpy_check_quit_flag (extlang=<optimized out>)
|
||||
at worktree-test1/gdb/python/python.c:278
|
||||
#4 0x0000000000576e96 in check_quit_flag ()
|
||||
at worktree-test1/gdb/extension.c:776
|
||||
#5 0x000000000057700c in restore_active_ext_lang (previous=0xe9c050)
|
||||
at worktree-test1/gdb/extension.c:729
|
||||
#6 0x000000000088913a in do_my_cleanups (
|
||||
pmy_chain=0xc31870 <final_cleanup_chain>,
|
||||
old_chain=0xae5720 <sentinel_cleanup>)
|
||||
at worktree-test1/gdbsupport/cleanups.cc:131
|
||||
#7 do_final_cleanups ()
|
||||
at worktree-test1/gdbsupport/cleanups.cc:143
|
||||
|
||||
In this case, we're trying to call a Python C API function after
|
||||
Py_Finalize() has been called from finalize_python(). I made
|
||||
finalize_python set gdb_python_initialized to false and then cause
|
||||
check_quit_flag() to return early when it's false.
|
||||
|
||||
With these changes in place, GDB seems to be working again with
|
||||
Python3.9b1. I think it likely that there are other problems lurking.
|
||||
I wouldn't be surprised to find that there are other calls into Python
|
||||
where we don't first make sure that we have the GIL. Further changes
|
||||
may well be needed.
|
||||
|
||||
I see no regressions testing on Rawhide using a GDB built with the
|
||||
default Python version (3.8.3) versus one built using Python 3.9b1.
|
||||
|
||||
I've also tested on Fedora 28, 29, 30, 31, and 32 (all x86_64) using
|
||||
the default (though updated) system installed versions of Python on
|
||||
those OSes. This means that I've tested against Python versions
|
||||
2.7.15, 2.7.17, 2.7.18, 3.7.7, 3.8.2, and 3.8.3. In each case GDB
|
||||
still builds without problem and shows no regressions after applying
|
||||
this patch.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
2020-MM-DD Kevin Buettner <kevinb@redhat.com>
|
||||
Keith Seitz <keiths@redhat.com>
|
||||
|
||||
* python/python.c (do_start_initialization): For Python 3.9 and
|
||||
later, call PyEval_SaveThread instead of PyEval_ReleaseLock.
|
||||
(class gdbpy_gil): Move to earlier in file.
|
||||
(finalize_python): Set gdb_python_initialized.
|
||||
(gdbpy_check_quit_flag): Acquire GIL via gdbpy_gil. Return early
|
||||
when not initialized.
|
||||
|
||||
diff --git a/gdb/python/python.c b/gdb/python/python.c
|
||||
--- a/gdb/python/python.c
|
||||
+++ b/gdb/python/python.c
|
||||
@@ -234,6 +234,30 @@ gdbpy_enter::~gdbpy_enter ()
|
||||
PyGILState_Release (m_state);
|
||||
}
|
||||
|
||||
+/* A helper class to save and restore the GIL, but without touching
|
||||
+ the other globals that are handled by gdbpy_enter. */
|
||||
+
|
||||
+class gdbpy_gil
|
||||
+{
|
||||
+public:
|
||||
+
|
||||
+ gdbpy_gil ()
|
||||
+ : m_state (PyGILState_Ensure ())
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ ~gdbpy_gil ()
|
||||
+ {
|
||||
+ PyGILState_Release (m_state);
|
||||
+ }
|
||||
+
|
||||
+ DISABLE_COPY_AND_ASSIGN (gdbpy_gil);
|
||||
+
|
||||
+private:
|
||||
+
|
||||
+ PyGILState_STATE m_state;
|
||||
+};
|
||||
+
|
||||
/* Set the quit flag. */
|
||||
|
||||
static void
|
||||
@@ -247,6 +271,10 @@ gdbpy_set_quit_flag (const struct extension_language_defn *extlang)
|
||||
static int
|
||||
gdbpy_check_quit_flag (const struct extension_language_defn *extlang)
|
||||
{
|
||||
+ if (!gdb_python_initialized)
|
||||
+ return 0;
|
||||
+
|
||||
+ gdbpy_gil gil;
|
||||
return PyOS_InterruptOccurred ();
|
||||
}
|
||||
|
||||
@@ -924,30 +952,6 @@ gdbpy_source_script (const struct extension_language_defn *extlang,
|
||||
|
||||
/* Posting and handling events. */
|
||||
|
||||
-/* A helper class to save and restore the GIL, but without touching
|
||||
- the other globals that are handled by gdbpy_enter. */
|
||||
-
|
||||
-class gdbpy_gil
|
||||
-{
|
||||
-public:
|
||||
-
|
||||
- gdbpy_gil ()
|
||||
- : m_state (PyGILState_Ensure ())
|
||||
- {
|
||||
- }
|
||||
-
|
||||
- ~gdbpy_gil ()
|
||||
- {
|
||||
- PyGILState_Release (m_state);
|
||||
- }
|
||||
-
|
||||
- DISABLE_COPY_AND_ASSIGN (gdbpy_gil);
|
||||
-
|
||||
-private:
|
||||
-
|
||||
- PyGILState_STATE m_state;
|
||||
-};
|
||||
-
|
||||
/* A single event. */
|
||||
struct gdbpy_event
|
||||
{
|
||||
@@ -1548,6 +1552,7 @@ finalize_python (void *ignore)
|
||||
|
||||
Py_Finalize ();
|
||||
|
||||
+ gdb_python_initialized = false;
|
||||
restore_active_ext_lang (previous_active);
|
||||
}
|
||||
|
||||
@@ -1720,8 +1725,7 @@ do_start_initialization ()
|
||||
return false;
|
||||
|
||||
/* Release the GIL while gdb runs. */
|
||||
- PyThreadState_Swap (NULL);
|
||||
- PyEval_ReleaseLock ();
|
||||
+ PyEval_SaveThread ();
|
||||
|
||||
make_final_cleanup (finalize_python, NULL);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,123 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Keith Seitz <keiths@redhat.com>
|
||||
Date: Mon, 8 Jun 2020 11:33:47 -0700
|
||||
Subject: gdb-rhbz1844458-use-fputX_unfiltered.patch
|
||||
|
||||
;; Fix fput?_unfiltered functions
|
||||
;; RH BZ 1844458 (Sergio Durigan Junior and Tom Tromey)
|
||||
|
||||
From 9effb44ccbf50c16da66aaab5fd535fe17e38e32 Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
Date: Wed, 19 Feb 2020 16:40:48 -0500
|
||||
Subject: [PATCH] Make '{putchar,fputc}_unfiltered' use 'fputs_unfiltered'
|
||||
|
||||
There is currently a regression when using
|
||||
'{putchar,fputc}_unfiltered' with 'puts_unfiltered' which was
|
||||
introduced by one of the commits that reworked the unfiltered print
|
||||
code.
|
||||
|
||||
The regression makes it impossible to use '{putchar,fputc}_unfiltered'
|
||||
with 'puts_unfiltered', because the former writes directly to the
|
||||
ui_file stream using 'stream->write', while the latter uses a buffered
|
||||
mechanism (see 'wrap_buffer') and delays the printing.
|
||||
|
||||
If you do a quick & dirty hack on e.g. top.c:show_gdb_datadir:
|
||||
|
||||
@@ -2088,6 +2088,13 @@ static void
|
||||
show_gdb_datadir (struct ui_file *file, int from_tty,
|
||||
struct cmd_list_element *c, const char *value)
|
||||
{
|
||||
+ putchar_unfiltered ('\n');
|
||||
+ puts_unfiltered ("TEST");
|
||||
+ putchar_unfiltered ('>');
|
||||
+ puts_unfiltered ("PUTS");
|
||||
+ puts_unfiltered ("PUTS");
|
||||
+ putchar_unfiltered ('\n');
|
||||
|
||||
rebuild GDB and invoke the "show data-directory" command, you will
|
||||
see:
|
||||
|
||||
(gdb) show data-directory
|
||||
|
||||
>
|
||||
TESTPUTSGDB's data directory is "/usr/local/share/gdb".
|
||||
|
||||
Note how the '>' was printed before the output, and "TEST" and "PUTS"
|
||||
were printed together.
|
||||
|
||||
My first attempt to fix this was to always call 'flush_wrap_buffer' at
|
||||
the end of 'fputs_maybe_filtered', since it seemed to me that the
|
||||
function should always print what was requested. But I wasn't sure
|
||||
this was the right thing to do, so I talked to Tom on IRC and he gave
|
||||
me another, simpler idea: make '{putchar,fputc}_unfiltered' call into
|
||||
the already existing 'fputs_unfiltered' function.
|
||||
|
||||
This patch implements the idea. I regtested it on the Buildbot, and
|
||||
no regressions were detected.
|
||||
|
||||
gdb/ChangeLog:
|
||||
2020-02-20 Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
Tom Tromey <tom@tromey.com>
|
||||
|
||||
* utils.c (fputs_maybe_filtered): Call 'stream->puts' instead
|
||||
of 'fputc_unfiltered'.
|
||||
(putchar_unfiltered): Call 'fputc_unfiltered'.
|
||||
(fputc_unfiltered): Call 'fputs_unfiltered'.
|
||||
|
||||
diff --git a/gdb/utils.c b/gdb/utils.c
|
||||
--- a/gdb/utils.c
|
||||
+++ b/gdb/utils.c
|
||||
@@ -1783,7 +1783,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
|
||||
newline -- if chars_per_line is right, we
|
||||
probably just overflowed anyway; if it's wrong,
|
||||
let us keep going. */
|
||||
- fputc_unfiltered ('\n', stream);
|
||||
+ /* XXX: The ideal thing would be to call
|
||||
+ 'stream->putc' here, but we can't because it
|
||||
+ currently calls 'fputc_unfiltered', which ends up
|
||||
+ calling us, which generates an infinite
|
||||
+ recursion. */
|
||||
+ stream->puts ("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1828,7 +1833,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
|
||||
wrap_here ((char *) 0); /* Spit out chars, cancel
|
||||
further wraps. */
|
||||
lines_printed++;
|
||||
- fputc_unfiltered ('\n', stream);
|
||||
+ /* XXX: The ideal thing would be to call
|
||||
+ 'stream->putc' here, but we can't because it
|
||||
+ currently calls 'fputc_unfiltered', which ends up
|
||||
+ calling us, which generates an infinite
|
||||
+ recursion. */
|
||||
+ stream->puts ("\n");
|
||||
lineptr++;
|
||||
}
|
||||
}
|
||||
@@ -1923,10 +1933,7 @@ fputs_highlighted (const char *str, const compiled_regex &highlight,
|
||||
int
|
||||
putchar_unfiltered (int c)
|
||||
{
|
||||
- char buf = c;
|
||||
-
|
||||
- ui_file_write (gdb_stdout, &buf, 1);
|
||||
- return c;
|
||||
+ return fputc_unfiltered (c, gdb_stdout);
|
||||
}
|
||||
|
||||
/* Write character C to gdb_stdout using GDB's paging mechanism and return C.
|
||||
@@ -1941,9 +1948,11 @@ putchar_filtered (int c)
|
||||
int
|
||||
fputc_unfiltered (int c, struct ui_file *stream)
|
||||
{
|
||||
- char buf = c;
|
||||
+ char buf[2];
|
||||
|
||||
- ui_file_write (stream, &buf, 1);
|
||||
+ buf[0] = c;
|
||||
+ buf[1] = 0;
|
||||
+ fputs_unfiltered (buf, stream);
|
||||
return c;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Keith Seitz <keiths@redhat.com>
|
||||
Date: Mon, 16 Nov 2020 12:42:09 -0500
|
||||
Subject: gdb-rhbz1898252-loadable-section-outside-ELF-segments.patch
|
||||
|
||||
;; Backport of "Exclude debuginfo files from 'outside of ELF segments'
|
||||
;; warning" (Keith Seitz)
|
||||
|
||||
Exclude debuginfo files from "outside of ELF segments" warning
|
||||
|
||||
When GDB loads an ELF file, it will warn when a section is not located
|
||||
in an ELF segment:
|
||||
|
||||
$ ./gdb -q -iex "set build-id-verbose 0" --ex "b systemctl_main" -ex "r" -batch --args systemctl kexec
|
||||
Breakpoint 1 at 0xc24d: file ../src/systemctl/systemctl.c, line 8752.
|
||||
warning: Loadable section ".note.gnu.property" outside of ELF segments
|
||||
in .gnu_debugdata for /lib64/libgcc_s.so.1
|
||||
[Thread debugging using libthread_db enabled]
|
||||
Using host libthread_db library "/lib64/libthread_db.so.1".
|
||||
warning: Loadable section ".note.gnu.property" outside of ELF segments
|
||||
in .gnu_debugdata for /lib64/libcap.so.2
|
||||
warning: Loadable section ".note.gnu.property" outside of ELF segments
|
||||
in .gnu_debugdata for /lib64/libacl.so.1
|
||||
warning: Loadable section ".note.gnu.property" outside of ELF segments
|
||||
in .gnu_debugdata for /lib64/libcryptsetup.so.12
|
||||
warning: Loadable section ".note.gnu.property" outside of ELF segments
|
||||
in .gnu_debugdata for /lib64/libgcrypt.so.20
|
||||
warning: Loadable section ".note.gnu.property" outside of ELF segments
|
||||
in .gnu_debugdata for /lib64/libip4tc.so.2
|
||||
[snip]
|
||||
This has feature has also been reported by various users, most notably
|
||||
the Fedora-EOL'd bug 1553086.
|
||||
|
||||
Mark Wielaard explains the issue quite nicely in
|
||||
|
||||
https://sourceware.org/bugzilla/show_bug.cgi?id=24717#c2
|
||||
|
||||
The short of it is, the ELF program headers for debuginfo files are
|
||||
not suited to this particular use case. Consequently, the warning
|
||||
generated above really is useless and should be ignored.
|
||||
|
||||
This patch follows the same heuristic that BFD itself uses.
|
||||
|
||||
gdb/ChangeLog
|
||||
2020-11-13 Keith Seitz <keiths@redhat.com>
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1553086
|
||||
* elfread.c (elf_symfile_segments): Omit "Loadable section ...
|
||||
outside of ELF segments" warning for debugin
|
||||
|
||||
diff --git a/gdb/elfread.c b/gdb/elfread.c
|
||||
--- a/gdb/elfread.c
|
||||
+++ b/gdb/elfread.c
|
||||
@@ -147,7 +147,12 @@ elf_symfile_segments (bfd *abfd)
|
||||
RealView) use SHT_NOBITS for uninitialized data. Since it is
|
||||
uninitialized, it doesn't need a program header. Such
|
||||
binaries are not relocatable. */
|
||||
- if (bfd_section_size (sect) > 0 && j == num_segments
|
||||
+
|
||||
+ /* Exclude debuginfo files from this warning, too, since those
|
||||
+ are often not strictly compliant with the standard. See, e.g.,
|
||||
+ ld/24717 for more discussion. */
|
||||
+ if (!is_debuginfo_file (abfd)
|
||||
+ && bfd_section_size (sect) > 0 && j == num_segments
|
||||
&& (bfd_section_flags (sect) & SEC_LOAD) != 0)
|
||||
warning (_("Loadable section \"%s\" outside of ELF segments"),
|
||||
bfd_section_name (sect));
|
|
@ -0,0 +1,593 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Pedro Alves <pedro@palves.net>
|
||||
Date: Fri, 30 Oct 2020 18:26:15 +0100
|
||||
Subject: gdb-rhbz1909902-frame_id_p-assert-1.patch
|
||||
|
||||
;; Backport fix for frame_id_p assertion failure (RH BZ 1909902).
|
||||
|
||||
Make scoped_restore_current_thread's cdtors exception free (RFC)
|
||||
|
||||
If the remote target closes while we're reading registers/memory for
|
||||
restoring the selected frame in scoped_restore_current_thread's dtor,
|
||||
the corresponding TARGET_CLOSE_ERROR error is swallowed by the
|
||||
scoped_restore_current_thread's dtor, because letting exceptions
|
||||
escape from a dtor is bad. It isn't great to lose that errors like
|
||||
that, though. I've been thinking about how to avoid it, and I came up
|
||||
with this patch.
|
||||
|
||||
The idea here is to make scoped_restore_current_thread's dtor do as
|
||||
little as possible, to avoid any work that might throw in the first
|
||||
place. And to do that, instead of having the dtor call
|
||||
restore_selected_frame, which re-finds the previously selected frame,
|
||||
just record the frame_id/level of the desired selected frame, and have
|
||||
get_selected_frame find the frame the next time it is called. In
|
||||
effect, this implements most of Cagney's suggestion, here:
|
||||
|
||||
/* On demand, create the selected frame and then return it. If the
|
||||
selected frame can not be created, this function prints then throws
|
||||
an error. When MESSAGE is non-NULL, use it for the error message,
|
||||
otherwize use a generic error message. */
|
||||
/* FIXME: cagney/2002-11-28: At present, when there is no selected
|
||||
frame, this function always returns the current (inner most) frame.
|
||||
It should instead, when a thread has previously had its frame
|
||||
selected (but not resumed) and the frame cache invalidated, find
|
||||
and then return that thread's previously selected frame. */
|
||||
extern struct frame_info *get_selected_frame (const char *message);
|
||||
|
||||
The only thing missing to fully implement that would be to make
|
||||
reinit_frame_cache just clear selected_frame instead of calling
|
||||
select_frame(NULL), and the call select_frame(NULL) explicitly in the
|
||||
places where we really wanted reinit_frame_cache to go back to the
|
||||
current frame too. That can done separately, though, I'm not
|
||||
proposing to do that in this patch.
|
||||
|
||||
Note that this patch renames restore_selected_frame to
|
||||
lookup_selected_frame, and adds a new restore_selected_frame function
|
||||
that doesn't throw, to be paired with the also-new save_selected_frame
|
||||
function.
|
||||
|
||||
There's a restore_selected_frame function in infrun.c that I think can
|
||||
be replaced by the new one in frame.c.
|
||||
|
||||
Also done in this patch is make the get_selected_frame's parameter be
|
||||
optional, so that we don't have to pass down nullptr explicitly all
|
||||
over the place.
|
||||
|
||||
lookup_selected_frame should really move from thread.c to frame.c, but
|
||||
I didn't do that here, just to avoid churn in the patch while it
|
||||
collects comments. I did make it extern and declared it in frame.h
|
||||
already, preparing for the move. I will do the move as a follow up
|
||||
patch if people agree with this approach.
|
||||
|
||||
Incidentally, this patch alone would fix the crashes fixed by the
|
||||
previous patches in the series, because with this,
|
||||
scoped_restore_current_thread's constructor doesn't throw either.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* blockframe.c (block_innermost_frame): Use get_selected_frame.
|
||||
* frame.c
|
||||
(scoped_restore_selected_frame::scoped_restore_selected_frame):
|
||||
Use save_selected_frame. Save language as well.
|
||||
(scoped_restore_selected_frame::~scoped_restore_selected_frame):
|
||||
Use restore_selected_frame, and restore language as well.
|
||||
(selected_frame_id, selected_frame_level): New.
|
||||
(selected_frame): Update comments.
|
||||
(save_selected_frame, restore_selected_frame): New.
|
||||
(get_selected_frame): Use lookup_selected_frame.
|
||||
(get_selected_frame_if_set): Delete.
|
||||
(select_frame): Record selected_frame_level and selected_frame_id.
|
||||
* frame.h (scoped_restore_selected_frame) <m_level, m_lang>: New
|
||||
fields.
|
||||
(get_selected_frame): Make 'message' parameter optional.
|
||||
(get_selected_frame_if_set): Delete declaration.
|
||||
(select_frame): Update comments.
|
||||
(save_selected_frame, restore_selected_frame)
|
||||
(lookup_selected_frame): Declare.
|
||||
* gdbthread.h (scoped_restore_current_thread) <m_lang>: New field.
|
||||
* infrun.c (struct infcall_control_state) <selected_frame_level>:
|
||||
New field.
|
||||
(save_infcall_control_state): Use save_selected_frame.
|
||||
(restore_selected_frame): Delete.
|
||||
(restore_infcall_control_state): Use restore_selected_frame.
|
||||
* stack.c (select_frame_command_core, frame_command_core): Use
|
||||
get_selected_frame.
|
||||
* thread.c (restore_selected_frame): Rename to ...
|
||||
(lookup_selected_frame): ... this and make extern. Select the
|
||||
current frame if the frame level is -1.
|
||||
(scoped_restore_current_thread::restore): Also restore the
|
||||
language.
|
||||
(scoped_restore_current_thread::~scoped_restore_current_thread):
|
||||
Don't try/catch.
|
||||
(scoped_restore_current_thread::scoped_restore_current_thread):
|
||||
Save the language as well. Use save_selected_frame.
|
||||
|
||||
Change-Id: I73fd1cfc40d8513c28e5596383b7ecd8bcfe700f
|
||||
|
||||
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
|
||||
--- a/gdb/blockframe.c
|
||||
+++ b/gdb/blockframe.c
|
||||
@@ -464,14 +464,10 @@ find_gnu_ifunc_target_type (CORE_ADDR resolver_funaddr)
|
||||
struct frame_info *
|
||||
block_innermost_frame (const struct block *block)
|
||||
{
|
||||
- struct frame_info *frame;
|
||||
-
|
||||
if (block == NULL)
|
||||
return NULL;
|
||||
|
||||
- frame = get_selected_frame_if_set ();
|
||||
- if (frame == NULL)
|
||||
- frame = get_current_frame ();
|
||||
+ frame_info *frame = get_selected_frame ();
|
||||
while (frame != NULL)
|
||||
{
|
||||
const struct block *frame_block = get_frame_block (frame, NULL);
|
||||
diff --git a/gdb/frame.c b/gdb/frame.c
|
||||
--- a/gdb/frame.c
|
||||
+++ b/gdb/frame.c
|
||||
@@ -317,17 +317,15 @@ frame_stash_invalidate (void)
|
||||
/* See frame.h */
|
||||
scoped_restore_selected_frame::scoped_restore_selected_frame ()
|
||||
{
|
||||
- m_fid = get_frame_id (get_selected_frame (NULL));
|
||||
+ m_lang = current_language->la_language;
|
||||
+ save_selected_frame (&m_fid, &m_level);
|
||||
}
|
||||
|
||||
/* See frame.h */
|
||||
scoped_restore_selected_frame::~scoped_restore_selected_frame ()
|
||||
{
|
||||
- frame_info *frame = frame_find_by_id (m_fid);
|
||||
- if (frame == NULL)
|
||||
- warning (_("Unable to restore previously selected frame."));
|
||||
- else
|
||||
- select_frame (frame);
|
||||
+ restore_selected_frame (m_fid, m_level);
|
||||
+ set_language (m_lang);
|
||||
}
|
||||
|
||||
/* Flag to control debugging. */
|
||||
@@ -1685,10 +1683,63 @@ get_current_frame (void)
|
||||
}
|
||||
|
||||
/* The "selected" stack frame is used by default for local and arg
|
||||
- access. May be zero, for no selected frame. */
|
||||
-
|
||||
+ access.
|
||||
+
|
||||
+ The "single source of truth" for the selected frame is the
|
||||
+ SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL pair.
|
||||
+
|
||||
+ Frame IDs can be saved/restored across reinitializing the frame
|
||||
+ cache, while frame_info pointers can't (frame_info objects are
|
||||
+ invalidated). If we know the corresponding frame_info object, it
|
||||
+ is cached in SELECTED_FRAME.
|
||||
+
|
||||
+ If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
|
||||
+ and the target has stack and is stopped, the selected frame is the
|
||||
+ current (innermost) frame. This means that SELECTED_FRAME_LEVEL is
|
||||
+ never 0 and SELECTED_FRAME_ID is never the ID of the innermost
|
||||
+ frame.
|
||||
+
|
||||
+ If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
|
||||
+ and the target has no stack or is executing, then there's no
|
||||
+ selected frame. */
|
||||
+static frame_id selected_frame_id = null_frame_id;
|
||||
+static int selected_frame_level = -1;
|
||||
+
|
||||
+/* The cached frame_info object pointing to the selected frame.
|
||||
+ Looked up on demand by get_selected_frame. */
|
||||
static struct frame_info *selected_frame;
|
||||
|
||||
+/* See frame.h. */
|
||||
+
|
||||
+void
|
||||
+save_selected_frame (frame_id *frame_id, int *frame_level)
|
||||
+ noexcept
|
||||
+{
|
||||
+ *frame_id = selected_frame_id;
|
||||
+ *frame_level = selected_frame_level;
|
||||
+}
|
||||
+
|
||||
+/* See frame.h. */
|
||||
+
|
||||
+void
|
||||
+restore_selected_frame (frame_id frame_id, int frame_level)
|
||||
+ noexcept
|
||||
+{
|
||||
+ /* save_selected_frame never returns level == 0, so we shouldn't see
|
||||
+ it here either. */
|
||||
+ gdb_assert (frame_level != 0);
|
||||
+
|
||||
+ /* FRAME_ID can be null_frame_id only IFF frame_level is -1. */
|
||||
+ gdb_assert ((frame_level == -1 && !frame_id_p (frame_id))
|
||||
+ || (frame_level != -1 && frame_id_p (frame_id)));
|
||||
+
|
||||
+ selected_frame_id = frame_id;
|
||||
+ selected_frame_level = frame_level;
|
||||
+
|
||||
+ /* Will be looked up later by get_selected_frame. */
|
||||
+ selected_frame = nullptr;
|
||||
+}
|
||||
+
|
||||
bool
|
||||
has_stack_frames ()
|
||||
{
|
||||
@@ -1715,9 +1766,7 @@ has_stack_frames ()
|
||||
return true;
|
||||
}
|
||||
|
||||
-/* Return the selected frame. Always non-NULL (unless there isn't an
|
||||
- inferior sufficient for creating a frame) in which case an error is
|
||||
- thrown. */
|
||||
+/* See frame.h. */
|
||||
|
||||
struct frame_info *
|
||||
get_selected_frame (const char *message)
|
||||
@@ -1726,24 +1775,14 @@ get_selected_frame (const char *message)
|
||||
{
|
||||
if (message != NULL && !has_stack_frames ())
|
||||
error (("%s"), message);
|
||||
- /* Hey! Don't trust this. It should really be re-finding the
|
||||
- last selected frame of the currently selected thread. This,
|
||||
- though, is better than nothing. */
|
||||
- select_frame (get_current_frame ());
|
||||
+
|
||||
+ lookup_selected_frame (selected_frame_id, selected_frame_level);
|
||||
}
|
||||
/* There is always a frame. */
|
||||
gdb_assert (selected_frame != NULL);
|
||||
return selected_frame;
|
||||
}
|
||||
|
||||
-/* If there is a selected frame, return it. Otherwise, return NULL. */
|
||||
-
|
||||
-struct frame_info *
|
||||
-get_selected_frame_if_set (void)
|
||||
-{
|
||||
- return selected_frame;
|
||||
-}
|
||||
-
|
||||
/* This is a variant of get_selected_frame() which can be called when
|
||||
the inferior does not have a frame; in that case it will return
|
||||
NULL instead of calling error(). */
|
||||
@@ -1756,12 +1795,42 @@ deprecated_safe_get_selected_frame (void)
|
||||
return get_selected_frame (NULL);
|
||||
}
|
||||
|
||||
-/* Select frame FI (or NULL - to invalidate the current frame). */
|
||||
+/* Select frame FI (or NULL - to invalidate the selected frame). */
|
||||
|
||||
void
|
||||
select_frame (struct frame_info *fi)
|
||||
{
|
||||
selected_frame = fi;
|
||||
+ selected_frame_level = frame_relative_level (fi);
|
||||
+ if (selected_frame_level == 0)
|
||||
+ {
|
||||
+ /* Treat the current frame especially -- we want to always
|
||||
+ save/restore it without warning, even if the frame ID changes
|
||||
+ (see lookup_selected_frame). E.g.:
|
||||
+
|
||||
+ // The current frame is selected, the target had just stopped.
|
||||
+ {
|
||||
+ scoped_restore_selected_frame restore_frame;
|
||||
+ some_operation_that_changes_the_stack ();
|
||||
+ }
|
||||
+ // scoped_restore_selected_frame's dtor runs, but the
|
||||
+ // original frame_id can't be found. No matter whether it
|
||||
+ // is found or not, we still end up with the now-current
|
||||
+ // frame selected. Warning in lookup_selected_frame in this
|
||||
+ // case seems pointless.
|
||||
+
|
||||
+ Also get_frame_id may access the target's registers/memory,
|
||||
+ and thus skipping get_frame_id optimizes the common case.
|
||||
+
|
||||
+ Saving the selected frame this way makes get_selected_frame
|
||||
+ and restore_current_frame return/re-select whatever frame is
|
||||
+ the innermost (current) then. */
|
||||
+ selected_frame_level = -1;
|
||||
+ selected_frame_id = null_frame_id;
|
||||
+ }
|
||||
+ else
|
||||
+ selected_frame_id = get_frame_id (fi);
|
||||
+
|
||||
/* NOTE: cagney/2002-05-04: FI can be NULL. This occurs when the
|
||||
frame is being invalidated. */
|
||||
|
||||
diff --git a/gdb/frame.h b/gdb/frame.h
|
||||
--- a/gdb/frame.h
|
||||
+++ b/gdb/frame.h
|
||||
@@ -186,8 +186,14 @@ class scoped_restore_selected_frame
|
||||
|
||||
private:
|
||||
|
||||
- /* The ID of the previously selected frame. */
|
||||
+ /* The ID and level of the previously selected frame. */
|
||||
struct frame_id m_fid;
|
||||
+ int m_level;
|
||||
+
|
||||
+ /* Save/restore the language as well, because selecting a frame
|
||||
+ changes the current language to the frame's language if "set
|
||||
+ language auto". */
|
||||
+ enum language m_lang;
|
||||
};
|
||||
|
||||
/* Methods for constructing and comparing Frame IDs. */
|
||||
@@ -316,24 +322,49 @@ extern bool has_stack_frames ();
|
||||
modifies the target invalidating the frame cache). */
|
||||
extern void reinit_frame_cache (void);
|
||||
|
||||
-/* On demand, create the selected frame and then return it. If the
|
||||
- selected frame can not be created, this function prints then throws
|
||||
- an error. When MESSAGE is non-NULL, use it for the error message,
|
||||
+/* Return the selected frame. Always returns non-NULL. If there
|
||||
+ isn't an inferior sufficient for creating a frame, an error is
|
||||
+ thrown. When MESSAGE is non-NULL, use it for the error message,
|
||||
otherwise use a generic error message. */
|
||||
/* FIXME: cagney/2002-11-28: At present, when there is no selected
|
||||
frame, this function always returns the current (inner most) frame.
|
||||
It should instead, when a thread has previously had its frame
|
||||
selected (but not resumed) and the frame cache invalidated, find
|
||||
and then return that thread's previously selected frame. */
|
||||
-extern struct frame_info *get_selected_frame (const char *message);
|
||||
-
|
||||
-/* If there is a selected frame, return it. Otherwise, return NULL. */
|
||||
-extern struct frame_info *get_selected_frame_if_set (void);
|
||||
+extern struct frame_info *get_selected_frame (const char *message = nullptr);
|
||||
|
||||
-/* Select a specific frame. NULL, apparently implies re-select the
|
||||
- inner most frame. */
|
||||
+/* Select a specific frame. NULL implies re-select the inner most
|
||||
+ frame. */
|
||||
extern void select_frame (struct frame_info *);
|
||||
|
||||
+/* Save the frame ID and frame level of the selected frame in FRAME_ID
|
||||
+ and FRAME_LEVEL, to be restored later with restore_selected_frame.
|
||||
+
|
||||
+ This is preferred over getting the same info out of
|
||||
+ get_selected_frame directly because this function does not create
|
||||
+ the selected-frame's frame_info object if it hasn't been created
|
||||
+ yet, and thus is more efficient and doesn't throw. */
|
||||
+extern void save_selected_frame (frame_id *frame_id, int *frame_level)
|
||||
+ noexcept;
|
||||
+
|
||||
+/* Restore selected frame as saved with save_selected_frame.
|
||||
+
|
||||
+ Does not try to find the corresponding frame_info object. Instead
|
||||
+ the next call to get_selected_frame will look it up and cache the
|
||||
+ result.
|
||||
+
|
||||
+ This function does not throw. It is designed to be safe to called
|
||||
+ from the destructors of RAII types. */
|
||||
+extern void restore_selected_frame (frame_id frame_id, int frame_level)
|
||||
+ noexcept;
|
||||
+
|
||||
+/* Lookup the frame_info object for the selected frame FRAME_ID /
|
||||
+ FRAME_LEVEL and cache the result.
|
||||
+
|
||||
+ If FRAME_LEVEL > 0 and the originally selected frame isn't found,
|
||||
+ warn and select the innermost (current) frame. */
|
||||
+extern void lookup_selected_frame (frame_id frame_id, int frame_level);
|
||||
+
|
||||
/* Given a FRAME, return the next (more inner, younger) or previous
|
||||
(more outer, older) frame. */
|
||||
extern struct frame_info *get_prev_frame (struct frame_info *);
|
||||
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
|
||||
--- a/gdb/gdbthread.h
|
||||
+++ b/gdb/gdbthread.h
|
||||
@@ -673,6 +673,10 @@ class scoped_restore_current_thread
|
||||
frame_id m_selected_frame_id;
|
||||
int m_selected_frame_level;
|
||||
bool m_was_stopped;
|
||||
+ /* Save/restore the language as well, because selecting a frame
|
||||
+ changes the current language to the frame's language if "set
|
||||
+ language auto". */
|
||||
+ enum language m_lang;
|
||||
};
|
||||
|
||||
/* Returns a pointer into the thread_info corresponding to
|
||||
diff --git a/gdb/infrun.c b/gdb/infrun.c
|
||||
--- a/gdb/infrun.c
|
||||
+++ b/gdb/infrun.c
|
||||
@@ -9006,8 +9006,10 @@ struct infcall_control_state
|
||||
enum stop_stack_kind stop_stack_dummy = STOP_NONE;
|
||||
int stopped_by_random_signal = 0;
|
||||
|
||||
- /* ID if the selected frame when the inferior function call was made. */
|
||||
+ /* ID and level of the selected frame when the inferior function
|
||||
+ call was made. */
|
||||
struct frame_id selected_frame_id {};
|
||||
+ int selected_frame_level = -1;
|
||||
};
|
||||
|
||||
/* Save all of the information associated with the inferior<==>gdb
|
||||
@@ -9036,27 +9038,12 @@ save_infcall_control_state ()
|
||||
inf_status->stop_stack_dummy = stop_stack_dummy;
|
||||
inf_status->stopped_by_random_signal = stopped_by_random_signal;
|
||||
|
||||
- inf_status->selected_frame_id = get_frame_id (get_selected_frame (NULL));
|
||||
+ save_selected_frame (&inf_status->selected_frame_id,
|
||||
+ &inf_status->selected_frame_level);
|
||||
|
||||
return inf_status;
|
||||
}
|
||||
|
||||
-static void
|
||||
-restore_selected_frame (const frame_id &fid)
|
||||
-{
|
||||
- frame_info *frame = frame_find_by_id (fid);
|
||||
-
|
||||
- /* If inf_status->selected_frame_id is NULL, there was no previously
|
||||
- selected frame. */
|
||||
- if (frame == NULL)
|
||||
- {
|
||||
- warning (_("Unable to restore previously selected frame."));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- select_frame (frame);
|
||||
-}
|
||||
-
|
||||
/* Restore inferior session state to INF_STATUS. */
|
||||
|
||||
void
|
||||
@@ -9084,21 +9071,8 @@ restore_infcall_control_state (struct infcall_control_state *inf_status)
|
||||
|
||||
if (target_has_stack)
|
||||
{
|
||||
- /* The point of the try/catch is that if the stack is clobbered,
|
||||
- walking the stack might encounter a garbage pointer and
|
||||
- error() trying to dereference it. */
|
||||
- try
|
||||
- {
|
||||
- restore_selected_frame (inf_status->selected_frame_id);
|
||||
- }
|
||||
- catch (const gdb_exception_error &ex)
|
||||
- {
|
||||
- exception_fprintf (gdb_stderr, ex,
|
||||
- "Unable to restore previously selected frame:\n");
|
||||
- /* Error in restoring the selected frame. Select the
|
||||
- innermost frame. */
|
||||
- select_frame (get_current_frame ());
|
||||
- }
|
||||
+ restore_selected_frame (inf_status->selected_frame_id,
|
||||
+ inf_status->selected_frame_level);
|
||||
}
|
||||
|
||||
delete inf_status;
|
||||
diff --git a/gdb/stack.c b/gdb/stack.c
|
||||
--- a/gdb/stack.c
|
||||
+++ b/gdb/stack.c
|
||||
@@ -1842,9 +1842,9 @@ trailing_outermost_frame (int count)
|
||||
static void
|
||||
select_frame_command_core (struct frame_info *fi, bool ignored)
|
||||
{
|
||||
- struct frame_info *prev_frame = get_selected_frame_if_set ();
|
||||
+ frame_info *prev_frame = get_selected_frame ();
|
||||
select_frame (fi);
|
||||
- if (get_selected_frame_if_set () != prev_frame)
|
||||
+ if (get_selected_frame () != prev_frame)
|
||||
gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
|
||||
}
|
||||
|
||||
@@ -1863,10 +1863,9 @@ select_frame_for_mi (struct frame_info *fi)
|
||||
static void
|
||||
frame_command_core (struct frame_info *fi, bool ignored)
|
||||
{
|
||||
- struct frame_info *prev_frame = get_selected_frame_if_set ();
|
||||
-
|
||||
+ frame_info *prev_frame = get_selected_frame ();
|
||||
select_frame (fi);
|
||||
- if (get_selected_frame_if_set () != prev_frame)
|
||||
+ if (get_selected_frame () != prev_frame)
|
||||
gdb::observers::user_selected_context_changed.notify (USER_SELECTED_FRAME);
|
||||
else
|
||||
print_selected_thread_frame (current_uiout, USER_SELECTED_FRAME);
|
||||
diff --git a/gdb/thread.c b/gdb/thread.c
|
||||
--- a/gdb/thread.c
|
||||
+++ b/gdb/thread.c
|
||||
@@ -1325,20 +1325,26 @@ switch_to_thread (process_stratum_target *proc_target, ptid_t ptid)
|
||||
switch_to_thread (thr);
|
||||
}
|
||||
|
||||
-static void
|
||||
-restore_selected_frame (struct frame_id a_frame_id, int frame_level)
|
||||
+/* See frame.h. */
|
||||
+
|
||||
+void
|
||||
+lookup_selected_frame (struct frame_id a_frame_id, int frame_level)
|
||||
{
|
||||
struct frame_info *frame = NULL;
|
||||
int count;
|
||||
|
||||
- /* This means there was no selected frame. */
|
||||
+ /* This either means there was no selected frame, or the selected
|
||||
+ frame was the current frame. In either case, select the current
|
||||
+ frame. */
|
||||
if (frame_level == -1)
|
||||
{
|
||||
- select_frame (NULL);
|
||||
+ select_frame (get_current_frame ());
|
||||
return;
|
||||
}
|
||||
|
||||
- gdb_assert (frame_level >= 0);
|
||||
+ /* select_frame never saves 0 in SELECTED_FRAME_LEVEL, so we
|
||||
+ shouldn't see it here. */
|
||||
+ gdb_assert (frame_level > 0);
|
||||
|
||||
/* Restore by level first, check if the frame id is the same as
|
||||
expected. If that fails, try restoring by frame id. If that
|
||||
@@ -1409,64 +1415,28 @@ scoped_restore_current_thread::restore ()
|
||||
&& target_has_stack
|
||||
&& target_has_memory)
|
||||
restore_selected_frame (m_selected_frame_id, m_selected_frame_level);
|
||||
+
|
||||
+ set_language (m_lang);
|
||||
}
|
||||
|
||||
scoped_restore_current_thread::~scoped_restore_current_thread ()
|
||||
{
|
||||
if (!m_dont_restore)
|
||||
- {
|
||||
- try
|
||||
- {
|
||||
- restore ();
|
||||
- }
|
||||
- catch (const gdb_exception &ex)
|
||||
- {
|
||||
- /* We're in a dtor, there's really nothing else we can do
|
||||
- but swallow the exception. */
|
||||
- }
|
||||
- }
|
||||
+ restore ();
|
||||
}
|
||||
|
||||
scoped_restore_current_thread::scoped_restore_current_thread ()
|
||||
{
|
||||
m_inf = inferior_ref::new_reference (current_inferior ());
|
||||
|
||||
+ m_lang = current_language->la_language;
|
||||
+
|
||||
if (inferior_ptid != null_ptid)
|
||||
{
|
||||
m_thread = thread_info_ref::new_reference (inferior_thread ());
|
||||
|
||||
- struct frame_info *frame;
|
||||
-
|
||||
m_was_stopped = m_thread->state == THREAD_STOPPED;
|
||||
- if (m_was_stopped
|
||||
- && target_has_registers
|
||||
- && target_has_stack
|
||||
- && target_has_memory)
|
||||
- {
|
||||
- /* When processing internal events, there might not be a
|
||||
- selected frame. If we naively call get_selected_frame
|
||||
- here, then we can end up reading debuginfo for the
|
||||
- current frame, but we don't generally need the debuginfo
|
||||
- at this point. */
|
||||
- frame = get_selected_frame_if_set ();
|
||||
- }
|
||||
- else
|
||||
- frame = NULL;
|
||||
-
|
||||
- try
|
||||
- {
|
||||
- m_selected_frame_id = get_frame_id (frame);
|
||||
- m_selected_frame_level = frame_relative_level (frame);
|
||||
- }
|
||||
- catch (const gdb_exception_error &ex)
|
||||
- {
|
||||
- m_selected_frame_id = null_frame_id;
|
||||
- m_selected_frame_level = -1;
|
||||
-
|
||||
- /* Better let this propagate. */
|
||||
- if (ex.error == TARGET_CLOSE_ERROR)
|
||||
- throw;
|
||||
- }
|
||||
+ save_selected_frame (&m_selected_frame_id, &m_selected_frame_level);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Pedro Alves <pedro@palves.net>
|
||||
Date: Sat, 31 Oct 2020 00:27:18 +0000
|
||||
Subject: gdb-rhbz1909902-frame_id_p-assert-2.patch
|
||||
|
||||
;; Backport patch #2 which fixes a frame_id_p assertion failure (RH BZ 1909902).
|
||||
|
||||
Fix frame cycle detection
|
||||
|
||||
The recent commit to make scoped_restore_current_thread's cdtors
|
||||
exception free regressed gdb.base/eh_return.exp:
|
||||
|
||||
Breakpoint 1, 0x00000000004012bb in eh2 (gdb/frame.c:641: internal-error: frame_id get_frame_id(frame_info*): Assertion `stashed' failed.
|
||||
A problem internal to GDB has been detected,
|
||||
further debugging may prove unreliable.
|
||||
Quit this debugging session? (y or n) FAIL: gdb.base/eh_return.exp: hit breakpoint (GDB internal error)
|
||||
|
||||
That testcase uses __builtin_eh_return and, before the regression, the
|
||||
backtrace at eh2 looked like this:
|
||||
|
||||
(gdb) bt
|
||||
#0 0x00000000004006eb in eh2 (p=0x4006ec <continuation>) at src/gdb/testsuite/gdb.base/eh_return.c:54
|
||||
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
|
||||
|
||||
That "previous frame identical to this frame" is caught by the cycle
|
||||
detection based on frame id.
|
||||
|
||||
The assertion failing is this one:
|
||||
|
||||
638 /* Since this is the first frame in the chain, this should
|
||||
639 always succeed. */
|
||||
640 bool stashed = frame_stash_add (fi);
|
||||
641 gdb_assert (stashed);
|
||||
|
||||
originally added by
|
||||
|
||||
commit f245535cf583ae4ca13b10d47b3c7d3334593ece
|
||||
Author: Pedro Alves <palves@redhat.com>
|
||||
AuthorDate: Mon Sep 5 18:41:38 2016 +0100
|
||||
|
||||
Fix PR19927: Avoid unwinder recursion if sniffer uses calls parse_and_eval
|
||||
|
||||
The assertion is failing because frame #1's frame id was stashed
|
||||
before the id of frame #0 is stashed. The frame id of frame #1 was
|
||||
stashed here:
|
||||
|
||||
(top-gdb) bt
|
||||
#0 frame_stash_add (frame=0x1e24c90) at src/gdb/frame.c:276
|
||||
#1 0x0000000000669c1b in get_prev_frame_if_no_cycle (this_frame=0x19f8370) at src/gdb/frame.c:2120
|
||||
#2 0x000000000066a339 in get_prev_frame_always_1 (this_frame=0x19f8370) at src/gdb/frame.c:2303
|
||||
#3 0x000000000066a360 in get_prev_frame_always (this_frame=0x19f8370) at src/gdb/frame.c:2319
|
||||
#4 0x000000000066b56c in get_frame_unwind_stop_reason (frame=0x19f8370) at src/gdb/frame.c:3028
|
||||
#5 0x000000000059f929 in dwarf2_frame_cfa (this_frame=0x19f8370) at src/gdb/dwarf2/frame.c:1462
|
||||
#6 0x00000000005ce434 in dwarf_evaluate_loc_desc::get_frame_cfa (this=0x7fffffffc070) at src/gdb/dwarf2/loc.c:666
|
||||
#7 0x00000000005989a9 in dwarf_expr_context::execute_stack_op (this=0x7fffffffc070, op_ptr=0x1b2a053 "\364\003", op_end=0x1b2a053 "\364\003") at src/gdb/dwarf2/expr.c:1161
|
||||
#8 0x0000000000596af6 in dwarf_expr_context::eval (this=0x7fffffffc070, addr=0x1b2a052 "\234\364\003", len=1) at src/gdb/dwarf2/expr.c:303
|
||||
#9 0x0000000000597b4e in dwarf_expr_context::execute_stack_op (this=0x7fffffffc070, op_ptr=0x1b2a063 "", op_end=0x1b2a063 "") at src/gdb/dwarf2/expr.c:865
|
||||
#10 0x0000000000596af6 in dwarf_expr_context::eval (this=0x7fffffffc070, addr=0x1b2a061 "\221X", len=2) at src/gdb/dwarf2/expr.c:303
|
||||
#11 0x00000000005c8b5a in dwarf2_evaluate_loc_desc_full (type=0x1b564d0, frame=0x19f8370, data=0x1b2a061 "\221X", size=2, per_cu=0x1b28760, per_objfile=0x1a84930, subobj_type=0x1b564d0, subobj_byte_offset=0) at src/gdb/dwarf2/loc.c:2260
|
||||
#12 0x00000000005c9243 in dwarf2_evaluate_loc_desc (type=0x1b564d0, frame=0x19f8370, data=0x1b2a061 "\221X", size=2, per_cu=0x1b28760, per_objfile=0x1a84930) at src/gdb/dwarf2/loc.c:2444
|
||||
#13 0x00000000005cb769 in locexpr_read_variable (symbol=0x1b59840, frame=0x19f8370) at src/gdb/dwarf2/loc.c:3687
|
||||
#14 0x0000000000663137 in language_defn::read_var_value (this=0x122ea60 <c_language_defn>, var=0x1b59840, var_block=0x0, frame=0x19f8370) at src/gdb/findvar.c:618
|
||||
#15 0x0000000000663c3b in read_var_value (var=0x1b59840, var_block=0x0, frame=0x19f8370) at src/gdb/findvar.c:822
|
||||
#16 0x00000000008c7d9f in read_frame_arg (fp_opts=..., sym=0x1b59840, frame=0x19f8370, argp=0x7fffffffc470, entryargp=0x7fffffffc490) at src/gdb/stack.c:542
|
||||
#17 0x00000000008c89cd in print_frame_args (fp_opts=..., func=0x1b597c0, frame=0x19f8370, num=-1, stream=0x1aba860) at src/gdb/stack.c:890
|
||||
#18 0x00000000008c9bf8 in print_frame (fp_opts=..., frame=0x19f8370, print_level=0, print_what=SRC_AND_LOC, print_args=1, sal=...) at src/gdb/stack.c:1394
|
||||
#19 0x00000000008c92b9 in print_frame_info (fp_opts=..., frame=0x19f8370, print_level=0, print_what=SRC_AND_LOC, print_args=1, set_current_sal=1) at src/gdb/stack.c:1119
|
||||
#20 0x00000000008c75f0 in print_stack_frame (frame=0x19f8370, print_level=0, print_what=SRC_AND_LOC, set_current_sal=1) at src/gdb/stack.c:366
|
||||
#21 0x000000000070250b in print_stop_location (ws=0x7fffffffc9e0) at src/gdb/infrun.c:8110
|
||||
#22 0x0000000000702569 in print_stop_event (uiout=0x1a8b9e0, displays=true) at src/gdb/infrun.c:8126
|
||||
#23 0x000000000096d04b in tui_on_normal_stop (bs=0x1bcd1c0, print_frame=1) at src/gdb/tui/tui-interp.c:98
|
||||
...
|
||||
|
||||
Before the commit to make scoped_restore_current_thread's cdtors
|
||||
exception free, scoped_restore_current_thread's dtor would call
|
||||
get_frame_id on the selected frame, and we use
|
||||
scoped_restore_current_thread pervasively. That had the side effect
|
||||
of stashing the frame id of frame #0 before reaching the path shown in
|
||||
the backtrace. I.e., the frame id of frame #0 happened to be stashed
|
||||
before the frame id of frame #1. But that was by chance, not by
|
||||
design.
|
||||
|
||||
This commit:
|
||||
|
||||
commit 256ae5dbc73d1348850f86ee77a0dc3b04bc7cc0
|
||||
Author: Kevin Buettner <kevinb@redhat.com>
|
||||
AuthorDate: Mon Oct 31 12:47:42 2016 -0700
|
||||
|
||||
Stash frame id of current frame before stashing frame id for previous frame
|
||||
|
||||
Fixed a similar problem, by making sure get_prev_frame computes the
|
||||
frame id of the current frame before unwinding the previous frame, so
|
||||
that the cycle detection works properly. That fix misses the scenario
|
||||
we're now running against, because if you notice, the backtrace above
|
||||
shows that frame #4 calls get_prev_frame_always, not get_prev_frame.
|
||||
I.e., nothing is calling get_frame_id on the current frame.
|
||||
|
||||
The fix here is to move Kevin's fix down from get_prev_frame to
|
||||
get_prev_frame_always. Or actually, a bit further down to
|
||||
get_prev_frame_always_1 -- note that inline_frame_this_id calls
|
||||
get_prev_frame_always, so we need to be careful to avoid recursion in
|
||||
that scenario.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* frame.c (get_prev_frame): Move get_frame_id call from here ...
|
||||
(get_prev_frame_always_1): ... to here.
|
||||
* inline-frame.c (inline_frame_this_id): Mention
|
||||
get_prev_frame_always_1 in comment.
|
||||
|
||||
Change-Id: Id960c98ab2d072c48a436c3eb160cc4b2a5cfd1d
|
||||
|
||||
diff --git a/gdb/frame.c b/gdb/frame.c
|
||||
--- a/gdb/frame.c
|
||||
+++ b/gdb/frame.c
|
||||
@@ -2133,6 +2133,23 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
|
||||
if (get_frame_type (this_frame) == INLINE_FRAME)
|
||||
return get_prev_frame_if_no_cycle (this_frame);
|
||||
|
||||
+ /* If this_frame is the current frame, then compute and stash its
|
||||
+ frame id prior to fetching and computing the frame id of the
|
||||
+ previous frame. Otherwise, the cycle detection code in
|
||||
+ get_prev_frame_if_no_cycle() will not work correctly. When
|
||||
+ get_frame_id() is called later on, an assertion error will be
|
||||
+ triggered in the event of a cycle between the current frame and
|
||||
+ its previous frame.
|
||||
+
|
||||
+ Note we do this after the INLINE_FRAME check above. That is
|
||||
+ because the inline frame's frame id computation needs to fetch
|
||||
+ the frame id of its previous real stack frame. I.e., we need to
|
||||
+ avoid recursion in that case. This is OK since we're sure the
|
||||
+ inline frame won't create a cycle with the real stack frame. See
|
||||
+ inline_frame_this_id. */
|
||||
+ if (this_frame->level == 0)
|
||||
+ get_frame_id (this_frame);
|
||||
+
|
||||
/* Check that this frame is unwindable. If it isn't, don't try to
|
||||
unwind to the prev frame. */
|
||||
this_frame->stop_reason
|
||||
@@ -2410,16 +2427,6 @@ get_prev_frame (struct frame_info *this_frame)
|
||||
something should be calling get_selected_frame() or
|
||||
get_current_frame(). */
|
||||
gdb_assert (this_frame != NULL);
|
||||
-
|
||||
- /* If this_frame is the current frame, then compute and stash
|
||||
- its frame id prior to fetching and computing the frame id of the
|
||||
- previous frame. Otherwise, the cycle detection code in
|
||||
- get_prev_frame_if_no_cycle() will not work correctly. When
|
||||
- get_frame_id() is called later on, an assertion error will
|
||||
- be triggered in the event of a cycle between the current
|
||||
- frame and its previous frame. */
|
||||
- if (this_frame->level == 0)
|
||||
- get_frame_id (this_frame);
|
||||
|
||||
frame_pc_p = get_frame_pc_if_available (this_frame, &frame_pc);
|
||||
|
||||
diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c
|
||||
--- a/gdb/inline-frame.c
|
||||
+++ b/gdb/inline-frame.c
|
||||
@@ -161,7 +161,8 @@ inline_frame_this_id (struct frame_info *this_frame,
|
||||
real frame's this_id method. So we must call
|
||||
get_prev_frame_always. Because we are inlined into some
|
||||
function, there must be previous frames, so this is safe - as
|
||||
- long as we're careful not to create any cycles. */
|
||||
+ long as we're careful not to create any cycles. See related
|
||||
+ comments in get_prev_frame_always_1. */
|
||||
*this_id = get_frame_id (get_prev_frame_always (this_frame));
|
||||
|
||||
/* We need a valid frame ID, so we need to be based on a valid
|
|
@ -0,0 +1,67 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Tom de Vries <tdevries@suse.de>
|
||||
Date: Mon, 30 Aug 2021 16:03:15 +0200
|
||||
Subject: gdb-rhbz1916516-pathstuff.cc132-internal-error.patch
|
||||
|
||||
;;[gdb/cli] Don't assert on empty string for core-file
|
||||
;;(Tom de Vries)
|
||||
|
||||
With current gdb we run into:
|
||||
...
|
||||
$ gdb -batch '' ''
|
||||
: No such file or directory.
|
||||
pathstuff.cc:132: internal-error: \
|
||||
gdb::unique_xmalloc_ptr<char> gdb_abspath(const char*): \
|
||||
Assertion `path != NULL && path[0] != '\0'' failed.
|
||||
...
|
||||
|
||||
Fix this by skipping the call to gdb_abspath in core_target_open in the
|
||||
empty-string case, such that we have instead:
|
||||
...
|
||||
$ gdb -batch '' ''
|
||||
: No such file or directory.
|
||||
: No such file or directory.
|
||||
$
|
||||
...
|
||||
|
||||
Tested on x86_64-linux.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
2021-08-30 Tom de Vries <tdevries@suse.de>
|
||||
|
||||
PR cli/28290
|
||||
* gdb/corelow.c (core_target_open): Skip call to gdb_abspath in the
|
||||
empty-string case.
|
||||
|
||||
gdb/testsuite/ChangeLog:
|
||||
|
||||
2021-08-30 Tom de Vries <tdevries@suse.de>
|
||||
|
||||
PR cli/28290
|
||||
* gdb.base/batch-exit-status.exp: Add gdb '' and gdb '' '' tests.
|
||||
|
||||
diff --git a/gdb/corelow.c b/gdb/corelow.c
|
||||
--- a/gdb/corelow.c
|
||||
+++ b/gdb/corelow.c
|
||||
@@ -446,7 +446,8 @@ core_target_open (const char *arg, int from_tty)
|
||||
}
|
||||
|
||||
gdb::unique_xmalloc_ptr<char> filename (tilde_expand (arg));
|
||||
- if (!IS_ABSOLUTE_PATH (filename.get ()))
|
||||
+ if (strlen (filename.get ()) != 0
|
||||
+ && !IS_ABSOLUTE_PATH (filename.get ()))
|
||||
filename = gdb_abspath (filename.get ());
|
||||
|
||||
flags = O_BINARY | O_LARGEFILE;
|
||||
diff --git a/gdb/testsuite/gdb.base/batch-exit-status.exp b/gdb/testsuite/gdb.base/batch-exit-status.exp
|
||||
--- a/gdb/testsuite/gdb.base/batch-exit-status.exp
|
||||
+++ b/gdb/testsuite/gdb.base/batch-exit-status.exp
|
||||
@@ -76,3 +76,7 @@ test_exit_status 1 "-batch -x $good_commands -x $bad_commands" \
|
||||
"-batch -x good-commands -x bad-commands"
|
||||
test_exit_status 1 "-batch -x $good_commands -ex \"set not-a-thing 4\"" \
|
||||
"-batch -x good-commands -ex \"set not-a-thing 4\""
|
||||
+
|
||||
+set no_such_re ": No such file or directory\\."
|
||||
+test_exit_status 1 "-batch \"\"" $no_such_re
|
||||
+test_exit_status 1 "-batch \"\" \"\"" [multi_line $no_such_re $no_such_re]
|
|
@ -0,0 +1,375 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Mon, 24 May 2021 17:10:28 -0700
|
||||
Subject: gdb-rhbz1964167-convert-enum-range_type.patch
|
||||
|
||||
;; [fortran] Backport Andrew Burgess's commit which changes enum
|
||||
;; range_type into a bit field enum.
|
||||
|
||||
gdb: Convert enum range_type to a bit field enum
|
||||
|
||||
The expression range_type enum represents the following ideas:
|
||||
|
||||
- Lower bound is set to default,
|
||||
- Upper bound is set to default,
|
||||
- Upper bound is exclusive.
|
||||
|
||||
There are currently 6 entries in the enum to represent the combination
|
||||
of all those ideas.
|
||||
|
||||
In a future commit I'd like to add stride information to the range,
|
||||
this could in theory appear with any of the existing enum entries, so
|
||||
this would take us to 12 enum entries.
|
||||
|
||||
This feels like its getting a little out of hand, so in this commit I
|
||||
switch the range_type enum over to being a flags style enum. There's
|
||||
one entry to represent no flags being set, then 3 flags to represent
|
||||
the 3 ideas above. Adding stride information will require adding only
|
||||
one more enum flag.
|
||||
|
||||
I've then gone through and updated the code to handle this change.
|
||||
|
||||
There should be no user visible changes after this commit.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* expprint.c (print_subexp_standard): Update to reflect changes to
|
||||
enum range_type.
|
||||
(dump_subexp_body_standard): Likewise.
|
||||
* expression.h (enum range_type): Convert to a bit field enum, and
|
||||
make the enum unsigned.
|
||||
* f-exp.y (subrange): Update to reflect changes to enum
|
||||
range_type.
|
||||
* f-lang.c (value_f90_subarray): Likewise.
|
||||
* parse.c (operator_length_standard): Likewise.
|
||||
* rust-exp.y (rust_parser::convert_ast_to_expression): Likewise.
|
||||
* rust-lang.c (rust_range): Likewise.
|
||||
(rust_compute_range): Likewise.
|
||||
(rust_subscript): Likewise.
|
||||
|
||||
diff --git a/gdb/expprint.c b/gdb/expprint.c
|
||||
--- a/gdb/expprint.c
|
||||
+++ b/gdb/expprint.c
|
||||
@@ -584,17 +584,13 @@ print_subexp_standard (struct expression *exp, int *pos,
|
||||
longest_to_int (exp->elts[pc + 1].longconst);
|
||||
*pos += 2;
|
||||
|
||||
- if (range_type == NONE_BOUND_DEFAULT_EXCLUSIVE
|
||||
- || range_type == LOW_BOUND_DEFAULT_EXCLUSIVE)
|
||||
+ if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
|
||||
fputs_filtered ("EXCLUSIVE_", stream);
|
||||
fputs_filtered ("RANGE(", stream);
|
||||
- if (range_type == HIGH_BOUND_DEFAULT
|
||||
- || range_type == NONE_BOUND_DEFAULT
|
||||
- || range_type == NONE_BOUND_DEFAULT_EXCLUSIVE)
|
||||
+ if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
|
||||
print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
|
||||
fputs_filtered ("..", stream);
|
||||
- if (range_type == LOW_BOUND_DEFAULT
|
||||
- || range_type == NONE_BOUND_DEFAULT)
|
||||
+ if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
|
||||
print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
|
||||
fputs_filtered (")", stream);
|
||||
return;
|
||||
@@ -1114,36 +1110,19 @@ dump_subexp_body_standard (struct expression *exp,
|
||||
longest_to_int (exp->elts[elt].longconst);
|
||||
elt += 2;
|
||||
|
||||
- switch (range_type)
|
||||
- {
|
||||
- case BOTH_BOUND_DEFAULT:
|
||||
- fputs_filtered ("Range '..'", stream);
|
||||
- break;
|
||||
- case LOW_BOUND_DEFAULT:
|
||||
- fputs_filtered ("Range '..EXP'", stream);
|
||||
- break;
|
||||
- case LOW_BOUND_DEFAULT_EXCLUSIVE:
|
||||
- fputs_filtered ("ExclusiveRange '..EXP'", stream);
|
||||
- break;
|
||||
- case HIGH_BOUND_DEFAULT:
|
||||
- fputs_filtered ("Range 'EXP..'", stream);
|
||||
- break;
|
||||
- case NONE_BOUND_DEFAULT:
|
||||
- fputs_filtered ("Range 'EXP..EXP'", stream);
|
||||
- break;
|
||||
- case NONE_BOUND_DEFAULT_EXCLUSIVE:
|
||||
- fputs_filtered ("ExclusiveRange 'EXP..EXP'", stream);
|
||||
- break;
|
||||
- default:
|
||||
- fputs_filtered ("Invalid Range!", stream);
|
||||
- break;
|
||||
- }
|
||||
+ if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
|
||||
+ fputs_filtered ("Exclusive", stream);
|
||||
+ fputs_filtered ("Range '", stream);
|
||||
+ if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
|
||||
+ fputs_filtered ("EXP", stream);
|
||||
+ fputs_filtered ("..", stream);
|
||||
+ if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
|
||||
+ fputs_filtered ("EXP", stream);
|
||||
+ fputs_filtered ("'", stream);
|
||||
|
||||
- if (range_type == HIGH_BOUND_DEFAULT
|
||||
- || range_type == NONE_BOUND_DEFAULT)
|
||||
+ if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
|
||||
elt = dump_subexp (exp, stream, elt);
|
||||
- if (range_type == LOW_BOUND_DEFAULT
|
||||
- || range_type == NONE_BOUND_DEFAULT)
|
||||
+ if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
|
||||
elt = dump_subexp (exp, stream, elt);
|
||||
}
|
||||
break;
|
||||
diff --git a/gdb/expression.h b/gdb/expression.h
|
||||
--- a/gdb/expression.h
|
||||
+++ b/gdb/expression.h
|
||||
@@ -185,22 +185,22 @@ extern void dump_prefix_expression (struct expression *, struct ui_file *);
|
||||
or inclusive. So we have six sorts of subrange. This enumeration
|
||||
type is to identify this. */
|
||||
|
||||
-enum range_type
|
||||
+enum range_type : unsigned
|
||||
{
|
||||
- /* Neither the low nor the high bound was given -- so this refers to
|
||||
- the entire available range. */
|
||||
- BOTH_BOUND_DEFAULT,
|
||||
- /* The low bound was not given and the high bound is inclusive. */
|
||||
- LOW_BOUND_DEFAULT,
|
||||
- /* The high bound was not given and the low bound in inclusive. */
|
||||
- HIGH_BOUND_DEFAULT,
|
||||
- /* Both bounds were given and both are inclusive. */
|
||||
- NONE_BOUND_DEFAULT,
|
||||
- /* The low bound was not given and the high bound is exclusive. */
|
||||
- NONE_BOUND_DEFAULT_EXCLUSIVE,
|
||||
- /* Both bounds were given. The low bound is inclusive and the high
|
||||
- bound is exclusive. */
|
||||
- LOW_BOUND_DEFAULT_EXCLUSIVE,
|
||||
+ /* This is a standard range. Both the lower and upper bounds are
|
||||
+ defined, and the bounds are inclusive. */
|
||||
+ RANGE_STANDARD = 0,
|
||||
+
|
||||
+ /* The low bound was not given. */
|
||||
+ RANGE_LOW_BOUND_DEFAULT = 1 << 0,
|
||||
+
|
||||
+ /* The high bound was not given. */
|
||||
+ RANGE_HIGH_BOUND_DEFAULT = 1 << 1,
|
||||
+
|
||||
+ /* The high bound of this range is exclusive. */
|
||||
+ RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
|
||||
};
|
||||
|
||||
+DEF_ENUM_FLAGS_TYPE (enum range_type, range_types);
|
||||
+
|
||||
#endif /* !defined (EXPRESSION_H) */
|
||||
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
|
||||
--- a/gdb/f-exp.y
|
||||
+++ b/gdb/f-exp.y
|
||||
@@ -287,26 +287,30 @@ arglist : arglist ',' exp %prec ABOVE_COMMA
|
||||
/* There are four sorts of subrange types in F90. */
|
||||
|
||||
subrange: exp ':' exp %prec ABOVE_COMMA
|
||||
- { write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
- write_exp_elt_longcst (pstate, NONE_BOUND_DEFAULT);
|
||||
+ { write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
+ write_exp_elt_longcst (pstate, RANGE_STANDARD);
|
||||
write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
;
|
||||
|
||||
subrange: exp ':' %prec ABOVE_COMMA
|
||||
{ write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
- write_exp_elt_longcst (pstate, HIGH_BOUND_DEFAULT);
|
||||
+ write_exp_elt_longcst (pstate,
|
||||
+ RANGE_HIGH_BOUND_DEFAULT);
|
||||
write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
;
|
||||
|
||||
subrange: ':' exp %prec ABOVE_COMMA
|
||||
{ write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
- write_exp_elt_longcst (pstate, LOW_BOUND_DEFAULT);
|
||||
+ write_exp_elt_longcst (pstate,
|
||||
+ RANGE_LOW_BOUND_DEFAULT);
|
||||
write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
;
|
||||
|
||||
subrange: ':' %prec ABOVE_COMMA
|
||||
{ write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
- write_exp_elt_longcst (pstate, BOTH_BOUND_DEFAULT);
|
||||
+ write_exp_elt_longcst (pstate,
|
||||
+ (RANGE_LOW_BOUND_DEFAULT
|
||||
+ | RANGE_HIGH_BOUND_DEFAULT));
|
||||
write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
;
|
||||
|
||||
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
|
||||
--- a/gdb/f-lang.c
|
||||
+++ b/gdb/f-lang.c
|
||||
@@ -131,12 +131,12 @@ value_f90_subarray (struct value *array,
|
||||
|
||||
*pos += 3;
|
||||
|
||||
- if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
|
||||
+ if (range_type & RANGE_LOW_BOUND_DEFAULT)
|
||||
low_bound = range->bounds ()->low.const_val ();
|
||||
else
|
||||
low_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
|
||||
- if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
|
||||
+ if (range_type & RANGE_HIGH_BOUND_DEFAULT)
|
||||
high_bound = range->bounds ()->high.const_val ();
|
||||
else
|
||||
high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
diff --git a/gdb/parse.c b/gdb/parse.c
|
||||
--- a/gdb/parse.c
|
||||
+++ b/gdb/parse.c
|
||||
@@ -921,21 +921,13 @@ operator_length_standard (const struct expression *expr, int endpos,
|
||||
range_type = (enum range_type)
|
||||
longest_to_int (expr->elts[endpos - 2].longconst);
|
||||
|
||||
- switch (range_type)
|
||||
- {
|
||||
- case LOW_BOUND_DEFAULT:
|
||||
- case LOW_BOUND_DEFAULT_EXCLUSIVE:
|
||||
- case HIGH_BOUND_DEFAULT:
|
||||
- args = 1;
|
||||
- break;
|
||||
- case BOTH_BOUND_DEFAULT:
|
||||
- args = 0;
|
||||
- break;
|
||||
- case NONE_BOUND_DEFAULT:
|
||||
- case NONE_BOUND_DEFAULT_EXCLUSIVE:
|
||||
- args = 2;
|
||||
- break;
|
||||
- }
|
||||
+ /* Assume the range has 2 arguments (low bound and high bound), then
|
||||
+ reduce the argument count if any bounds are set to default. */
|
||||
+ args = 2;
|
||||
+ if (range_type & RANGE_LOW_BOUND_DEFAULT)
|
||||
+ --args;
|
||||
+ if (range_type & RANGE_HIGH_BOUND_DEFAULT)
|
||||
+ --args;
|
||||
|
||||
break;
|
||||
|
||||
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
|
||||
--- a/gdb/rust-exp.y
|
||||
+++ b/gdb/rust-exp.y
|
||||
@@ -2492,24 +2492,29 @@ rust_parser::convert_ast_to_expression (const struct rust_op *operation,
|
||||
|
||||
case OP_RANGE:
|
||||
{
|
||||
- enum range_type kind = BOTH_BOUND_DEFAULT;
|
||||
+ enum range_type kind = (RANGE_HIGH_BOUND_DEFAULT
|
||||
+ | RANGE_LOW_BOUND_DEFAULT);
|
||||
|
||||
if (operation->left.op != NULL)
|
||||
{
|
||||
convert_ast_to_expression (operation->left.op, top);
|
||||
- kind = HIGH_BOUND_DEFAULT;
|
||||
+ kind &= ~RANGE_LOW_BOUND_DEFAULT;
|
||||
}
|
||||
if (operation->right.op != NULL)
|
||||
{
|
||||
convert_ast_to_expression (operation->right.op, top);
|
||||
- if (kind == BOTH_BOUND_DEFAULT)
|
||||
- kind = (operation->inclusive
|
||||
- ? LOW_BOUND_DEFAULT : LOW_BOUND_DEFAULT_EXCLUSIVE);
|
||||
+ if (kind == (RANGE_HIGH_BOUND_DEFAULT | RANGE_LOW_BOUND_DEFAULT))
|
||||
+ {
|
||||
+ kind = RANGE_LOW_BOUND_DEFAULT;
|
||||
+ if (!operation->inclusive)
|
||||
+ kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
- gdb_assert (kind == HIGH_BOUND_DEFAULT);
|
||||
- kind = (operation->inclusive
|
||||
- ? NONE_BOUND_DEFAULT : NONE_BOUND_DEFAULT_EXCLUSIVE);
|
||||
+ gdb_assert (kind == RANGE_HIGH_BOUND_DEFAULT);
|
||||
+ kind = RANGE_STANDARD;
|
||||
+ if (!operation->inclusive)
|
||||
+ kind |= RANGE_HIGH_BOUND_EXCLUSIVE;
|
||||
}
|
||||
}
|
||||
else
|
||||
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
|
||||
--- a/gdb/rust-lang.c
|
||||
+++ b/gdb/rust-lang.c
|
||||
@@ -1082,13 +1082,11 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
|
||||
kind = (enum range_type) longest_to_int (exp->elts[*pos + 1].longconst);
|
||||
*pos += 3;
|
||||
|
||||
- if (kind == HIGH_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT
|
||||
- || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
|
||||
+ if (!(kind & RANGE_LOW_BOUND_DEFAULT))
|
||||
low = evaluate_subexp (nullptr, exp, pos, noside);
|
||||
- if (kind == LOW_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT_EXCLUSIVE
|
||||
- || kind == NONE_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT_EXCLUSIVE)
|
||||
+ if (!(kind & RANGE_HIGH_BOUND_DEFAULT))
|
||||
high = evaluate_subexp (nullptr, exp, pos, noside);
|
||||
- bool inclusive = (kind == NONE_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT);
|
||||
+ bool inclusive = !(kind & RANGE_HIGH_BOUND_EXCLUSIVE);
|
||||
|
||||
if (noside == EVAL_SKIP)
|
||||
return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
|
||||
@@ -1171,13 +1169,13 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
|
||||
static void
|
||||
rust_compute_range (struct type *type, struct value *range,
|
||||
LONGEST *low, LONGEST *high,
|
||||
- enum range_type *kind)
|
||||
+ range_types *kind)
|
||||
{
|
||||
int i;
|
||||
|
||||
*low = 0;
|
||||
*high = 0;
|
||||
- *kind = BOTH_BOUND_DEFAULT;
|
||||
+ *kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
|
||||
|
||||
if (type->num_fields () == 0)
|
||||
return;
|
||||
@@ -1185,15 +1183,15 @@ rust_compute_range (struct type *type, struct value *range,
|
||||
i = 0;
|
||||
if (strcmp (TYPE_FIELD_NAME (type, 0), "start") == 0)
|
||||
{
|
||||
- *kind = HIGH_BOUND_DEFAULT;
|
||||
+ *kind = RANGE_HIGH_BOUND_DEFAULT;
|
||||
*low = value_as_long (value_field (range, 0));
|
||||
++i;
|
||||
}
|
||||
if (type->num_fields () > i
|
||||
&& strcmp (TYPE_FIELD_NAME (type, i), "end") == 0)
|
||||
{
|
||||
- *kind = (*kind == BOTH_BOUND_DEFAULT
|
||||
- ? LOW_BOUND_DEFAULT : NONE_BOUND_DEFAULT);
|
||||
+ *kind = (*kind == (RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT)
|
||||
+ ? RANGE_LOW_BOUND_DEFAULT : RANGE_STANDARD);
|
||||
*high = value_as_long (value_field (range, i));
|
||||
|
||||
if (rust_inclusive_range_type_p (type))
|
||||
@@ -1211,7 +1209,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
|
||||
struct type *rhstype;
|
||||
LONGEST low, high_bound;
|
||||
/* Initialized to appease the compiler. */
|
||||
- enum range_type kind = BOTH_BOUND_DEFAULT;
|
||||
+ range_types kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
|
||||
LONGEST high = 0;
|
||||
int want_slice = 0;
|
||||
|
||||
@@ -1308,8 +1306,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
|
||||
else
|
||||
error (_("Cannot subscript non-array type"));
|
||||
|
||||
- if (want_slice
|
||||
- && (kind == BOTH_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT))
|
||||
+ if (want_slice && (kind & RANGE_LOW_BOUND_DEFAULT))
|
||||
low = low_bound;
|
||||
if (low < 0)
|
||||
error (_("Index less than zero"));
|
||||
@@ -1327,7 +1324,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
|
||||
CORE_ADDR addr;
|
||||
struct value *addrval, *tem;
|
||||
|
||||
- if (kind == BOTH_BOUND_DEFAULT || kind == HIGH_BOUND_DEFAULT)
|
||||
+ if (kind & RANGE_HIGH_BOUND_DEFAULT)
|
||||
high = high_bound;
|
||||
if (high < 0)
|
||||
error (_("High index less than zero"));
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,193 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Mon, 24 May 2021 22:30:32 -0700
|
||||
Subject: gdb-rhbz1964167-fortran-array-strides-in-expressions.patch
|
||||
|
||||
;; [fortran] Backport Andrew Burgess's commit which adds support
|
||||
;; for array strides in expressions.
|
||||
|
||||
gdb/fortran: add support for parsing array strides in expressions
|
||||
|
||||
With this commit GDB now understands the syntax of Fortran array
|
||||
strides, a user can type an expression including an array stride, but
|
||||
they will only get an error informing them that array strides are not
|
||||
supported.
|
||||
|
||||
This alone is an improvement on what we had before in GDB, better to
|
||||
give the user a helpful message that a particular feature is not
|
||||
supported than to just claim a syntax error.
|
||||
|
||||
Before:
|
||||
|
||||
(gdb) p array (1:10:2, 2:10:2)
|
||||
A syntax error in expression, near `:2, 2:10:2)'.
|
||||
|
||||
Now:
|
||||
|
||||
(gdb) p array (1:10:2, 2:10:2)
|
||||
Fortran array strides are not currently supported
|
||||
|
||||
Later commits will allow GDB to handle array strides correctly.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* expprint.c (dump_subexp_body_standard): Print RANGE_HAS_STRIDE.
|
||||
* expression.h (enum range_type): Add RANGE_HAS_STRIDE.
|
||||
* f-exp.y (arglist): Allow for a series of subranges.
|
||||
(subrange): Add cases for subranges with strides.
|
||||
* f-lang.c (value_f90_subarray): Catch use of array strides and
|
||||
throw an error.
|
||||
* parse.c (operator_length_standard): Handle RANGE_HAS_STRIDE.
|
||||
|
||||
gdb/testsuite/ChangeLog:
|
||||
|
||||
* gdb.fortran/array-slices.exp: Add a new test.
|
||||
|
||||
diff --git a/gdb/expprint.c b/gdb/expprint.c
|
||||
--- a/gdb/expprint.c
|
||||
+++ b/gdb/expprint.c
|
||||
@@ -1118,12 +1118,16 @@ dump_subexp_body_standard (struct expression *exp,
|
||||
fputs_filtered ("..", stream);
|
||||
if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
|
||||
fputs_filtered ("EXP", stream);
|
||||
+ if (range_flag & RANGE_HAS_STRIDE)
|
||||
+ fputs_filtered (":EXP", stream);
|
||||
fputs_filtered ("'", stream);
|
||||
|
||||
if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
|
||||
elt = dump_subexp (exp, stream, elt);
|
||||
if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
|
||||
elt = dump_subexp (exp, stream, elt);
|
||||
+ if (range_flag & RANGE_HAS_STRIDE)
|
||||
+ elt = dump_subexp (exp, stream, elt);
|
||||
}
|
||||
break;
|
||||
|
||||
diff --git a/gdb/expression.h b/gdb/expression.h
|
||||
--- a/gdb/expression.h
|
||||
+++ b/gdb/expression.h
|
||||
@@ -199,6 +199,9 @@ enum range_flag : unsigned
|
||||
|
||||
/* The high bound of this range is exclusive. */
|
||||
RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
|
||||
+
|
||||
+ /* The range has a stride. */
|
||||
+ RANGE_HAS_STRIDE = 1 << 3,
|
||||
};
|
||||
|
||||
DEF_ENUM_FLAGS_TYPE (enum range_flag, range_flags);
|
||||
diff --git a/gdb/f-exp.y b/gdb/f-exp.y
|
||||
--- a/gdb/f-exp.y
|
||||
+++ b/gdb/f-exp.y
|
||||
@@ -284,6 +284,10 @@ arglist : arglist ',' exp %prec ABOVE_COMMA
|
||||
{ pstate->arglist_len++; }
|
||||
;
|
||||
|
||||
+arglist : arglist ',' subrange %prec ABOVE_COMMA
|
||||
+ { pstate->arglist_len++; }
|
||||
+ ;
|
||||
+
|
||||
/* There are four sorts of subrange types in F90. */
|
||||
|
||||
subrange: exp ':' exp %prec ABOVE_COMMA
|
||||
@@ -314,6 +318,38 @@ subrange: ':' %prec ABOVE_COMMA
|
||||
write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
;
|
||||
|
||||
+/* And each of the four subrange types can also have a stride. */
|
||||
+subrange: exp ':' exp ':' exp %prec ABOVE_COMMA
|
||||
+ { write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
+ write_exp_elt_longcst (pstate, RANGE_HAS_STRIDE);
|
||||
+ write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
+ ;
|
||||
+
|
||||
+subrange: exp ':' ':' exp %prec ABOVE_COMMA
|
||||
+ { write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
+ write_exp_elt_longcst (pstate,
|
||||
+ (RANGE_HIGH_BOUND_DEFAULT
|
||||
+ | RANGE_HAS_STRIDE));
|
||||
+ write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
+ ;
|
||||
+
|
||||
+subrange: ':' exp ':' exp %prec ABOVE_COMMA
|
||||
+ { write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
+ write_exp_elt_longcst (pstate,
|
||||
+ (RANGE_LOW_BOUND_DEFAULT
|
||||
+ | RANGE_HAS_STRIDE));
|
||||
+ write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
+ ;
|
||||
+
|
||||
+subrange: ':' ':' exp %prec ABOVE_COMMA
|
||||
+ { write_exp_elt_opcode (pstate, OP_RANGE);
|
||||
+ write_exp_elt_longcst (pstate,
|
||||
+ (RANGE_LOW_BOUND_DEFAULT
|
||||
+ | RANGE_HIGH_BOUND_DEFAULT
|
||||
+ | RANGE_HAS_STRIDE));
|
||||
+ write_exp_elt_opcode (pstate, OP_RANGE); }
|
||||
+ ;
|
||||
+
|
||||
complexnum: exp ',' exp
|
||||
{ }
|
||||
;
|
||||
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
|
||||
--- a/gdb/f-lang.c
|
||||
+++ b/gdb/f-lang.c
|
||||
@@ -124,7 +124,7 @@ value_f90_subarray (struct value *array,
|
||||
struct expression *exp, int *pos, enum noside noside)
|
||||
{
|
||||
int pc = (*pos) + 1;
|
||||
- LONGEST low_bound, high_bound;
|
||||
+ LONGEST low_bound, high_bound, stride;
|
||||
struct type *range = check_typedef (value_type (array)->index_type ());
|
||||
enum range_flag range_flag
|
||||
= (enum range_flag) longest_to_int (exp->elts[pc].longconst);
|
||||
@@ -141,6 +141,14 @@ value_f90_subarray (struct value *array,
|
||||
else
|
||||
high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
|
||||
+ if (range_flag & RANGE_HAS_STRIDE)
|
||||
+ stride = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
+ else
|
||||
+ stride = 1;
|
||||
+
|
||||
+ if (stride != 1)
|
||||
+ error (_("Fortran array strides are not currently supported"));
|
||||
+
|
||||
return value_slice (array, low_bound, high_bound - low_bound + 1);
|
||||
}
|
||||
|
||||
diff --git a/gdb/parse.c b/gdb/parse.c
|
||||
--- a/gdb/parse.c
|
||||
+++ b/gdb/parse.c
|
||||
@@ -924,6 +924,8 @@ operator_length_standard (const struct expression *expr, int endpos,
|
||||
/* Assume the range has 2 arguments (low bound and high bound), then
|
||||
reduce the argument count if any bounds are set to default. */
|
||||
args = 2;
|
||||
+ if (range_flag & RANGE_HAS_STRIDE)
|
||||
+ ++args;
|
||||
if (range_flag & RANGE_LOW_BOUND_DEFAULT)
|
||||
--args;
|
||||
if (range_flag & RANGE_HIGH_BOUND_DEFAULT)
|
||||
diff --git a/gdb/testsuite/gdb.fortran/array-slices.exp b/gdb/testsuite/gdb.fortran/array-slices.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/array-slices.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/array-slices.exp
|
||||
@@ -66,3 +66,19 @@ foreach result $array_contents msg $message_strings {
|
||||
}
|
||||
|
||||
gdb_continue_to_breakpoint "continue to Final Breakpoint"
|
||||
+
|
||||
+# Next test that asking for an array with stride at the CLI gives an
|
||||
+# error.
|
||||
+clean_restart ${testfile}
|
||||
+
|
||||
+if ![fortran_runto_main] then {
|
||||
+ perror "couldn't run to main"
|
||||
+ continue
|
||||
+}
|
||||
+
|
||||
+gdb_breakpoint "show"
|
||||
+gdb_continue_to_breakpoint "show"
|
||||
+gdb_test "up" ".*"
|
||||
+gdb_test "p array (1:10:2, 1:10:2)" \
|
||||
+ "Fortran array strides are not currently supported" \
|
||||
+ "using array stride gives an error"
|
|
@ -0,0 +1,209 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Mon, 24 May 2021 16:53:22 -0700
|
||||
Subject: gdb-rhbz1964167-fortran-clean-up-array-expression-evaluation.patch
|
||||
|
||||
;; [fortran] Backport Andrew Burgess's commit which cleans up
|
||||
;; array/string expression evaluation.
|
||||
|
||||
gdb/fortran: Clean up array/string expression evaluation
|
||||
|
||||
This commit is a refactor of part of the Fortran array and string
|
||||
handling code.
|
||||
|
||||
The current code is split into two blocks, linked, weirdly, with a
|
||||
goto. After this commit all the code is moved to its own function,
|
||||
and arrays and strings are now handled using the same code; this will
|
||||
be useful later when I want to add array stride support where strings
|
||||
will want to be treated just like arrays, but is a good clean up even
|
||||
without the array stride work, which is why I'm merging it now.
|
||||
|
||||
For now the new function is added as a static within eval.c, even
|
||||
though the function is Fortran only. A following commit will remove
|
||||
some of the Fortran specific code from eval.c into one of the Fortran
|
||||
specific files, including this new function.
|
||||
|
||||
There should be no user visible changes after this commit.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* eval.c (fortran_value_subarray): New function, content is taken
|
||||
from...
|
||||
(evaluate_subexp_standard): ...here, in two places. Now arrays
|
||||
and strings both call the new function.
|
||||
(calc_f77_array_dims): Add header comment, handle strings.
|
||||
|
||||
diff --git a/gdb/eval.c b/gdb/eval.c
|
||||
--- a/gdb/eval.c
|
||||
+++ b/gdb/eval.c
|
||||
@@ -1260,6 +1260,67 @@ is_integral_or_integral_reference (struct type *type)
|
||||
&& is_integral_type (TYPE_TARGET_TYPE (type)));
|
||||
}
|
||||
|
||||
+/* Called from evaluate_subexp_standard to perform array indexing, and
|
||||
+ sub-range extraction, for Fortran. As well as arrays this function
|
||||
+ also handles strings as they can be treated like arrays of characters.
|
||||
+ ARRAY is the array or string being accessed. EXP, POS, and NOSIDE are
|
||||
+ as for evaluate_subexp_standard, and NARGS is the number of arguments
|
||||
+ in this access (e.g. 'array (1,2,3)' would be NARGS 3). */
|
||||
+
|
||||
+static struct value *
|
||||
+fortran_value_subarray (struct value *array, struct expression *exp,
|
||||
+ int *pos, int nargs, enum noside noside)
|
||||
+{
|
||||
+ if (exp->elts[*pos].opcode == OP_RANGE)
|
||||
+ return value_f90_subarray (array, exp, pos, noside);
|
||||
+
|
||||
+ if (noside == EVAL_SKIP)
|
||||
+ {
|
||||
+ skip_undetermined_arglist (nargs, exp, pos, noside);
|
||||
+ /* Return the dummy value with the correct type. */
|
||||
+ return array;
|
||||
+ }
|
||||
+
|
||||
+ LONGEST subscript_array[MAX_FORTRAN_DIMS];
|
||||
+ int ndimensions = 1;
|
||||
+ struct type *type = check_typedef (value_type (array));
|
||||
+
|
||||
+ if (nargs > MAX_FORTRAN_DIMS)
|
||||
+ error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
|
||||
+
|
||||
+ ndimensions = calc_f77_array_dims (type);
|
||||
+
|
||||
+ if (nargs != ndimensions)
|
||||
+ error (_("Wrong number of subscripts"));
|
||||
+
|
||||
+ gdb_assert (nargs > 0);
|
||||
+
|
||||
+ /* Now that we know we have a legal array subscript expression let us
|
||||
+ actually find out where this element exists in the array. */
|
||||
+
|
||||
+ /* Take array indices left to right. */
|
||||
+ for (int i = 0; i < nargs; i++)
|
||||
+ {
|
||||
+ /* Evaluate each subscript; it must be a legal integer in F77. */
|
||||
+ value *arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
+
|
||||
+ /* Fill in the subscript array. */
|
||||
+ subscript_array[i] = value_as_long (arg2);
|
||||
+ }
|
||||
+
|
||||
+ /* Internal type of array is arranged right to left. */
|
||||
+ for (int i = nargs; i > 0; i--)
|
||||
+ {
|
||||
+ struct type *array_type = check_typedef (value_type (array));
|
||||
+ LONGEST index = subscript_array[i - 1];
|
||||
+
|
||||
+ array = value_subscripted_rvalue (array, index,
|
||||
+ f77_get_lowerbound (array_type));
|
||||
+ }
|
||||
+
|
||||
+ return array;
|
||||
+}
|
||||
+
|
||||
struct value *
|
||||
evaluate_subexp_standard (struct type *expect_type,
|
||||
struct expression *exp, int *pos,
|
||||
@@ -1953,33 +2014,8 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
switch (code)
|
||||
{
|
||||
case TYPE_CODE_ARRAY:
|
||||
- if (exp->elts[*pos].opcode == OP_RANGE)
|
||||
- return value_f90_subarray (arg1, exp, pos, noside);
|
||||
- else
|
||||
- {
|
||||
- if (noside == EVAL_SKIP)
|
||||
- {
|
||||
- skip_undetermined_arglist (nargs, exp, pos, noside);
|
||||
- /* Return the dummy value with the correct type. */
|
||||
- return arg1;
|
||||
- }
|
||||
- goto multi_f77_subscript;
|
||||
- }
|
||||
-
|
||||
case TYPE_CODE_STRING:
|
||||
- if (exp->elts[*pos].opcode == OP_RANGE)
|
||||
- return value_f90_subarray (arg1, exp, pos, noside);
|
||||
- else
|
||||
- {
|
||||
- if (noside == EVAL_SKIP)
|
||||
- {
|
||||
- skip_undetermined_arglist (nargs, exp, pos, noside);
|
||||
- /* Return the dummy value with the correct type. */
|
||||
- return arg1;
|
||||
- }
|
||||
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
- return value_subscript (arg1, value_as_long (arg2));
|
||||
- }
|
||||
+ return fortran_value_subarray (arg1, exp, pos, nargs, noside);
|
||||
|
||||
case TYPE_CODE_PTR:
|
||||
case TYPE_CODE_FUNC:
|
||||
@@ -2400,49 +2436,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
}
|
||||
return (arg1);
|
||||
|
||||
- multi_f77_subscript:
|
||||
- {
|
||||
- LONGEST subscript_array[MAX_FORTRAN_DIMS];
|
||||
- int ndimensions = 1, i;
|
||||
- struct value *array = arg1;
|
||||
-
|
||||
- if (nargs > MAX_FORTRAN_DIMS)
|
||||
- error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
|
||||
-
|
||||
- ndimensions = calc_f77_array_dims (type);
|
||||
-
|
||||
- if (nargs != ndimensions)
|
||||
- error (_("Wrong number of subscripts"));
|
||||
-
|
||||
- gdb_assert (nargs > 0);
|
||||
-
|
||||
- /* Now that we know we have a legal array subscript expression
|
||||
- let us actually find out where this element exists in the array. */
|
||||
-
|
||||
- /* Take array indices left to right. */
|
||||
- for (i = 0; i < nargs; i++)
|
||||
- {
|
||||
- /* Evaluate each subscript; it must be a legal integer in F77. */
|
||||
- arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
-
|
||||
- /* Fill in the subscript array. */
|
||||
-
|
||||
- subscript_array[i] = value_as_long (arg2);
|
||||
- }
|
||||
-
|
||||
- /* Internal type of array is arranged right to left. */
|
||||
- for (i = nargs; i > 0; i--)
|
||||
- {
|
||||
- struct type *array_type = check_typedef (value_type (array));
|
||||
- LONGEST index = subscript_array[i - 1];
|
||||
-
|
||||
- array = value_subscripted_rvalue (array, index,
|
||||
- f77_get_lowerbound (array_type));
|
||||
- }
|
||||
-
|
||||
- return array;
|
||||
- }
|
||||
-
|
||||
case BINOP_LOGICAL_AND:
|
||||
arg1 = evaluate_subexp (nullptr, exp, pos, noside);
|
||||
if (noside == EVAL_SKIP)
|
||||
@@ -3354,12 +3347,17 @@ parse_and_eval_type (char *p, int length)
|
||||
return expr->elts[1].type;
|
||||
}
|
||||
|
||||
+/* Return the number of dimensions for a Fortran array or string. */
|
||||
+
|
||||
int
|
||||
calc_f77_array_dims (struct type *array_type)
|
||||
{
|
||||
int ndimen = 1;
|
||||
struct type *tmp_type;
|
||||
|
||||
+ if ((array_type->code () == TYPE_CODE_STRING))
|
||||
+ return 1;
|
||||
+
|
||||
if ((array_type->code () != TYPE_CODE_ARRAY))
|
||||
error (_("Can't get dimensions for a non-array type"));
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Tue, 25 May 2021 17:34:57 -0700
|
||||
Subject: gdb-rhbz1964167-fortran-fix-type-format-mismatch-in-f-lang.c.patch
|
||||
|
||||
;; [fortran] Backport Simon Marchi's commit which fixes a 32-bit build
|
||||
;; problem in gdb/f-lang.c.
|
||||
|
||||
gdb: fix format string warnings in f-lang.c
|
||||
|
||||
I get a bunch of these warnings when compiling for i386 (32-bit):
|
||||
|
||||
CXX f-lang.o
|
||||
/home/simark/src/binutils-gdb/gdb/f-lang.c: In function 'value* fortran_value_subarray(value*, expression*, int*, int, noside)':
|
||||
/home/simark/src/binutils-gdb/gdb/f-lang.c:453:48: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'LONGEST' {aka 'long long int'} [-Werror=format=]
|
||||
453 | debug_printf ("| | |-> Low bound: %ld\n", lb);
|
||||
| ~~^ ~~
|
||||
| | |
|
||||
| | LONGEST {aka long long int}
|
||||
| long int
|
||||
| %lld
|
||||
|
||||
Fix them by using plongest/pulongest.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* f-lang.c (fortran_value_subarray): Use plongest/pulongest.
|
||||
|
||||
Change-Id: I666ead5593653d5a1a3dab2ffdc72942c928c7d2
|
||||
|
||||
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
|
||||
--- a/gdb/f-lang.c
|
||||
+++ b/gdb/f-lang.c
|
||||
@@ -463,21 +463,21 @@ fortran_value_subarray (struct value *array, struct expression *exp,
|
||||
std::string str = type_to_string (dim_type);
|
||||
debug_printf ("| |-> Type: %s\n", str.c_str ());
|
||||
debug_printf ("| |-> Array:\n");
|
||||
- debug_printf ("| | |-> Low bound: %ld\n", lb);
|
||||
- debug_printf ("| | |-> High bound: %ld\n", ub);
|
||||
- debug_printf ("| | |-> Bit stride: %ld\n", sd);
|
||||
- debug_printf ("| | |-> Byte stride: %ld\n", sd / 8);
|
||||
- debug_printf ("| | |-> Type size: %ld\n",
|
||||
- TYPE_LENGTH (dim_type));
|
||||
- debug_printf ("| | '-> Target type size: %ld\n",
|
||||
- TYPE_LENGTH (target_type));
|
||||
+ debug_printf ("| | |-> Low bound: %s\n", plongest (lb));
|
||||
+ debug_printf ("| | |-> High bound: %s\n", plongest (ub));
|
||||
+ debug_printf ("| | |-> Bit stride: %s\n", plongest (sd));
|
||||
+ debug_printf ("| | |-> Byte stride: %s\n", plongest (sd / 8));
|
||||
+ debug_printf ("| | |-> Type size: %s\n",
|
||||
+ pulongest (TYPE_LENGTH (dim_type)));
|
||||
+ debug_printf ("| | '-> Target type size: %s\n",
|
||||
+ pulongest (TYPE_LENGTH (target_type)));
|
||||
debug_printf ("| |-> Accessing:\n");
|
||||
- debug_printf ("| | |-> Low bound: %ld\n",
|
||||
- low);
|
||||
- debug_printf ("| | |-> High bound: %ld\n",
|
||||
- high);
|
||||
- debug_printf ("| | '-> Element stride: %ld\n",
|
||||
- stride);
|
||||
+ debug_printf ("| | |-> Low bound: %s\n",
|
||||
+ plongest (low));
|
||||
+ debug_printf ("| | |-> High bound: %s\n",
|
||||
+ plongest (high));
|
||||
+ debug_printf ("| | '-> Element stride: %s\n",
|
||||
+ plongest (stride));
|
||||
}
|
||||
|
||||
/* Check the user hasn't asked for something invalid. */
|
||||
@@ -519,13 +519,17 @@ fortran_value_subarray (struct value *array, struct expression *exp,
|
||||
if (fortran_array_slicing_debug)
|
||||
{
|
||||
debug_printf ("| '-> Results:\n");
|
||||
- debug_printf ("| |-> Offset = %ld\n", offset);
|
||||
- debug_printf ("| |-> Elements = %ld\n", e_count);
|
||||
- debug_printf ("| |-> Low bound = %ld\n", new_low);
|
||||
- debug_printf ("| |-> High bound = %ld\n", new_high);
|
||||
- debug_printf ("| |-> Byte stride = %ld\n", new_stride);
|
||||
- debug_printf ("| |-> Last element = %ld\n", last_elem);
|
||||
- debug_printf ("| |-> Remainder = %ld\n", remainder);
|
||||
+ debug_printf ("| |-> Offset = %s\n", plongest (offset));
|
||||
+ debug_printf ("| |-> Elements = %s\n", plongest (e_count));
|
||||
+ debug_printf ("| |-> Low bound = %s\n", plongest (new_low));
|
||||
+ debug_printf ("| |-> High bound = %s\n",
|
||||
+ plongest (new_high));
|
||||
+ debug_printf ("| |-> Byte stride = %s\n",
|
||||
+ plongest (new_stride));
|
||||
+ debug_printf ("| |-> Last element = %s\n",
|
||||
+ plongest (last_elem));
|
||||
+ debug_printf ("| |-> Remainder = %s\n",
|
||||
+ plongest (remainder));
|
||||
debug_printf ("| '-> Contiguous = %s\n",
|
||||
(is_dim_contiguous ? "Yes" : "No"));
|
||||
}
|
||||
@@ -561,14 +565,16 @@ fortran_value_subarray (struct value *array, struct expression *exp,
|
||||
std::string str = type_to_string (dim_type);
|
||||
debug_printf ("| |-> Type: %s\n", str.c_str ());
|
||||
debug_printf ("| |-> Array:\n");
|
||||
- debug_printf ("| | |-> Low bound: %ld\n", lb);
|
||||
- debug_printf ("| | |-> High bound: %ld\n", ub);
|
||||
- debug_printf ("| | |-> Byte stride: %ld\n", sd);
|
||||
- debug_printf ("| | |-> Type size: %ld\n", TYPE_LENGTH (dim_type));
|
||||
- debug_printf ("| | '-> Target type size: %ld\n",
|
||||
- TYPE_LENGTH (target_type));
|
||||
+ debug_printf ("| | |-> Low bound: %s\n", plongest (lb));
|
||||
+ debug_printf ("| | |-> High bound: %s\n", plongest (ub));
|
||||
+ debug_printf ("| | |-> Byte stride: %s\n", plongest (sd));
|
||||
+ debug_printf ("| | |-> Type size: %s\n",
|
||||
+ pulongest (TYPE_LENGTH (dim_type)));
|
||||
+ debug_printf ("| | '-> Target type size: %s\n",
|
||||
+ pulongest (TYPE_LENGTH (target_type)));
|
||||
debug_printf ("| '-> Accessing:\n");
|
||||
- debug_printf ("| '-> Index: %ld\n", index);
|
||||
+ debug_printf ("| '-> Index: %s\n",
|
||||
+ plongest (index));
|
||||
}
|
||||
|
||||
/* If the array has actual content then check the index is in
|
||||
@@ -625,7 +631,8 @@ fortran_value_subarray (struct value *array, struct expression *exp,
|
||||
debug_printf ("'-> Final result:\n");
|
||||
debug_printf (" |-> Type: %s\n",
|
||||
type_to_string (array_slice_type).c_str ());
|
||||
- debug_printf (" |-> Total offset: %ld\n", total_offset);
|
||||
+ debug_printf (" |-> Total offset: %s\n",
|
||||
+ plongest (total_offset));
|
||||
debug_printf (" |-> Base address: %s\n",
|
||||
core_addr_to_string (value_address (array)));
|
||||
debug_printf (" '-> Contiguous = %s\n",
|
|
@ -0,0 +1,224 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Mon, 24 May 2021 17:15:27 -0700
|
||||
Subject: gdb-rhbz1964167-fortran-range_type-to-range_flag.patch
|
||||
|
||||
;; [fortran] Backport Andrew Burgess's commit which renames enum
|
||||
;; range_type to enum range_flag.
|
||||
|
||||
gdb: rename 'enum range_type' to 'enum range_flag'
|
||||
|
||||
To avoid confusion with other parts of GDB relating to types and
|
||||
ranges, rename this enum to make it clearer that it is a set of
|
||||
individual flags rather than an enumeration of different types of
|
||||
range.
|
||||
|
||||
There should be no user visible changes after this commit.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* expprint.c (print_subexp_standard): Change enum range_type to
|
||||
range_flag and rename variables to match.
|
||||
(dump_subexp_body_standard): Likewise.
|
||||
* expression.h (enum range_type): Rename to...
|
||||
(enum range_flag): ...this.
|
||||
(range_types): Rename to...
|
||||
(range_flags): ...this.
|
||||
* f-lang.c (value_f90_subarray): Change enum range_type to
|
||||
range_flag and rename variables to match.
|
||||
* parse.c (operator_length_standard): Likewise.
|
||||
* rust-exp.y (rust_parser::convert_ast_to_expression): Change enum
|
||||
range_type to range_flag.
|
||||
* rust-lang.c (rust_evaluate_funcall): Likewise.
|
||||
(rust_range): Likewise.
|
||||
(rust_compute_range): Likewise.
|
||||
(rust_subscript): Likewise.
|
||||
|
||||
diff --git a/gdb/expprint.c b/gdb/expprint.c
|
||||
--- a/gdb/expprint.c
|
||||
+++ b/gdb/expprint.c
|
||||
@@ -578,19 +578,19 @@ print_subexp_standard (struct expression *exp, int *pos,
|
||||
|
||||
case OP_RANGE:
|
||||
{
|
||||
- enum range_type range_type;
|
||||
+ enum range_flag range_flag;
|
||||
|
||||
- range_type = (enum range_type)
|
||||
+ range_flag = (enum range_flag)
|
||||
longest_to_int (exp->elts[pc + 1].longconst);
|
||||
*pos += 2;
|
||||
|
||||
- if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
|
||||
+ if (range_flag & RANGE_HIGH_BOUND_EXCLUSIVE)
|
||||
fputs_filtered ("EXCLUSIVE_", stream);
|
||||
fputs_filtered ("RANGE(", stream);
|
||||
- if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
|
||||
+ if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
|
||||
print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
|
||||
fputs_filtered ("..", stream);
|
||||
- if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
|
||||
+ if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
|
||||
print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
|
||||
fputs_filtered (")", stream);
|
||||
return;
|
||||
@@ -1104,25 +1104,25 @@ dump_subexp_body_standard (struct expression *exp,
|
||||
break;
|
||||
case OP_RANGE:
|
||||
{
|
||||
- enum range_type range_type;
|
||||
+ enum range_flag range_flag;
|
||||
|
||||
- range_type = (enum range_type)
|
||||
+ range_flag = (enum range_flag)
|
||||
longest_to_int (exp->elts[elt].longconst);
|
||||
elt += 2;
|
||||
|
||||
- if (range_type & RANGE_HIGH_BOUND_EXCLUSIVE)
|
||||
+ if (range_flag & RANGE_HIGH_BOUND_EXCLUSIVE)
|
||||
fputs_filtered ("Exclusive", stream);
|
||||
fputs_filtered ("Range '", stream);
|
||||
- if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
|
||||
+ if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
|
||||
fputs_filtered ("EXP", stream);
|
||||
fputs_filtered ("..", stream);
|
||||
- if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
|
||||
+ if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
|
||||
fputs_filtered ("EXP", stream);
|
||||
fputs_filtered ("'", stream);
|
||||
|
||||
- if (!(range_type & RANGE_LOW_BOUND_DEFAULT))
|
||||
+ if (!(range_flag & RANGE_LOW_BOUND_DEFAULT))
|
||||
elt = dump_subexp (exp, stream, elt);
|
||||
- if (!(range_type & RANGE_HIGH_BOUND_DEFAULT))
|
||||
+ if (!(range_flag & RANGE_HIGH_BOUND_DEFAULT))
|
||||
elt = dump_subexp (exp, stream, elt);
|
||||
}
|
||||
break;
|
||||
diff --git a/gdb/expression.h b/gdb/expression.h
|
||||
--- a/gdb/expression.h
|
||||
+++ b/gdb/expression.h
|
||||
@@ -185,7 +185,7 @@ extern void dump_prefix_expression (struct expression *, struct ui_file *);
|
||||
or inclusive. So we have six sorts of subrange. This enumeration
|
||||
type is to identify this. */
|
||||
|
||||
-enum range_type : unsigned
|
||||
+enum range_flag : unsigned
|
||||
{
|
||||
/* This is a standard range. Both the lower and upper bounds are
|
||||
defined, and the bounds are inclusive. */
|
||||
@@ -201,6 +201,6 @@ enum range_type : unsigned
|
||||
RANGE_HIGH_BOUND_EXCLUSIVE = 1 << 2,
|
||||
};
|
||||
|
||||
-DEF_ENUM_FLAGS_TYPE (enum range_type, range_types);
|
||||
+DEF_ENUM_FLAGS_TYPE (enum range_flag, range_flags);
|
||||
|
||||
#endif /* !defined (EXPRESSION_H) */
|
||||
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
|
||||
--- a/gdb/f-lang.c
|
||||
+++ b/gdb/f-lang.c
|
||||
@@ -126,17 +126,17 @@ value_f90_subarray (struct value *array,
|
||||
int pc = (*pos) + 1;
|
||||
LONGEST low_bound, high_bound;
|
||||
struct type *range = check_typedef (value_type (array)->index_type ());
|
||||
- enum range_type range_type
|
||||
- = (enum range_type) longest_to_int (exp->elts[pc].longconst);
|
||||
+ enum range_flag range_flag
|
||||
+ = (enum range_flag) longest_to_int (exp->elts[pc].longconst);
|
||||
|
||||
*pos += 3;
|
||||
|
||||
- if (range_type & RANGE_LOW_BOUND_DEFAULT)
|
||||
+ if (range_flag & RANGE_LOW_BOUND_DEFAULT)
|
||||
low_bound = range->bounds ()->low.const_val ();
|
||||
else
|
||||
low_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
|
||||
- if (range_type & RANGE_HIGH_BOUND_DEFAULT)
|
||||
+ if (range_flag & RANGE_HIGH_BOUND_DEFAULT)
|
||||
high_bound = range->bounds ()->high.const_val ();
|
||||
else
|
||||
high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
diff --git a/gdb/parse.c b/gdb/parse.c
|
||||
--- a/gdb/parse.c
|
||||
+++ b/gdb/parse.c
|
||||
@@ -774,7 +774,7 @@ operator_length_standard (const struct expression *expr, int endpos,
|
||||
{
|
||||
int oplen = 1;
|
||||
int args = 0;
|
||||
- enum range_type range_type;
|
||||
+ enum range_flag range_flag;
|
||||
int i;
|
||||
|
||||
if (endpos < 1)
|
||||
@@ -918,15 +918,15 @@ operator_length_standard (const struct expression *expr, int endpos,
|
||||
|
||||
case OP_RANGE:
|
||||
oplen = 3;
|
||||
- range_type = (enum range_type)
|
||||
+ range_flag = (enum range_flag)
|
||||
longest_to_int (expr->elts[endpos - 2].longconst);
|
||||
|
||||
/* Assume the range has 2 arguments (low bound and high bound), then
|
||||
reduce the argument count if any bounds are set to default. */
|
||||
args = 2;
|
||||
- if (range_type & RANGE_LOW_BOUND_DEFAULT)
|
||||
+ if (range_flag & RANGE_LOW_BOUND_DEFAULT)
|
||||
--args;
|
||||
- if (range_type & RANGE_HIGH_BOUND_DEFAULT)
|
||||
+ if (range_flag & RANGE_HIGH_BOUND_DEFAULT)
|
||||
--args;
|
||||
|
||||
break;
|
||||
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
|
||||
--- a/gdb/rust-exp.y
|
||||
+++ b/gdb/rust-exp.y
|
||||
@@ -2492,7 +2492,7 @@ rust_parser::convert_ast_to_expression (const struct rust_op *operation,
|
||||
|
||||
case OP_RANGE:
|
||||
{
|
||||
- enum range_type kind = (RANGE_HIGH_BOUND_DEFAULT
|
||||
+ unsigned int kind = (RANGE_HIGH_BOUND_DEFAULT
|
||||
| RANGE_LOW_BOUND_DEFAULT);
|
||||
|
||||
if (operation->left.op != NULL)
|
||||
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
|
||||
--- a/gdb/rust-lang.c
|
||||
+++ b/gdb/rust-lang.c
|
||||
@@ -1070,7 +1070,6 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
|
||||
static struct value *
|
||||
rust_range (struct expression *exp, int *pos, enum noside noside)
|
||||
{
|
||||
- enum range_type kind;
|
||||
struct value *low = NULL, *high = NULL;
|
||||
struct value *addrval, *result;
|
||||
CORE_ADDR addr;
|
||||
@@ -1079,7 +1078,8 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
|
||||
struct type *temp_type;
|
||||
const char *name;
|
||||
|
||||
- kind = (enum range_type) longest_to_int (exp->elts[*pos + 1].longconst);
|
||||
+ auto kind
|
||||
+ = (enum range_flag) longest_to_int (exp->elts[*pos + 1].longconst);
|
||||
*pos += 3;
|
||||
|
||||
if (!(kind & RANGE_LOW_BOUND_DEFAULT))
|
||||
@@ -1169,7 +1169,7 @@ rust_range (struct expression *exp, int *pos, enum noside noside)
|
||||
static void
|
||||
rust_compute_range (struct type *type, struct value *range,
|
||||
LONGEST *low, LONGEST *high,
|
||||
- range_types *kind)
|
||||
+ range_flags *kind)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1209,7 +1209,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
|
||||
struct type *rhstype;
|
||||
LONGEST low, high_bound;
|
||||
/* Initialized to appease the compiler. */
|
||||
- range_types kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
|
||||
+ range_flags kind = RANGE_LOW_BOUND_DEFAULT | RANGE_HIGH_BOUND_DEFAULT;
|
||||
LONGEST high = 0;
|
||||
int want_slice = 0;
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Mon, 24 May 2021 17:07:36 -0700
|
||||
Subject: gdb-rhbz1964167-fortran-whitespace_array.patch
|
||||
|
||||
;; [fortran] Backport Andrew Burgess's commit which eliminates undesirable
|
||||
;; whitespace when printing arrays.
|
||||
|
||||
gdb/fortran: Change whitespace when printing arrays
|
||||
|
||||
This commit makes the whitespace usage when printing Fortran arrays
|
||||
more consistent, and more inline with how we print C arrays.
|
||||
|
||||
Currently a 2 dimensional Fotran array is printed like this, I find
|
||||
the marked whitespace unpleasant:
|
||||
|
||||
(( 1, 2, 3) ( 4, 5, 6) )
|
||||
^ ^ ^
|
||||
|
||||
After this commit the same array is printed like this:
|
||||
|
||||
((1, 2, 3) (4, 5, 6))
|
||||
|
||||
Which seems more inline with how we print C arrays, in the case of C
|
||||
arrays we don't add extra whitespace before the first element.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* f-valprint.c (f77_print_array_1): Adjust printing of whitespace
|
||||
for arrays.
|
||||
|
||||
gdb/testsuite/ChangeLog:
|
||||
|
||||
* gdb.fortran/array-slices.exp: Update expected results.
|
||||
* gdb.fortran/class-allocatable-array.exp: Likewise.
|
||||
* gdb.fortran/multi-dim.exp: Likewise.
|
||||
* gdb.fortran/vla-type.exp: Likewise.
|
||||
* gdb.mi/mi-vla-fortran.exp: Likewise.
|
||||
|
||||
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
|
||||
--- a/gdb/f-valprint.c
|
||||
+++ b/gdb/f-valprint.c
|
||||
@@ -137,14 +137,17 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type,
|
||||
(TYPE_TARGET_TYPE (type), value_contents_for_printing_const (val)
|
||||
+ offs, addr + offs);
|
||||
|
||||
- fprintf_filtered (stream, "( ");
|
||||
+ fprintf_filtered (stream, "(");
|
||||
f77_print_array_1 (nss + 1, ndimensions, value_type (subarray),
|
||||
value_contents_for_printing (subarray),
|
||||
value_embedded_offset (subarray),
|
||||
value_address (subarray),
|
||||
stream, recurse, subarray, options, elts);
|
||||
offs += byte_stride;
|
||||
- fprintf_filtered (stream, ") ");
|
||||
+ fprintf_filtered (stream, ")");
|
||||
+
|
||||
+ if (i < upperbound)
|
||||
+ fprintf_filtered (stream, " ");
|
||||
}
|
||||
if (*elts >= options->print_max && i < upperbound)
|
||||
fprintf_filtered (stream, "...");
|
||||
diff --git a/gdb/testsuite/gdb.fortran/array-slices.exp b/gdb/testsuite/gdb.fortran/array-slices.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/array-slices.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/array-slices.exp
|
||||
@@ -38,14 +38,14 @@ gdb_breakpoint [gdb_get_line_number "Final Breakpoint"]
|
||||
|
||||
set array_contents \
|
||||
[list \
|
||||
- " = \\(\\( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\) \\( 11, 12, 13, 14, 15, 16, 17, 18, 19, 20\\) \\( 21, 22, 23, 24, 25, 26, 27, 28, 29, 30\\) \\( 31, 32, 33, 34, 35, 36, 37, 38, 39, 40\\) \\( 41, 42, 43, 44, 45, 46, 47, 48, 49, 50\\) \\( 51, 52, 53, 54, 55, 56, 57, 58, 59, 60\\) \\( 61, 62, 63, 64, 65, 66, 67, 68, 69, 70\\) \\( 71, 72, 73, 74, 75, 76, 77, 78, 79, 80\\) \\( 81, 82, 83, 84, 85, 86, 87, 88, 89, 90\\) \\( 91, 92, 93, 94, 95, 96, 97, 98, 99, 100\\) \\)" \
|
||||
- " = \\(\\( 1, 2, 3, 4, 5\\) \\( 11, 12, 13, 14, 15\\) \\( 21, 22, 23, 24, 25\\) \\( 31, 32, 33, 34, 35\\) \\( 41, 42, 43, 44, 45\\) \\)" \
|
||||
- " = \\(\\( 1, 3, 5, 7, 9\\) \\( 21, 23, 25, 27, 29\\) \\( 41, 43, 45, 47, 49\\) \\( 61, 63, 65, 67, 69\\) \\( 81, 83, 85, 87, 89\\) \\)" \
|
||||
- " = \\(\\( 1, 4, 7, 10\\) \\( 21, 24, 27, 30\\) \\( 41, 44, 47, 50\\) \\( 61, 64, 67, 70\\) \\( 81, 84, 87, 90\\) \\)" \
|
||||
- " = \\(\\( 1, 5, 9\\) \\( 31, 35, 39\\) \\( 61, 65, 69\\) \\( 91, 95, 99\\) \\)" \
|
||||
- " = \\(\\( -26, -25, -24, -23, -22, -21, -20, -19, -18, -17\\) \\( -19, -18, -17, -16, -15, -14, -13, -12, -11, -10\\) \\( -12, -11, -10, -9, -8, -7, -6, -5, -4, -3\\) \\( -5, -4, -3, -2, -1, 0, 1, 2, 3, 4\\) \\( 2, 3, 4, 5, 6, 7, 8, 9, 10, 11\\) \\( 9, 10, 11, 12, 13, 14, 15, 16, 17, 18\\) \\( 16, 17, 18, 19, 20, 21, 22, 23, 24, 25\\) \\( 23, 24, 25, 26, 27, 28, 29, 30, 31, 32\\) \\( 30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\) \\( 37, 38, 39, 40, 41, 42, 43, 44, 45, 46\\) \\)" \
|
||||
- " = \\(\\( -26, -25, -24, -23, -22, -21\\) \\( -19, -18, -17, -16, -15, -14\\) \\( -12, -11, -10, -9, -8, -7\\) \\)" \
|
||||
- " = \\(\\( -26, -24, -22, -20, -18\\) \\( -5, -3, -1, 1, 3\\) \\( 16, 18, 20, 22, 24\\) \\( 37, 39, 41, 43, 45\\) \\)" ]
|
||||
+ " = \\(\\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\) \\(11, 12, 13, 14, 15, 16, 17, 18, 19, 20\\) \\(21, 22, 23, 24, 25, 26, 27, 28, 29, 30\\) \\(31, 32, 33, 34, 35, 36, 37, 38, 39, 40\\) \\(41, 42, 43, 44, 45, 46, 47, 48, 49, 50\\) \\(51, 52, 53, 54, 55, 56, 57, 58, 59, 60\\) \\(61, 62, 63, 64, 65, 66, 67, 68, 69, 70\\) \\(71, 72, 73, 74, 75, 76, 77, 78, 79, 80\\) \\(81, 82, 83, 84, 85, 86, 87, 88, 89, 90\\) \\(91, 92, 93, 94, 95, 96, 97, 98, 99, 100\\)\\)" \
|
||||
+ " = \\(\\(1, 2, 3, 4, 5\\) \\(11, 12, 13, 14, 15\\) \\(21, 22, 23, 24, 25\\) \\(31, 32, 33, 34, 35\\) \\(41, 42, 43, 44, 45\\)\\)" \
|
||||
+ " = \\(\\(1, 3, 5, 7, 9\\) \\(21, 23, 25, 27, 29\\) \\(41, 43, 45, 47, 49\\) \\(61, 63, 65, 67, 69\\) \\(81, 83, 85, 87, 89\\)\\)" \
|
||||
+ " = \\(\\(1, 4, 7, 10\\) \\(21, 24, 27, 30\\) \\(41, 44, 47, 50\\) \\(61, 64, 67, 70\\) \\(81, 84, 87, 90\\)\\)" \
|
||||
+ " = \\(\\(1, 5, 9\\) \\(31, 35, 39\\) \\(61, 65, 69\\) \\(91, 95, 99\\)\\)" \
|
||||
+ " = \\(\\(-26, -25, -24, -23, -22, -21, -20, -19, -18, -17\\) \\(-19, -18, -17, -16, -15, -14, -13, -12, -11, -10\\) \\(-12, -11, -10, -9, -8, -7, -6, -5, -4, -3\\) \\(-5, -4, -3, -2, -1, 0, 1, 2, 3, 4\\) \\(2, 3, 4, 5, 6, 7, 8, 9, 10, 11\\) \\(9, 10, 11, 12, 13, 14, 15, 16, 17, 18\\) \\(16, 17, 18, 19, 20, 21, 22, 23, 24, 25\\) \\(23, 24, 25, 26, 27, 28, 29, 30, 31, 32\\) \\(30, 31, 32, 33, 34, 35, 36, 37, 38, 39\\) \\(37, 38, 39, 40, 41, 42, 43, 44, 45, 46\\)\\)" \
|
||||
+ " = \\(\\(-26, -25, -24, -23, -22, -21\\) \\(-19, -18, -17, -16, -15, -14\\) \\(-12, -11, -10, -9, -8, -7\\)\\)" \
|
||||
+ " = \\(\\(-26, -24, -22, -20, -18\\) \\(-5, -3, -1, 1, 3\\) \\(16, 18, 20, 22, 24\\) \\(37, 39, 41, 43, 45\\)\\)" ]
|
||||
|
||||
set message_strings \
|
||||
[list \
|
||||
diff --git a/gdb/testsuite/gdb.fortran/class-allocatable-array.exp b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/class-allocatable-array.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/class-allocatable-array.exp
|
||||
@@ -40,4 +40,4 @@ gdb_continue_to_breakpoint "Break Here"
|
||||
# cetainly going to fail.
|
||||
gdb_test "print this" " = \\( _data = \[^\r\n\]+, _vptr = \[^\r\n\]+\\)"
|
||||
gdb_test "print this%_data" " = \\(PTR TO -> \\( Type test_type \\)\\) \[^\r\n\]+"
|
||||
-gdb_test "print this%_data%b" " = \\(\\( 1, 2, 3\\) \\( 4, 5, 6\\) \\)"
|
||||
+gdb_test "print this%_data%b" " = \\(\\(1, 2, 3\\) \\(4, 5, 6\\)\\)"
|
||||
diff --git a/gdb/testsuite/gdb.fortran/multi-dim.exp b/gdb/testsuite/gdb.fortran/multi-dim.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/multi-dim.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/multi-dim.exp
|
||||
@@ -57,7 +57,7 @@ gdb_test "print foo(3,3,4)" \
|
||||
"print an invalid array index (3,3,4)"
|
||||
|
||||
gdb_test "print foo" \
|
||||
- { = \(\( \( 10, 10\) \( 10, 10\) \( 10, 10\) \) \( \( 10, 10\) \( 10, 10\) \( 10, 10\) \) \( \( 10, 10\) \( 10, 10\) \( 10, 10\) \) \( \( 10, 10\) \( 10, 10\) \( 10, 20\) \) \)} \
|
||||
+ { = \(\(\(10, 10\) \(10, 10\) \(10, 10\)\) \(\(10, 10\) \(10, 10\) \(10, 10\)\) \(\(10, 10\) \(10, 10\) \(10, 10\)\) \(\(10, 10\) \(10, 10\) \(10, 20\)\)\)} \
|
||||
"print full contents of the array"
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "break-variable"]
|
||||
diff --git a/gdb/testsuite/gdb.fortran/vla-type.exp b/gdb/testsuite/gdb.fortran/vla-type.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/vla-type.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/vla-type.exp
|
||||
@@ -66,9 +66,9 @@ gdb_test "ptype twov" \
|
||||
"\\s+$int, allocatable :: ivla1\\\(5,12,99\\\)" \
|
||||
"\\s+$int, allocatable :: ivla2\\\(9,12\\\)" \
|
||||
"End Type two" ]
|
||||
-gdb_test "print twov" " = \\\( ivla1 = \\\(\\\( \\\( 1, 1, 1, 1, 1\\\)\
|
||||
- \\\( 1, 1, 321, 1, 1\\\)\
|
||||
- \\\( 1, 1, 1, 1, 1\\\) .*"
|
||||
+gdb_test "print twov" " = \\\( ivla1 = \\\(\\\(\\\(1, 1, 1, 1, 1\\\)\
|
||||
+ \\\(1, 1, 321, 1, 1\\\)\
|
||||
+ \\\(1, 1, 1, 1, 1\\\) .*"
|
||||
|
||||
# Check type with attribute at beginn of type
|
||||
gdb_breakpoint [gdb_get_line_number "threev-filled"]
|
||||
diff --git a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp
|
||||
--- a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp
|
||||
+++ b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp
|
||||
@@ -180,7 +180,7 @@ mi_run_cmd
|
||||
mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \
|
||||
{ "" "disp=\"del\"" } "run to breakpoint at line $bp_lineno"
|
||||
mi_gdb_test "590-data-evaluate-expression pvla2" \
|
||||
- "590\\^done,value=\"\\(\\( 2, 2, 2, 2, 2\\) \\( 2, 2, 2, 2, 2\\) \\)\"" \
|
||||
+ "590\\^done,value=\"\\(\\(2, 2, 2, 2, 2\\) \\(2, 2, 2, 2, 2\\)\\)\"" \
|
||||
"evaluate associated vla"
|
||||
|
||||
mi_create_varobj_checked pvla2_associated pvla2 \
|
|
@ -0,0 +1,787 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Buettner <kevinb@redhat.com>
|
||||
Date: Mon, 24 May 2021 17:00:17 -0700
|
||||
Subject: gdb-rhbz1964167-move-fortran-expr-handling.patch
|
||||
|
||||
;; [fortran] Backport Andrew Burgess's commit which moves Fortran
|
||||
;; expression handling to f-lang.c.
|
||||
|
||||
gdb/fortran: Move Fortran expression handling into f-lang.c
|
||||
|
||||
The Fortran specific OP_F77_UNDETERMINED_ARGLIST is currently handled
|
||||
in the generic expression handling code. There's no reason why this
|
||||
should be the case, so this commit moves handling of this into Fortran
|
||||
specific files.
|
||||
|
||||
There should be no user visible changes after this commit.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
* eval.c: Remove 'f-lang.h' include.
|
||||
(value_f90_subarray): Moved to f-lang.c.
|
||||
(eval_call): Renamed to...
|
||||
(evaluate_subexp_do_call): ...this, is no longer static, header
|
||||
comment moved into header file.
|
||||
(evaluate_funcall): Update call to eval_call.
|
||||
(skip_undetermined_arglist): Moved to f-lang.c.
|
||||
(fortran_value_subarray): Likewise.
|
||||
(evaluate_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling
|
||||
moved to evaluate_subexp_f.
|
||||
(calc_f77_array_dims): Moved to f-lang.c
|
||||
* expprint.c (print_subexp_funcall): New function.
|
||||
(print_subexp_standard): OP_F77_UNDETERMINED_ARGLIST handling
|
||||
moved to print_subexp_f, OP_FUNCALL uses new function.
|
||||
(dump_subexp_body_funcall): New function.
|
||||
(dump_subexp_body_standard): OP_F77_UNDETERMINED_ARGLIST handling
|
||||
moved to dump_subexp_f, OP_FUNCALL uses new function.
|
||||
* expression.h (evaluate_subexp_do_call): Declare.
|
||||
* f-lang.c (value_f90_subarray): Moved from eval.c.
|
||||
(skip_undetermined_arglist): Likewise.
|
||||
(calc_f77_array_dims): Likewise.
|
||||
(fortran_value_subarray): Likewise.
|
||||
(evaluate_subexp_f): Add OP_F77_UNDETERMINED_ARGLIST support.
|
||||
(operator_length_f): Likewise.
|
||||
(print_subexp_f): Likewise.
|
||||
(dump_subexp_body_f): Likewise.
|
||||
* fortran-operator.def (OP_F77_UNDETERMINED_ARGLIST): Move
|
||||
declaration of this operation to here.
|
||||
* parse.c (operator_length_standard): OP_F77_UNDETERMINED_ARGLIST
|
||||
support moved to operator_length_f.
|
||||
* parser-defs.h (dump_subexp_body_funcall): Declare.
|
||||
(print_subexp_funcall): Declare.
|
||||
* std-operator.def (OP_F77_UNDETERMINED_ARGLIST): Moved to
|
||||
fortran-operator.def.
|
||||
|
||||
diff --git a/gdb/eval.c b/gdb/eval.c
|
||||
--- a/gdb/eval.c
|
||||
+++ b/gdb/eval.c
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "frame.h"
|
||||
#include "gdbthread.h"
|
||||
#include "language.h" /* For CAST_IS_CONVERSION. */
|
||||
-#include "f-lang.h" /* For array bound stuff. */
|
||||
#include "cp-abi.h"
|
||||
#include "infcall.h"
|
||||
#include "objc-lang.h"
|
||||
@@ -371,32 +370,6 @@ init_array_element (struct value *array, struct value *element,
|
||||
return index;
|
||||
}
|
||||
|
||||
-static struct value *
|
||||
-value_f90_subarray (struct value *array,
|
||||
- struct expression *exp, int *pos, enum noside noside)
|
||||
-{
|
||||
- int pc = (*pos) + 1;
|
||||
- LONGEST low_bound, high_bound;
|
||||
- struct type *range = check_typedef (value_type (array)->index_type ());
|
||||
- enum range_type range_type
|
||||
- = (enum range_type) longest_to_int (exp->elts[pc].longconst);
|
||||
-
|
||||
- *pos += 3;
|
||||
-
|
||||
- if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
|
||||
- low_bound = range->bounds ()->low.const_val ();
|
||||
- else
|
||||
- low_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
-
|
||||
- if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
|
||||
- high_bound = range->bounds ()->high.const_val ();
|
||||
- else
|
||||
- high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
-
|
||||
- return value_slice (array, low_bound, high_bound - low_bound + 1);
|
||||
-}
|
||||
-
|
||||
-
|
||||
/* Promote value ARG1 as appropriate before performing a unary operation
|
||||
on this argument.
|
||||
If the result is not appropriate for any particular language then it
|
||||
@@ -749,17 +722,13 @@ eval_skip_value (expression *exp)
|
||||
return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
|
||||
}
|
||||
|
||||
-/* Evaluate a function call. The function to be called is in
|
||||
- ARGVEC[0] and the arguments passed to the function are in
|
||||
- ARGVEC[1..NARGS]. FUNCTION_NAME is the name of the function, if
|
||||
- known. DEFAULT_RETURN_TYPE is used as the function's return type
|
||||
- if the return type is unknown. */
|
||||
+/* See expression.h. */
|
||||
|
||||
-static value *
|
||||
-eval_call (expression *exp, enum noside noside,
|
||||
- int nargs, value **argvec,
|
||||
- const char *function_name,
|
||||
- type *default_return_type)
|
||||
+value *
|
||||
+evaluate_subexp_do_call (expression *exp, enum noside noside,
|
||||
+ int nargs, value **argvec,
|
||||
+ const char *function_name,
|
||||
+ type *default_return_type)
|
||||
{
|
||||
if (argvec[0] == NULL)
|
||||
error (_("Cannot evaluate function -- may be inlined"));
|
||||
@@ -1230,20 +1199,8 @@ evaluate_funcall (type *expect_type, expression *exp, int *pos,
|
||||
/* Nothing to be done; argvec already correctly set up. */
|
||||
}
|
||||
|
||||
- return eval_call (exp, noside, nargs, argvec, var_func_name, expect_type);
|
||||
-}
|
||||
-
|
||||
-/* Helper for skipping all the arguments in an undetermined argument list.
|
||||
- This function was designed for use in the OP_F77_UNDETERMINED_ARGLIST
|
||||
- case of evaluate_subexp_standard as multiple, but not all, code paths
|
||||
- require a generic skip. */
|
||||
-
|
||||
-static void
|
||||
-skip_undetermined_arglist (int nargs, struct expression *exp, int *pos,
|
||||
- enum noside noside)
|
||||
-{
|
||||
- for (int i = 0; i < nargs; ++i)
|
||||
- evaluate_subexp (nullptr, exp, pos, noside);
|
||||
+ return evaluate_subexp_do_call (exp, noside, nargs, argvec,
|
||||
+ var_func_name, expect_type);
|
||||
}
|
||||
|
||||
/* Return true if type is integral or reference to integral */
|
||||
@@ -1260,67 +1217,6 @@ is_integral_or_integral_reference (struct type *type)
|
||||
&& is_integral_type (TYPE_TARGET_TYPE (type)));
|
||||
}
|
||||
|
||||
-/* Called from evaluate_subexp_standard to perform array indexing, and
|
||||
- sub-range extraction, for Fortran. As well as arrays this function
|
||||
- also handles strings as they can be treated like arrays of characters.
|
||||
- ARRAY is the array or string being accessed. EXP, POS, and NOSIDE are
|
||||
- as for evaluate_subexp_standard, and NARGS is the number of arguments
|
||||
- in this access (e.g. 'array (1,2,3)' would be NARGS 3). */
|
||||
-
|
||||
-static struct value *
|
||||
-fortran_value_subarray (struct value *array, struct expression *exp,
|
||||
- int *pos, int nargs, enum noside noside)
|
||||
-{
|
||||
- if (exp->elts[*pos].opcode == OP_RANGE)
|
||||
- return value_f90_subarray (array, exp, pos, noside);
|
||||
-
|
||||
- if (noside == EVAL_SKIP)
|
||||
- {
|
||||
- skip_undetermined_arglist (nargs, exp, pos, noside);
|
||||
- /* Return the dummy value with the correct type. */
|
||||
- return array;
|
||||
- }
|
||||
-
|
||||
- LONGEST subscript_array[MAX_FORTRAN_DIMS];
|
||||
- int ndimensions = 1;
|
||||
- struct type *type = check_typedef (value_type (array));
|
||||
-
|
||||
- if (nargs > MAX_FORTRAN_DIMS)
|
||||
- error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
|
||||
-
|
||||
- ndimensions = calc_f77_array_dims (type);
|
||||
-
|
||||
- if (nargs != ndimensions)
|
||||
- error (_("Wrong number of subscripts"));
|
||||
-
|
||||
- gdb_assert (nargs > 0);
|
||||
-
|
||||
- /* Now that we know we have a legal array subscript expression let us
|
||||
- actually find out where this element exists in the array. */
|
||||
-
|
||||
- /* Take array indices left to right. */
|
||||
- for (int i = 0; i < nargs; i++)
|
||||
- {
|
||||
- /* Evaluate each subscript; it must be a legal integer in F77. */
|
||||
- value *arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
-
|
||||
- /* Fill in the subscript array. */
|
||||
- subscript_array[i] = value_as_long (arg2);
|
||||
- }
|
||||
-
|
||||
- /* Internal type of array is arranged right to left. */
|
||||
- for (int i = nargs; i > 0; i--)
|
||||
- {
|
||||
- struct type *array_type = check_typedef (value_type (array));
|
||||
- LONGEST index = subscript_array[i - 1];
|
||||
-
|
||||
- array = value_subscripted_rvalue (array, index,
|
||||
- f77_get_lowerbound (array_type));
|
||||
- }
|
||||
-
|
||||
- return array;
|
||||
-}
|
||||
-
|
||||
struct value *
|
||||
evaluate_subexp_standard (struct type *expect_type,
|
||||
struct expression *exp, int *pos,
|
||||
@@ -1335,7 +1231,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
struct type *type;
|
||||
int nargs;
|
||||
struct value **argvec;
|
||||
- int code;
|
||||
int ix;
|
||||
long mem_offset;
|
||||
struct type **arg_types;
|
||||
@@ -1976,84 +1871,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
case OP_FUNCALL:
|
||||
return evaluate_funcall (expect_type, exp, pos, noside);
|
||||
|
||||
- case OP_F77_UNDETERMINED_ARGLIST:
|
||||
-
|
||||
- /* Remember that in F77, functions, substring ops and
|
||||
- array subscript operations cannot be disambiguated
|
||||
- at parse time. We have made all array subscript operations,
|
||||
- substring operations as well as function calls come here
|
||||
- and we now have to discover what the heck this thing actually was.
|
||||
- If it is a function, we process just as if we got an OP_FUNCALL. */
|
||||
-
|
||||
- nargs = longest_to_int (exp->elts[pc + 1].longconst);
|
||||
- (*pos) += 2;
|
||||
-
|
||||
- /* First determine the type code we are dealing with. */
|
||||
- arg1 = evaluate_subexp (nullptr, exp, pos, noside);
|
||||
- type = check_typedef (value_type (arg1));
|
||||
- code = type->code ();
|
||||
-
|
||||
- if (code == TYPE_CODE_PTR)
|
||||
- {
|
||||
- /* Fortran always passes variable to subroutines as pointer.
|
||||
- So we need to look into its target type to see if it is
|
||||
- array, string or function. If it is, we need to switch
|
||||
- to the target value the original one points to. */
|
||||
- struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
-
|
||||
- if (target_type->code () == TYPE_CODE_ARRAY
|
||||
- || target_type->code () == TYPE_CODE_STRING
|
||||
- || target_type->code () == TYPE_CODE_FUNC)
|
||||
- {
|
||||
- arg1 = value_ind (arg1);
|
||||
- type = check_typedef (value_type (arg1));
|
||||
- code = type->code ();
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- switch (code)
|
||||
- {
|
||||
- case TYPE_CODE_ARRAY:
|
||||
- case TYPE_CODE_STRING:
|
||||
- return fortran_value_subarray (arg1, exp, pos, nargs, noside);
|
||||
-
|
||||
- case TYPE_CODE_PTR:
|
||||
- case TYPE_CODE_FUNC:
|
||||
- case TYPE_CODE_INTERNAL_FUNCTION:
|
||||
- /* It's a function call. */
|
||||
- /* Allocate arg vector, including space for the function to be
|
||||
- called in argvec[0] and a terminating NULL. */
|
||||
- argvec = (struct value **)
|
||||
- alloca (sizeof (struct value *) * (nargs + 2));
|
||||
- argvec[0] = arg1;
|
||||
- tem = 1;
|
||||
- for (; tem <= nargs; tem++)
|
||||
- {
|
||||
- argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
- /* Arguments in Fortran are passed by address. Coerce the
|
||||
- arguments here rather than in value_arg_coerce as otherwise
|
||||
- the call to malloc to place the non-lvalue parameters in
|
||||
- target memory is hit by this Fortran specific logic. This
|
||||
- results in malloc being called with a pointer to an integer
|
||||
- followed by an attempt to malloc the arguments to malloc in
|
||||
- target memory. Infinite recursion ensues. */
|
||||
- if (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC)
|
||||
- {
|
||||
- bool is_artificial
|
||||
- = TYPE_FIELD_ARTIFICIAL (value_type (arg1), tem - 1);
|
||||
- argvec[tem] = fortran_argument_convert (argvec[tem],
|
||||
- is_artificial);
|
||||
- }
|
||||
- }
|
||||
- argvec[tem] = 0; /* signal end of arglist */
|
||||
- if (noside == EVAL_SKIP)
|
||||
- return eval_skip_value (exp);
|
||||
- return eval_call (exp, noside, nargs, argvec, NULL, expect_type);
|
||||
-
|
||||
- default:
|
||||
- error (_("Cannot perform substring on this type"));
|
||||
- }
|
||||
-
|
||||
case OP_COMPLEX:
|
||||
/* We have a complex number, There should be 2 floating
|
||||
point numbers that compose it. */
|
||||
@@ -3346,27 +3163,3 @@ parse_and_eval_type (char *p, int length)
|
||||
error (_("Internal error in eval_type."));
|
||||
return expr->elts[1].type;
|
||||
}
|
||||
-
|
||||
-/* Return the number of dimensions for a Fortran array or string. */
|
||||
-
|
||||
-int
|
||||
-calc_f77_array_dims (struct type *array_type)
|
||||
-{
|
||||
- int ndimen = 1;
|
||||
- struct type *tmp_type;
|
||||
-
|
||||
- if ((array_type->code () == TYPE_CODE_STRING))
|
||||
- return 1;
|
||||
-
|
||||
- if ((array_type->code () != TYPE_CODE_ARRAY))
|
||||
- error (_("Can't get dimensions for a non-array type"));
|
||||
-
|
||||
- tmp_type = array_type;
|
||||
-
|
||||
- while ((tmp_type = TYPE_TARGET_TYPE (tmp_type)))
|
||||
- {
|
||||
- if (tmp_type->code () == TYPE_CODE_ARRAY)
|
||||
- ++ndimen;
|
||||
- }
|
||||
- return ndimen;
|
||||
-}
|
||||
diff --git a/gdb/expprint.c b/gdb/expprint.c
|
||||
--- a/gdb/expprint.c
|
||||
+++ b/gdb/expprint.c
|
||||
@@ -53,6 +53,25 @@ print_subexp (struct expression *exp, int *pos,
|
||||
exp->language_defn->la_exp_desc->print_subexp (exp, pos, stream, prec);
|
||||
}
|
||||
|
||||
+/* See parser-defs.h. */
|
||||
+
|
||||
+void
|
||||
+print_subexp_funcall (struct expression *exp, int *pos,
|
||||
+ struct ui_file *stream)
|
||||
+{
|
||||
+ (*pos) += 2;
|
||||
+ unsigned nargs = longest_to_int (exp->elts[*pos].longconst);
|
||||
+ print_subexp (exp, pos, stream, PREC_SUFFIX);
|
||||
+ fputs_filtered (" (", stream);
|
||||
+ for (unsigned tem = 0; tem < nargs; tem++)
|
||||
+ {
|
||||
+ if (tem != 0)
|
||||
+ fputs_filtered (", ", stream);
|
||||
+ print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
|
||||
+ }
|
||||
+ fputs_filtered (")", stream);
|
||||
+}
|
||||
+
|
||||
/* Standard implementation of print_subexp for use in language_defn
|
||||
vectors. */
|
||||
void
|
||||
@@ -187,18 +206,7 @@ print_subexp_standard (struct expression *exp, int *pos,
|
||||
return;
|
||||
|
||||
case OP_FUNCALL:
|
||||
- case OP_F77_UNDETERMINED_ARGLIST:
|
||||
- (*pos) += 2;
|
||||
- nargs = longest_to_int (exp->elts[pc + 1].longconst);
|
||||
- print_subexp (exp, pos, stream, PREC_SUFFIX);
|
||||
- fputs_filtered (" (", stream);
|
||||
- for (tem = 0; tem < nargs; tem++)
|
||||
- {
|
||||
- if (tem != 0)
|
||||
- fputs_filtered (", ", stream);
|
||||
- print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
|
||||
- }
|
||||
- fputs_filtered (")", stream);
|
||||
+ print_subexp_funcall (exp, pos, stream);
|
||||
return;
|
||||
|
||||
case OP_NAME:
|
||||
@@ -796,6 +804,22 @@ dump_subexp_body (struct expression *exp, struct ui_file *stream, int elt)
|
||||
return exp->language_defn->la_exp_desc->dump_subexp_body (exp, stream, elt);
|
||||
}
|
||||
|
||||
+/* See parser-defs.h. */
|
||||
+
|
||||
+int
|
||||
+dump_subexp_body_funcall (struct expression *exp,
|
||||
+ struct ui_file *stream, int elt)
|
||||
+{
|
||||
+ int nargs = longest_to_int (exp->elts[elt].longconst);
|
||||
+ fprintf_filtered (stream, "Number of args: %d", nargs);
|
||||
+ elt += 2;
|
||||
+
|
||||
+ for (int i = 1; i <= nargs + 1; i++)
|
||||
+ elt = dump_subexp (exp, stream, elt);
|
||||
+
|
||||
+ return elt;
|
||||
+}
|
||||
+
|
||||
/* Default value for subexp_body in exp_descriptor vector. */
|
||||
|
||||
int
|
||||
@@ -931,18 +955,7 @@ dump_subexp_body_standard (struct expression *exp,
|
||||
elt += 2;
|
||||
break;
|
||||
case OP_FUNCALL:
|
||||
- case OP_F77_UNDETERMINED_ARGLIST:
|
||||
- {
|
||||
- int i, nargs;
|
||||
-
|
||||
- nargs = longest_to_int (exp->elts[elt].longconst);
|
||||
-
|
||||
- fprintf_filtered (stream, "Number of args: %d", nargs);
|
||||
- elt += 2;
|
||||
-
|
||||
- for (i = 1; i <= nargs + 1; i++)
|
||||
- elt = dump_subexp (exp, stream, elt);
|
||||
- }
|
||||
+ elt = dump_subexp_body_funcall (exp, stream, elt);
|
||||
break;
|
||||
case OP_ARRAY:
|
||||
{
|
||||
diff --git a/gdb/expression.h b/gdb/expression.h
|
||||
--- a/gdb/expression.h
|
||||
+++ b/gdb/expression.h
|
||||
@@ -155,6 +155,18 @@ enum noside
|
||||
extern struct value *evaluate_subexp_standard
|
||||
(struct type *, struct expression *, int *, enum noside);
|
||||
|
||||
+/* Evaluate a function call. The function to be called is in ARGVEC[0] and
|
||||
+ the arguments passed to the function are in ARGVEC[1..NARGS].
|
||||
+ FUNCTION_NAME is the name of the function, if known.
|
||||
+ DEFAULT_RETURN_TYPE is used as the function's return type if the return
|
||||
+ type is unknown. */
|
||||
+
|
||||
+extern struct value *evaluate_subexp_do_call (expression *exp,
|
||||
+ enum noside noside,
|
||||
+ int nargs, value **argvec,
|
||||
+ const char *function_name,
|
||||
+ type *default_return_type);
|
||||
+
|
||||
/* From expprint.c */
|
||||
|
||||
extern void print_expression (struct expression *, struct ui_file *);
|
||||
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
|
||||
--- a/gdb/f-lang.c
|
||||
+++ b/gdb/f-lang.c
|
||||
@@ -114,6 +114,134 @@ enum f_primitive_types {
|
||||
nr_f_primitive_types
|
||||
};
|
||||
|
||||
+/* Called from fortran_value_subarray to take a slice of an array or a
|
||||
+ string. ARRAY is the array or string to be accessed. EXP, POS, and
|
||||
+ NOSIDE are as for evaluate_subexp_standard. Return a value that is a
|
||||
+ slice of the array. */
|
||||
+
|
||||
+static struct value *
|
||||
+value_f90_subarray (struct value *array,
|
||||
+ struct expression *exp, int *pos, enum noside noside)
|
||||
+{
|
||||
+ int pc = (*pos) + 1;
|
||||
+ LONGEST low_bound, high_bound;
|
||||
+ struct type *range = check_typedef (value_type (array)->index_type ());
|
||||
+ enum range_type range_type
|
||||
+ = (enum range_type) longest_to_int (exp->elts[pc].longconst);
|
||||
+
|
||||
+ *pos += 3;
|
||||
+
|
||||
+ if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
|
||||
+ low_bound = range->bounds ()->low.const_val ();
|
||||
+ else
|
||||
+ low_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
+
|
||||
+ if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT)
|
||||
+ high_bound = range->bounds ()->high.const_val ();
|
||||
+ else
|
||||
+ high_bound = value_as_long (evaluate_subexp (nullptr, exp, pos, noside));
|
||||
+
|
||||
+ return value_slice (array, low_bound, high_bound - low_bound + 1);
|
||||
+}
|
||||
+
|
||||
+/* Helper for skipping all the arguments in an undetermined argument list.
|
||||
+ This function was designed for use in the OP_F77_UNDETERMINED_ARGLIST
|
||||
+ case of evaluate_subexp_standard as multiple, but not all, code paths
|
||||
+ require a generic skip. */
|
||||
+
|
||||
+static void
|
||||
+skip_undetermined_arglist (int nargs, struct expression *exp, int *pos,
|
||||
+ enum noside noside)
|
||||
+{
|
||||
+ for (int i = 0; i < nargs; ++i)
|
||||
+ evaluate_subexp (nullptr, exp, pos, noside);
|
||||
+}
|
||||
+
|
||||
+/* Return the number of dimensions for a Fortran array or string. */
|
||||
+
|
||||
+int
|
||||
+calc_f77_array_dims (struct type *array_type)
|
||||
+{
|
||||
+ int ndimen = 1;
|
||||
+ struct type *tmp_type;
|
||||
+
|
||||
+ if ((array_type->code () == TYPE_CODE_STRING))
|
||||
+ return 1;
|
||||
+
|
||||
+ if ((array_type->code () != TYPE_CODE_ARRAY))
|
||||
+ error (_("Can't get dimensions for a non-array type"));
|
||||
+
|
||||
+ tmp_type = array_type;
|
||||
+
|
||||
+ while ((tmp_type = TYPE_TARGET_TYPE (tmp_type)))
|
||||
+ {
|
||||
+ if (tmp_type->code () == TYPE_CODE_ARRAY)
|
||||
+ ++ndimen;
|
||||
+ }
|
||||
+ return ndimen;
|
||||
+}
|
||||
+
|
||||
+/* Called from evaluate_subexp_standard to perform array indexing, and
|
||||
+ sub-range extraction, for Fortran. As well as arrays this function
|
||||
+ also handles strings as they can be treated like arrays of characters.
|
||||
+ ARRAY is the array or string being accessed. EXP, POS, and NOSIDE are
|
||||
+ as for evaluate_subexp_standard, and NARGS is the number of arguments
|
||||
+ in this access (e.g. 'array (1,2,3)' would be NARGS 3). */
|
||||
+
|
||||
+static struct value *
|
||||
+fortran_value_subarray (struct value *array, struct expression *exp,
|
||||
+ int *pos, int nargs, enum noside noside)
|
||||
+{
|
||||
+ if (exp->elts[*pos].opcode == OP_RANGE)
|
||||
+ return value_f90_subarray (array, exp, pos, noside);
|
||||
+
|
||||
+ if (noside == EVAL_SKIP)
|
||||
+ {
|
||||
+ skip_undetermined_arglist (nargs, exp, pos, noside);
|
||||
+ /* Return the dummy value with the correct type. */
|
||||
+ return array;
|
||||
+ }
|
||||
+
|
||||
+ LONGEST subscript_array[MAX_FORTRAN_DIMS];
|
||||
+ int ndimensions = 1;
|
||||
+ struct type *type = check_typedef (value_type (array));
|
||||
+
|
||||
+ if (nargs > MAX_FORTRAN_DIMS)
|
||||
+ error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS);
|
||||
+
|
||||
+ ndimensions = calc_f77_array_dims (type);
|
||||
+
|
||||
+ if (nargs != ndimensions)
|
||||
+ error (_("Wrong number of subscripts"));
|
||||
+
|
||||
+ gdb_assert (nargs > 0);
|
||||
+
|
||||
+ /* Now that we know we have a legal array subscript expression let us
|
||||
+ actually find out where this element exists in the array. */
|
||||
+
|
||||
+ /* Take array indices left to right. */
|
||||
+ for (int i = 0; i < nargs; i++)
|
||||
+ {
|
||||
+ /* Evaluate each subscript; it must be a legal integer in F77. */
|
||||
+ value *arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
+
|
||||
+ /* Fill in the subscript array. */
|
||||
+ subscript_array[i] = value_as_long (arg2);
|
||||
+ }
|
||||
+
|
||||
+ /* Internal type of array is arranged right to left. */
|
||||
+ for (int i = nargs; i > 0; i--)
|
||||
+ {
|
||||
+ struct type *array_type = check_typedef (value_type (array));
|
||||
+ LONGEST index = subscript_array[i - 1];
|
||||
+
|
||||
+ array = value_subscripted_rvalue (array, index,
|
||||
+ f77_get_lowerbound (array_type));
|
||||
+ }
|
||||
+
|
||||
+ return array;
|
||||
+}
|
||||
+
|
||||
/* Special expression evaluation cases for Fortran. */
|
||||
|
||||
static struct value *
|
||||
@@ -285,6 +413,87 @@ evaluate_subexp_f (struct type *expect_type, struct expression *exp,
|
||||
TYPE_LENGTH (type));
|
||||
return value_from_longest (builtin_type (exp->gdbarch)->builtin_int,
|
||||
TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
|
||||
+
|
||||
+
|
||||
+ case OP_F77_UNDETERMINED_ARGLIST:
|
||||
+ /* Remember that in F77, functions, substring ops and array subscript
|
||||
+ operations cannot be disambiguated at parse time. We have made
|
||||
+ all array subscript operations, substring operations as well as
|
||||
+ function calls come here and we now have to discover what the heck
|
||||
+ this thing actually was. If it is a function, we process just as
|
||||
+ if we got an OP_FUNCALL. */
|
||||
+ int nargs = longest_to_int (exp->elts[pc + 1].longconst);
|
||||
+ (*pos) += 2;
|
||||
+
|
||||
+ /* First determine the type code we are dealing with. */
|
||||
+ arg1 = evaluate_subexp (nullptr, exp, pos, noside);
|
||||
+ type = check_typedef (value_type (arg1));
|
||||
+ enum type_code code = type->code ();
|
||||
+
|
||||
+ if (code == TYPE_CODE_PTR)
|
||||
+ {
|
||||
+ /* Fortran always passes variable to subroutines as pointer.
|
||||
+ So we need to look into its target type to see if it is
|
||||
+ array, string or function. If it is, we need to switch
|
||||
+ to the target value the original one points to. */
|
||||
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
|
||||
+
|
||||
+ if (target_type->code () == TYPE_CODE_ARRAY
|
||||
+ || target_type->code () == TYPE_CODE_STRING
|
||||
+ || target_type->code () == TYPE_CODE_FUNC)
|
||||
+ {
|
||||
+ arg1 = value_ind (arg1);
|
||||
+ type = check_typedef (value_type (arg1));
|
||||
+ code = type->code ();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ switch (code)
|
||||
+ {
|
||||
+ case TYPE_CODE_ARRAY:
|
||||
+ case TYPE_CODE_STRING:
|
||||
+ return fortran_value_subarray (arg1, exp, pos, nargs, noside);
|
||||
+
|
||||
+ case TYPE_CODE_PTR:
|
||||
+ case TYPE_CODE_FUNC:
|
||||
+ case TYPE_CODE_INTERNAL_FUNCTION:
|
||||
+ {
|
||||
+ /* It's a function call. Allocate arg vector, including
|
||||
+ space for the function to be called in argvec[0] and a
|
||||
+ termination NULL. */
|
||||
+ struct value **argvec = (struct value **)
|
||||
+ alloca (sizeof (struct value *) * (nargs + 2));
|
||||
+ argvec[0] = arg1;
|
||||
+ int tem = 1;
|
||||
+ for (; tem <= nargs; tem++)
|
||||
+ {
|
||||
+ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
|
||||
+ /* Arguments in Fortran are passed by address. Coerce the
|
||||
+ arguments here rather than in value_arg_coerce as
|
||||
+ otherwise the call to malloc to place the non-lvalue
|
||||
+ parameters in target memory is hit by this Fortran
|
||||
+ specific logic. This results in malloc being called
|
||||
+ with a pointer to an integer followed by an attempt to
|
||||
+ malloc the arguments to malloc in target memory.
|
||||
+ Infinite recursion ensues. */
|
||||
+ if (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC)
|
||||
+ {
|
||||
+ bool is_artificial
|
||||
+ = TYPE_FIELD_ARTIFICIAL (value_type (arg1), tem - 1);
|
||||
+ argvec[tem] = fortran_argument_convert (argvec[tem],
|
||||
+ is_artificial);
|
||||
+ }
|
||||
+ }
|
||||
+ argvec[tem] = 0; /* signal end of arglist */
|
||||
+ if (noside == EVAL_SKIP)
|
||||
+ return eval_skip_value (exp);
|
||||
+ return evaluate_subexp_do_call (exp, noside, nargs, argvec, NULL,
|
||||
+ expect_type);
|
||||
+ }
|
||||
+
|
||||
+ default:
|
||||
+ error (_("Cannot perform substring on this type"));
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Should be unreachable. */
|
||||
@@ -318,6 +527,11 @@ operator_length_f (const struct expression *exp, int pc, int *oplenp,
|
||||
oplen = 1;
|
||||
args = 2;
|
||||
break;
|
||||
+
|
||||
+ case OP_F77_UNDETERMINED_ARGLIST:
|
||||
+ oplen = 3;
|
||||
+ args = 1 + longest_to_int (exp->elts[pc - 2].longconst);
|
||||
+ break;
|
||||
}
|
||||
|
||||
*oplenp = oplen;
|
||||
@@ -390,6 +604,10 @@ print_subexp_f (struct expression *exp, int *pos,
|
||||
case BINOP_FORTRAN_MODULO:
|
||||
print_binop_subexp_f (exp, pos, stream, prec, "MODULO");
|
||||
return;
|
||||
+
|
||||
+ case OP_F77_UNDETERMINED_ARGLIST:
|
||||
+ print_subexp_funcall (exp, pos, stream);
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,6 +650,9 @@ dump_subexp_body_f (struct expression *exp,
|
||||
case BINOP_FORTRAN_MODULO:
|
||||
operator_length_f (exp, (elt + 1), &oplen, &nargs);
|
||||
break;
|
||||
+
|
||||
+ case OP_F77_UNDETERMINED_ARGLIST:
|
||||
+ return dump_subexp_body_funcall (exp, stream, elt);
|
||||
}
|
||||
|
||||
elt += oplen;
|
||||
diff --git a/gdb/fortran-operator.def b/gdb/fortran-operator.def
|
||||
--- a/gdb/fortran-operator.def
|
||||
+++ b/gdb/fortran-operator.def
|
||||
@@ -17,6 +17,14 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
+/* This is EXACTLY like OP_FUNCALL but is semantically different.
|
||||
+ In F77, array subscript expressions, substring expressions and
|
||||
+ function calls are all exactly the same syntactically. They
|
||||
+ may only be disambiguated at runtime. Thus this operator,
|
||||
+ which indicates that we have found something of the form
|
||||
+ <name> ( <stuff> ). */
|
||||
+OP (OP_F77_UNDETERMINED_ARGLIST)
|
||||
+
|
||||
/* Single operand builtins. */
|
||||
OP (UNOP_FORTRAN_KIND)
|
||||
OP (UNOP_FORTRAN_FLOOR)
|
||||
diff --git a/gdb/parse.c b/gdb/parse.c
|
||||
--- a/gdb/parse.c
|
||||
+++ b/gdb/parse.c
|
||||
@@ -817,7 +817,6 @@ operator_length_standard (const struct expression *expr, int endpos,
|
||||
break;
|
||||
|
||||
case OP_FUNCALL:
|
||||
- case OP_F77_UNDETERMINED_ARGLIST:
|
||||
oplen = 3;
|
||||
args = 1 + longest_to_int (expr->elts[endpos - 2].longconst);
|
||||
break;
|
||||
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
|
||||
--- a/gdb/parser-defs.h
|
||||
+++ b/gdb/parser-defs.h
|
||||
@@ -338,6 +338,13 @@ extern int dump_subexp (struct expression *, struct ui_file *, int);
|
||||
extern int dump_subexp_body_standard (struct expression *,
|
||||
struct ui_file *, int);
|
||||
|
||||
+/* Dump (to STREAM) a function call like expression at position ELT in the
|
||||
+ expression array EXP. Return a new value for ELT just after the
|
||||
+ function call expression. */
|
||||
+
|
||||
+extern int dump_subexp_body_funcall (struct expression *exp,
|
||||
+ struct ui_file *stream, int elt);
|
||||
+
|
||||
extern void operator_length (const struct expression *, int, int *, int *);
|
||||
|
||||
extern void operator_length_standard (const struct expression *, int, int *,
|
||||
@@ -440,6 +447,15 @@ extern void print_subexp (struct expression *, int *, struct ui_file *,
|
||||
extern void print_subexp_standard (struct expression *, int *,
|
||||
struct ui_file *, enum precedence);
|
||||
|
||||
+/* Print a function call like expression to STREAM. This is called as a
|
||||
+ helper function by which point the expression node identifying this as a
|
||||
+ function call has already been stripped off and POS should point to the
|
||||
+ number of function call arguments. EXP is the object containing the
|
||||
+ list of expression elements. */
|
||||
+
|
||||
+extern void print_subexp_funcall (struct expression *exp, int *pos,
|
||||
+ struct ui_file *stream);
|
||||
+
|
||||
/* Function used to avoid direct calls to fprintf
|
||||
in the code generated by the bison parser. */
|
||||
|
||||
diff --git a/gdb/std-operator.def b/gdb/std-operator.def
|
||||
--- a/gdb/std-operator.def
|
||||
+++ b/gdb/std-operator.def
|
||||
@@ -168,14 +168,6 @@ OP (OP_FUNCALL)
|
||||
pointer. This is an Objective C message. */
|
||||
OP (OP_OBJC_MSGCALL)
|
||||
|
||||
-/* This is EXACTLY like OP_FUNCALL but is semantically different.
|
||||
- In F77, array subscript expressions, substring expressions and
|
||||
- function calls are all exactly the same syntactically. They
|
||||
- may only be disambiguated at runtime. Thus this operator,
|
||||
- which indicates that we have found something of the form
|
||||
- <name> ( <stuff> ). */
|
||||
-OP (OP_F77_UNDETERMINED_ARGLIST)
|
||||
-
|
||||
/* OP_COMPLEX takes a type in the following element, followed by another
|
||||
OP_COMPLEX, making three exp_elements. It is followed by two double
|
||||
args, and converts them into a complex number of the given type. */
|
|
@ -0,0 +1,51 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Bruno Larsen <blarsen@redhat.com>
|
||||
Date: Thu, 23 Sep 2021 11:19:09 -0300
|
||||
Subject: gdb-rhbz1970741-early-exit-for-empty-debuginfod-url.patch
|
||||
|
||||
;;[gdb] Improve early exits for env var in debuginfod-support.c
|
||||
;;(Tom de Vries)
|
||||
|
||||
There's an early exit in libdebuginfod's debuginfod_query_server, which checks
|
||||
both for:
|
||||
- getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL, and
|
||||
- (getenv (DEBUGINFOD_URLS_ENV_VAR))[0] == '\0'.
|
||||
|
||||
In debuginfod_source_query and debuginfod_debuginfo_query (which both
|
||||
end up calling debuginfod_query_server) there are also early exits checking
|
||||
the same env var, but those just check for NULL.
|
||||
|
||||
Make the early exit tests in debuginfod-support.c match those in
|
||||
libdebuginfod.
|
||||
|
||||
gdb/ChangeLog:
|
||||
|
||||
2020-11-18 Tom de Vries <tdevries@suse.de>
|
||||
|
||||
* debuginfod-support.c (debuginfod_source_query)
|
||||
(debuginfod_debuginfo_query): Also do early exit if
|
||||
"(getenv (DEBUGINFOD_URLS_ENV_VAR))[0] == '\0'".
|
||||
|
||||
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
|
||||
--- a/gdb/debuginfod-support.c
|
||||
+++ b/gdb/debuginfod-support.c
|
||||
@@ -98,7 +98,8 @@ debuginfod_source_query (const unsigned char *build_id,
|
||||
const char *srcpath,
|
||||
gdb::unique_xmalloc_ptr<char> *destname)
|
||||
{
|
||||
- if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL)
|
||||
+ const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
|
||||
+ if (urls_env_var == NULL || urls_env_var[0] == '\0')
|
||||
return scoped_fd (-ENOSYS);
|
||||
|
||||
debuginfod_client *c = debuginfod_init ();
|
||||
@@ -135,7 +136,8 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
|
||||
const char *filename,
|
||||
gdb::unique_xmalloc_ptr<char> *destname)
|
||||
{
|
||||
- if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL)
|
||||
+ const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
|
||||
+ if (urls_env_var == NULL || urls_env_var[0] == '\0')
|
||||
return scoped_fd (-ENOSYS);
|
||||
|
||||
debuginfod_client *c = debuginfod_init ();
|
|
@ -0,0 +1,30 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
|
||||
Date: Sun, 26 Sep 2021 23:39:22 +0200
|
||||
Subject: gdb-rhbz1976887-field-location-kind.patch
|
||||
|
||||
;;Backport upstream patch which fixes internal-error: Unexpected
|
||||
;; type field location kind (RHBZ 1976887).
|
||||
|
||||
gdbtypes.c: Add the case for FIELD_LOC_KIND_DWARF_BLOCK
|
||||
|
||||
The case for FIELD_LOC_KIND_DWARF_BLOCK was missing for
|
||||
switch TYPE_FIELD_LOC_KIND. Thas caused an internal-error
|
||||
under some circumstances.
|
||||
|
||||
Fixes bug 28030.
|
||||
|
||||
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
|
||||
--- a/gdb/gdbtypes.c
|
||||
+++ b/gdb/gdbtypes.c
|
||||
@@ -5434,6 +5434,10 @@ copy_type_recursive (struct objfile *objfile,
|
||||
xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type,
|
||||
i)));
|
||||
break;
|
||||
+ case FIELD_LOC_KIND_DWARF_BLOCK:
|
||||
+ SET_FIELD_DWARF_BLOCK (new_type->field (i),
|
||||
+ TYPE_FIELD_DWARF_BLOCK (type, i));
|
||||
+ break;
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("Unexpected type field location kind: %d"),
|
|
@ -25,7 +25,7 @@ a problem with make -j parallelization of the testsuite.
|
|||
diff --git a/gdb/testsuite/lib/future.exp b/gdb/testsuite/lib/future.exp
|
||||
--- a/gdb/testsuite/lib/future.exp
|
||||
+++ b/gdb/testsuite/lib/future.exp
|
||||
@@ -195,6 +195,10 @@ proc gdb_default_target_compile {source destfile type options} {
|
||||
@@ -197,6 +197,10 @@ proc gdb_default_target_compile_1 {source destfile type options} {
|
||||
set ldflags ""
|
||||
set dest [target_info name]
|
||||
|
||||
|
@ -36,7 +36,7 @@ diff --git a/gdb/testsuite/lib/future.exp b/gdb/testsuite/lib/future.exp
|
|||
if {[info exists CFLAGS_FOR_TARGET]} {
|
||||
append add_flags " $CFLAGS_FOR_TARGET"
|
||||
}
|
||||
@@ -529,10 +533,6 @@ proc gdb_default_target_compile {source destfile type options} {
|
||||
@@ -531,10 +535,6 @@ proc gdb_default_target_compile_1 {source destfile type options} {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,591 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
|
||||
Date: Sun, 26 Sep 2021 23:52:21 +0200
|
||||
Subject: gdb-test-for-rhbz1976887.patch
|
||||
|
||||
; Backport test for RHBZ 1976887 (Kevin Buettner).
|
||||
Test case reproducing PR28030 bug
|
||||
|
||||
The original reproducer for PR28030 required use of a specific
|
||||
compiler version - gcc-c++-11.1.1-3.fc34 is mentioned in the PR,
|
||||
though it seems probable that other gcc versions might also be able to
|
||||
reproduce the bug as well. This commit introduces a test case which,
|
||||
using the DWARF assembler, provides a reproducer which is independent
|
||||
of the compiler version. (Well, it'll work with whatever compilers
|
||||
the DWARF assembler works with.)
|
||||
|
||||
To the best of my knowledge, it's also the first test case which uses
|
||||
the DWARF assembler to provide debug info for a shared object. That
|
||||
being the case, I provided more than the usual commentary which should
|
||||
allow this case to be used as a template when a combo shared
|
||||
library / DWARF assembler test case is required in the future.
|
||||
|
||||
I provide some details regarding the bug in a comment near the
|
||||
beginning of locexpr-dml.exp.
|
||||
|
||||
This problem was difficult to reproduce; I found myself constantly
|
||||
referring to the backtrace while trying to figure out what (else) I
|
||||
might be missing while trying to create a reproducer. Below is a
|
||||
partial backtrace which I include for posterity.
|
||||
|
||||
#0 internal_error (
|
||||
file=0xc50110 "/ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c", line=5575,
|
||||
fmt=0xc520c0 "Unexpected type field location kind: %d")
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdbsupport/errors.cc:51
|
||||
#1 0x00000000006ef0c5 in copy_type_recursive (objfile=0x1635930,
|
||||
type=0x274c260, copied_types=0x30bb290)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c:5575
|
||||
#2 0x00000000006ef382 in copy_type_recursive (objfile=0x1635930,
|
||||
type=0x274ca10, copied_types=0x30bb290)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/gdbtypes.c:5602
|
||||
#3 0x0000000000a7409a in preserve_one_value (value=0x24269f0,
|
||||
objfile=0x1635930, copied_types=0x30bb290)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/value.c:2529
|
||||
#4 0x000000000072012a in gdbscm_preserve_values (
|
||||
extlang=0xc55720 <extension_language_guile>, objfile=0x1635930,
|
||||
copied_types=0x30bb290)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/guile/scm-value.c:94
|
||||
#5 0x00000000006a3f82 in preserve_ext_lang_values (objfile=0x1635930,
|
||||
copied_types=0x30bb290)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/extension.c:568
|
||||
#6 0x0000000000a7428d in preserve_values (objfile=0x1635930)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/value.c:2579
|
||||
#7 0x000000000082d514 in objfile::~objfile (this=0x1635930,
|
||||
__in_chrg=<optimized out>)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:549
|
||||
#8 0x0000000000831cc8 in std::_Sp_counted_ptr<objfile*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x1654580)
|
||||
at /usr/include/c++/11/bits/shared_ptr_base.h:348
|
||||
#9 0x00000000004e6617 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x1654580) at /usr/include/c++/11/bits/shared_ptr_base.h:168
|
||||
#10 0x00000000004e1d2f in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x190bb88, __in_chrg=<optimized out>)
|
||||
at /usr/include/c++/11/bits/shared_ptr_base.h:705
|
||||
#11 0x000000000082feee in std::__shared_ptr<objfile, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x190bb80, __in_chrg=<optimized out>)
|
||||
at /usr/include/c++/11/bits/shared_ptr_base.h:1154
|
||||
#12 0x000000000082ff0a in std::shared_ptr<objfile>::~shared_ptr (
|
||||
this=0x190bb80, __in_chrg=<optimized out>)
|
||||
at /usr/include/c++/11/bits/shared_ptr.h:122
|
||||
#13 0x000000000085ed7e in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<objfile> > >::destroy<std::shared_ptr<objfile> > (this=0x114bc00,
|
||||
__p=0x190bb80) at /usr/include/c++/11/ext/new_allocator.h:168
|
||||
#14 0x000000000085e88d in std::allocator_traits<std::allocator<std::_List_node<std::shared_ptr<objfile> > > >::destroy<std::shared_ptr<objfile> > (__a=...,
|
||||
__p=0x190bb80) at /usr/include/c++/11/bits/alloc_traits.h:531
|
||||
#15 0x000000000085e50c in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::_M_erase (this=0x114bc00, __position=
|
||||
std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x1635930})
|
||||
at /usr/include/c++/11/bits/stl_list.h:1925
|
||||
#16 0x000000000085df0e in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::erase (this=0x114bc00, __position=
|
||||
std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x1635930})
|
||||
at /usr/include/c++/11/bits/list.tcc:158
|
||||
#17 0x000000000085c748 in program_space::remove_objfile (this=0x114bbc0,
|
||||
objfile=0x1635930)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/progspace.c:210
|
||||
#18 0x000000000082d3ae in objfile::unlink (this=0x1635930)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:487
|
||||
#19 0x000000000082e68c in objfile_purge_solibs ()
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/objfiles.c:875
|
||||
#20 0x000000000092dd37 in no_shared_libraries (ignored=0x0, from_tty=1)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/solib.c:1236
|
||||
#21 0x00000000009a37fe in target_pre_inferior (from_tty=1)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/target.c:2496
|
||||
#22 0x00000000007454d6 in run_command_1 (args=0x0, from_tty=1,
|
||||
run_how=RUN_NORMAL)
|
||||
at /ironwood1/sourceware-git/f34-pr28030/bld/../../worktree-pr28030/gdb/infcmd.c:437
|
||||
|
||||
I'll note a few points regarding this backtrace:
|
||||
|
||||
Frame #1 is where the internal error occurs. It's caused by an
|
||||
unhandled case for FIELD_LOC_KIND_DWARF_BLOCK. The fix for this bug
|
||||
adds support for this case.
|
||||
|
||||
Frame #22 - it's a partial backtrace - shows that GDB is attempting to
|
||||
(re)run the program. You can see the exact command sequence that was
|
||||
used for reproducing this problem in the PR (at
|
||||
https://sourceware.org/bugzilla/show_bug.cgi?id=28030), but in a
|
||||
nutshell, after starting the program and advancing to the appropriate
|
||||
source line, GDB was asked to step into libstdc++; a "finish" command
|
||||
was issued, returning a value. The fact that a value was returned is
|
||||
very important. GDB was then used to step back into libstdc++. A
|
||||
breakpoint was set on a source line in the library after which a "run"
|
||||
command was issued.
|
||||
|
||||
Frame #19 shows a call to objfile_purge_solibs. It's aptly named.
|
||||
|
||||
Frame #7 is a call to the destructor for one of the objfile solibs; it
|
||||
turned out to be the one for libstdc++.
|
||||
|
||||
Frames #6 thru #3 show various value preservation frames. If you look
|
||||
at preserve_values() in gdb/value.c, the value history is preserved
|
||||
first, followed by internal variables, followed by values for the
|
||||
extension languages (python and guile).
|
||||
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-lib.c b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-lib.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-lib.c
|
||||
@@ -0,0 +1,48 @@
|
||||
+/* Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is part of GDB.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "locexpr-data-member-location.h"
|
||||
+
|
||||
+struct A g_A = {3, 4};
|
||||
+struct B g_B = { {8, 9}, 10, 11 };
|
||||
+
|
||||
+B *
|
||||
+foo ()
|
||||
+{ /* foo prologue */
|
||||
+ asm ("foo_label: .globl foo_label");
|
||||
+ return &g_B; /* foo return */
|
||||
+} /* foo end */
|
||||
+
|
||||
+B *
|
||||
+bar (B *v)
|
||||
+{ /* bar prologue */
|
||||
+ asm ("bar_label: .globl bar_label");
|
||||
+ return v; /* bar return */
|
||||
+} /* bar end */
|
||||
+
|
||||
+/* Some of the DWARF assembler procs (e.g. function_range) compile
|
||||
+ this file, expecting it to be a complete program with a main()
|
||||
+ function. When IS_SHAREDLIB is NOT defined, we have main() as
|
||||
+ defined below. */
|
||||
+
|
||||
+#ifndef IS_SHAREDLIB
|
||||
+int
|
||||
+main ()
|
||||
+{
|
||||
+ B *b = foo ();
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-main.c b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-main.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location-main.c
|
||||
@@ -0,0 +1,27 @@
|
||||
+/* Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is part of GDB.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include "locexpr-data-member-location.h"
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ B *v1;
|
||||
+ v1 = bar (foo ());
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.exp
|
||||
@@ -0,0 +1,349 @@
|
||||
+# Copyright 2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+# This test case uses the DWARF assembler to reproduce the problem
|
||||
+# described by PR28030. The bug turned out to be that
|
||||
+# FIELD_LOC_KIND_DWARF_BLOCK was not handled when recursively copying
|
||||
+# a value's type when preserving the value history during the freeing
|
||||
+# up of objfiles associated with a shared object. (Yes, figuring out
|
||||
+# how to make this happen in a concise test case turned out to be
|
||||
+# challenging.)
|
||||
+#
|
||||
+# The following elements proved to be necessary for reproducing the
|
||||
+# problem:
|
||||
+#
|
||||
+# 1) A location expression needed to be used with
|
||||
+# DW_AT_data_member_location rather than a simple offset.
|
||||
+# Moreover, this location expression needed to use opcodes
|
||||
+# which GDB's DWARF reader could not convert to a simple
|
||||
+# offset. (Note, however, that GDB could probably be improved
|
||||
+# to handle the opcodes chosen for this test; if decode_locdesc()
|
||||
+# in dwarf2/read.c is ever updated to handle both DW_OP_pick and
|
||||
+# DW_OP_drop, then this test could end up passing even if
|
||||
+# the bug it's intended to test has not been fixed.)
|
||||
+#
|
||||
+# 2) The debug info containing the above DWARF info needed
|
||||
+# to be associated with a shared object since the problem
|
||||
+# occurred while GDB was preserving values during the
|
||||
+# purging of shared objects.
|
||||
+#
|
||||
+# 3) After performing some simple gdb commands, the program is
|
||||
+# run again. In the course of running the objfile destructor
|
||||
+# associated with the shared object, values are preserved
|
||||
+# along with their types. As noted earlier, it was during
|
||||
+# the recursive type copy that the bug was observed.
|
||||
+#
|
||||
+# Therefore, due to #2 above, this test case creates debug info
|
||||
+# which is then used by a shared object.
|
||||
+
|
||||
+# This test can't be run on targets lacking shared library support.
|
||||
+if [skip_shlib_tests] {
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+load_lib dwarf.exp
|
||||
+
|
||||
+# This test can only be run on targets which support DWARF-2 and use gas.
|
||||
+if ![dwarf2_support] {
|
||||
+ return 0
|
||||
+}
|
||||
+
|
||||
+# gdb_test_file_name is the name of this file without the .exp
|
||||
+# extension. Use it to form basenames for the main program
|
||||
+# and shared object.
|
||||
+set main_basename ${::gdb_test_file_name}-main
|
||||
+set lib_basename ${::gdb_test_file_name}-lib
|
||||
+
|
||||
+# We're generating DWARF assembly for the shared object; therefore,
|
||||
+# the source file for the library / shared object must be listed first
|
||||
+# (in the standard_testfile invocation) since ${srcfile} is used by
|
||||
+# get_func_info (for determining the start, end, and length of a
|
||||
+# function).
|
||||
+#
|
||||
+# The output of Dwarf::assemble will be placed in $lib_basename.S
|
||||
+# which will be ${srcfile3} after the execution of standard_testfile.
|
||||
+
|
||||
+standard_testfile $lib_basename.c $main_basename.c $lib_basename.S
|
||||
+
|
||||
+set libsrc "${::srcdir}/${::subdir}/${::srcfile}"
|
||||
+set lib_so [standard_output_file ${lib_basename}.so]
|
||||
+set asm_file [standard_output_file ${::srcfile3}]
|
||||
+
|
||||
+# We need to know the size of some types in order to write some of the
|
||||
+# debugging info that we're about to generate. For that, we ask GDB
|
||||
+# by debugging the shared object associated with this test case.
|
||||
+
|
||||
+# Compile the shared library: -DIS_SHAREDLIB prevents main() from
|
||||
+# being defined. Note that debugging symbols will be present for
|
||||
+# this compilation.
|
||||
+if {[gdb_compile_shlib $libsrc $lib_so \
|
||||
+ {additional_flags=-DIS_SHAREDLIB debug}] != ""} {
|
||||
+ untested "failed to compile shared library"
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
+# Start a fresh GDB and load the shared library.
|
||||
+clean_restart $lib_so
|
||||
+
|
||||
+# Using our running GDB session, determine sizes of several types.
|
||||
+set long_size [get_sizeof "long" -1]
|
||||
+set addr_size [get_sizeof "void *" -1]
|
||||
+set struct_A_size [get_sizeof "g_A" -1]
|
||||
+set struct_B_size [get_sizeof "g_B" -1]
|
||||
+
|
||||
+if { $long_size == -1 || $addr_size == -1 \
|
||||
+ || $struct_A_size == -1 || $struct_B_size == -1} {
|
||||
+ perror "Can't determine type sizes"
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
+# Retrieve struct offset of MBR in struct TP
|
||||
+proc get_offsetof { tp mbr } {
|
||||
+ return [get_integer_valueof "&((${tp} *) 0)->${mbr}" -1]
|
||||
+}
|
||||
+
|
||||
+# Use running GDB session to get struct offsets
|
||||
+set A_a [get_offsetof A a]
|
||||
+set A_x [get_offsetof A x]
|
||||
+set B_a [get_offsetof B a]
|
||||
+set B_b [get_offsetof B b]
|
||||
+set B_x2 [get_offsetof B x2]
|
||||
+
|
||||
+# Create the DWARF.
|
||||
+Dwarf::assemble ${asm_file} {
|
||||
+ declare_labels L
|
||||
+
|
||||
+ # Find start, end, and length of functions foo and bar.
|
||||
+ # These calls to get_func_info will create and set variables
|
||||
+ # foo_start, bar_start, foo_end, bar_end, foo_len, and
|
||||
+ # bar_len.
|
||||
+ #
|
||||
+ # In order to get the right answers, get_func_info (and,
|
||||
+ # underneath, function_range) should use the same compiler flags
|
||||
+ # as those used to make a shared object. For any targets that get
|
||||
+ # this far, -fpic is probably correct.
|
||||
+ #
|
||||
+ # Also, it should be noted that IS_SHAREDLIB is NOT defined as one
|
||||
+ # of the additional flags. Not defining IS_SHAREDLIB will cause a
|
||||
+ # main() to be defined for the compilation of the shared library
|
||||
+ # source file which happens as a result of using get_func_info;
|
||||
+ # this is currently required in order to this facility.
|
||||
+ set flags {additional_flags=-fpic debug}
|
||||
+ get_func_info foo $flags
|
||||
+ get_func_info bar $flags
|
||||
+
|
||||
+ cu {} {
|
||||
+ DW_TAG_compile_unit {
|
||||
+ {DW_AT_language @DW_LANG_C_plus_plus}
|
||||
+ {name ${::srcfile}}
|
||||
+ {stmt_list $L DW_FORM_sec_offset}
|
||||
+ } {
|
||||
+ declare_labels int_label class_A_label class_B_label \
|
||||
+ B_ptr_label
|
||||
+
|
||||
+ int_label: DW_TAG_base_type {
|
||||
+ {DW_AT_byte_size ${::long_size} DW_FORM_udata}
|
||||
+ {DW_AT_encoding @DW_ATE_signed}
|
||||
+ {DW_AT_name "int"}
|
||||
+ }
|
||||
+
|
||||
+ class_A_label: DW_TAG_class_type {
|
||||
+ {DW_AT_name "A"}
|
||||
+ {DW_AT_byte_size ${::struct_A_size} DW_FORM_sdata}
|
||||
+ } {
|
||||
+ DW_TAG_member {
|
||||
+ {DW_AT_name "a"}
|
||||
+ {DW_AT_type :$int_label}
|
||||
+ {DW_AT_data_member_location ${::A_a} DW_FORM_udata}
|
||||
+ }
|
||||
+ DW_TAG_member {
|
||||
+ {DW_AT_name "x"}
|
||||
+ {DW_AT_type :$int_label}
|
||||
+ {DW_AT_data_member_location ${::A_x} DW_FORM_udata}
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ class_B_label: DW_TAG_class_type {
|
||||
+ {DW_AT_name "B"}
|
||||
+ {DW_AT_byte_size ${::struct_B_size} DW_FORM_sdata}
|
||||
+ } {
|
||||
+ # While there are easier / better ways to specify an
|
||||
+ # offset used by DW_AT_data_member_location than that
|
||||
+ # used below, we need a location expression here in
|
||||
+ # order to reproduce the bug. Moreover, this location
|
||||
+ # expression needs to use opcodes that aren't handled
|
||||
+ # by decode_locdesc() in dwarf2/read.c; if we use
|
||||
+ # opcodes that _are_ handled by that function, the
|
||||
+ # location expression will be converted into a simple
|
||||
+ # offset - which will then (again) not reproduce the
|
||||
+ # bug. At the time that this test was written,
|
||||
+ # neither DW_OP_pick nor DW_OP_drop were being handled
|
||||
+ # by decode_locdesc(); this is why those opcodes were
|
||||
+ # chosen.
|
||||
+ DW_TAG_inheritance {
|
||||
+ {DW_AT_type :$class_A_label}
|
||||
+ {DW_AT_data_member_location {
|
||||
+ DW_OP_constu ${::B_a}
|
||||
+ DW_OP_plus
|
||||
+ DW_OP_pick 0
|
||||
+ DW_OP_drop} SPECIAL_expr}
|
||||
+ {DW_AT_accessibility 1 DW_FORM_data1}
|
||||
+ }
|
||||
+ DW_TAG_member {
|
||||
+ {DW_AT_name "b"}
|
||||
+ {DW_AT_type :$int_label}
|
||||
+ {DW_AT_data_member_location ${::B_b} DW_FORM_udata}
|
||||
+ }
|
||||
+ DW_TAG_member {
|
||||
+ {DW_AT_name "x2"}
|
||||
+ {DW_AT_type :$int_label}
|
||||
+ {DW_AT_data_member_location ${::B_x2} DW_FORM_udata}
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ B_ptr_label: DW_TAG_pointer_type {
|
||||
+ {DW_AT_type :$class_B_label}
|
||||
+ {DW_AT_byte_size ${::addr_size} DW_FORM_sdata}
|
||||
+ }
|
||||
+
|
||||
+ DW_TAG_variable {
|
||||
+ {DW_AT_name "g_A"}
|
||||
+ {DW_AT_type :$class_A_label}
|
||||
+ {DW_AT_external 1 flag}
|
||||
+ {DW_AT_location {DW_OP_addr [gdb_target_symbol "g_A"]} \
|
||||
+ SPECIAL_expr}
|
||||
+ }
|
||||
+
|
||||
+ DW_TAG_variable {
|
||||
+ {DW_AT_name "g_B"}
|
||||
+ {DW_AT_type :$class_B_label}
|
||||
+ {DW_AT_external 1 flag}
|
||||
+ {DW_AT_location {DW_OP_addr [gdb_target_symbol "g_B"]} \
|
||||
+ SPECIAL_expr}
|
||||
+ }
|
||||
+
|
||||
+ # We can't use MACRO_AT for the definitions of foo and bar
|
||||
+ # because it doesn't provide a way to pass the appropriate
|
||||
+ # flags. Therefore, we list the name, low_pc, and high_pc
|
||||
+ # explicitly.
|
||||
+ DW_TAG_subprogram {
|
||||
+ {DW_AT_name foo}
|
||||
+ {DW_AT_low_pc $foo_start DW_FORM_addr}
|
||||
+ {DW_AT_high_pc $foo_end DW_FORM_addr}
|
||||
+ {DW_AT_type :${B_ptr_label}}
|
||||
+ {DW_AT_external 1 flag}
|
||||
+ }
|
||||
+
|
||||
+ DW_TAG_subprogram {
|
||||
+ {DW_AT_name bar}
|
||||
+ {DW_AT_low_pc $bar_start DW_FORM_addr}
|
||||
+ {DW_AT_high_pc $bar_end DW_FORM_addr}
|
||||
+ {DW_AT_type :${B_ptr_label}}
|
||||
+ {DW_AT_external 1 flag}
|
||||
+ } {
|
||||
+ DW_TAG_formal_parameter {
|
||||
+ {DW_AT_name v}
|
||||
+ {DW_AT_type :${B_ptr_label}}
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ lines {version 2} L {
|
||||
+ include_dir "${::srcdir}/${::subdir}"
|
||||
+ file_name "${::srcfile}" 1
|
||||
+
|
||||
+ # Generate a line table program.
|
||||
+ program {
|
||||
+ {DW_LNE_set_address $foo_start}
|
||||
+ {line [gdb_get_line_number "foo prologue"]}
|
||||
+ {DW_LNS_copy}
|
||||
+ {DW_LNE_set_address foo_label}
|
||||
+ {line [gdb_get_line_number "foo return"]}
|
||||
+ {DW_LNS_copy}
|
||||
+ {line [gdb_get_line_number "foo end"]}
|
||||
+ {DW_LNS_copy}
|
||||
+ {DW_LNE_set_address $foo_end}
|
||||
+ {DW_LNS_advance_line 1}
|
||||
+ {DW_LNS_copy}
|
||||
+ {DW_LNE_end_sequence}
|
||||
+
|
||||
+ {DW_LNE_set_address $bar_start}
|
||||
+ {line [gdb_get_line_number "bar prologue"]}
|
||||
+ {DW_LNS_copy}
|
||||
+ {DW_LNE_set_address bar_label}
|
||||
+ {line [gdb_get_line_number "bar return"]}
|
||||
+ {DW_LNS_copy}
|
||||
+ {line [gdb_get_line_number "bar end"]}
|
||||
+ {DW_LNS_copy}
|
||||
+ {DW_LNE_set_address $bar_end}
|
||||
+ {DW_LNS_advance_line 1}
|
||||
+ {DW_LNS_copy}
|
||||
+ {DW_LNE_end_sequence}
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+# Compile the shared object again, but this time include / use the
|
||||
+# DWARF info that we've created above. Note that (again)
|
||||
+# -DIS_SHAREDLIB is used to prevent inclusion of main() in the shared
|
||||
+# object. Also note the use of the "nodebug" option. Any debugging
|
||||
+# information that we need will be provided by the DWARF info created
|
||||
+# above.
|
||||
+if {[gdb_compile_shlib [list $libsrc $asm_file] $lib_so \
|
||||
+ {additional_flags=-DIS_SHAREDLIB nodebug}] != ""} {
|
||||
+ untested "failed to compile shared library"
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
+# Compile the main program for use with the shared object.
|
||||
+if [prepare_for_testing "failed to prepare" ${testfile} \
|
||||
+ ${::srcfile2} [list debug shlib=$lib_so]] {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+# Do whatever is necessary to make sure that the shared library is
|
||||
+# loaded for remote targets.
|
||||
+gdb_load_shlib ${lib_so}
|
||||
+
|
||||
+if ![runto_main] then {
|
||||
+ fail "can't run to main"
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
+# Step into foo so that we can finish out of it.
|
||||
+gdb_test "step" "foo .. at .* foo end.*" "step into foo"
|
||||
+
|
||||
+# Finishing out of foo will create a value that will later need to
|
||||
+# be preserved when restarting the program.
|
||||
+gdb_test "finish" "= \\(class B \\*\\) ${::hex} .*" "finish out of foo"
|
||||
+
|
||||
+# Dereferencing and printing the return value isn't necessary
|
||||
+# for reproducing the bug, but we should make sure that the
|
||||
+# return value is what we expect it to be.
|
||||
+gdb_test "p *$" { = {<A> = {a = 8, x = 9}, b = 10, x2 = 11}} \
|
||||
+ "dereference return value"
|
||||
+
|
||||
+# The original PR28030 reproducer stepped back into the shared object,
|
||||
+# so we'll do the same here:
|
||||
+gdb_test "step" "bar \\(.*" "step into bar"
|
||||
+
|
||||
+# We don't want a clean restart here since that will be too clean.
|
||||
+# The original reproducer for PR28030 set a breakpoint in the shared
|
||||
+# library and then restarted via "run". The command below does roughly
|
||||
+# the same thing. It's at this step that an internal error would
|
||||
+# occur for PR28030. The "message" argument tells runto to turn on
|
||||
+# the printing of PASSes while runto is doing its job.
|
||||
+runto "bar" message
|
||||
diff --git a/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.h b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.h
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.dwarf2/locexpr-data-member-location.h
|
||||
@@ -0,0 +1,30 @@
|
||||
+/* Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This file is part of GDB.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published by
|
||||
+ the Free Software Foundation; either version 3 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful,
|
||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ GNU General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+typedef struct A {
|
||||
+ long a;
|
||||
+ long x;
|
||||
+} A;
|
||||
+
|
||||
+typedef struct B {
|
||||
+ A a;
|
||||
+ long b;
|
||||
+ long x2;
|
||||
+} B;
|
||||
+
|
||||
+extern B *foo ();
|
||||
+extern B *bar (B *v);
|
|
@ -1,61 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Sergio Durigan Junior <sergiodj@redhat.com>
|
||||
Date: Thu, 7 Dec 2017 16:20:31 -0500
|
||||
Subject: gdb-vla-intel-fix-print-char-array.patch
|
||||
|
||||
;; Revert upstream commit 469412dd9ccc4de5874fd3299b105833f36b34cd
|
||||
|
||||
Revert commit (only the part touching gdb/f-valprint.c):
|
||||
|
||||
commit 469412dd9ccc4de5874fd3299b105833f36b34cd
|
||||
Author: Christoph Weinmann <christoph.t.weinmann@intel.com>
|
||||
Date: Fri Sep 8 15:11:47 2017 +0200
|
||||
|
||||
Remove C/C++ relevant code in Fortran specific file.
|
||||
|
||||
Remove code relevant for printing C/C++ Integer values in a
|
||||
Fortran specific file to unify printing of Fortran values.
|
||||
This does not change the output.
|
||||
|
||||
And adjust its testcase.
|
||||
|
||||
diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c
|
||||
--- a/gdb/f-valprint.c
|
||||
+++ b/gdb/f-valprint.c
|
||||
@@ -319,8 +319,22 @@ f_val_print (struct type *type, int embedded_offset,
|
||||
original_value, &opts, 0, stream);
|
||||
}
|
||||
else
|
||||
- val_print_scalar_formatted (type, embedded_offset,
|
||||
- original_value, options, 0, stream);
|
||||
+ {
|
||||
+ val_print_scalar_formatted (type, embedded_offset,
|
||||
+ original_value, options, 0, stream);
|
||||
+ /* C and C++ has no single byte int type, char is used instead.
|
||||
+ Since we don't know whether the value is really intended to
|
||||
+ be used as an integer or a character, print the character
|
||||
+ equivalent as well. */
|
||||
+ if (TYPE_LENGTH (type) == 1)
|
||||
+ {
|
||||
+ LONGEST c;
|
||||
+
|
||||
+ fputs_filtered (" ", stream);
|
||||
+ c = unpack_long (type, valaddr + embedded_offset);
|
||||
+ LA_PRINT_CHAR ((unsigned char) c, type, stream);
|
||||
+ }
|
||||
+ }
|
||||
break;
|
||||
|
||||
case TYPE_CODE_STRUCT:
|
||||
diff --git a/gdb/testsuite/gdb.fortran/printing-types.exp b/gdb/testsuite/gdb.fortran/printing-types.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/printing-types.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/printing-types.exp
|
||||
@@ -29,7 +29,7 @@ if {![runto MAIN__]} then {
|
||||
gdb_breakpoint [gdb_get_line_number "write"]
|
||||
gdb_continue_to_breakpoint "write"
|
||||
|
||||
-gdb_test "print oneByte" " = 1"
|
||||
+gdb_test "print oneByte" " = 1 \'\\\\001\'"
|
||||
gdb_test "print twobytes" " = 2"
|
||||
gdb_test "print chvalue" " = \'a\'"
|
||||
gdb_test "print logvalue" " = \.TRUE\."
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,167 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
Date: Fri, 1 Aug 2014 23:02:17 +0200
|
||||
Subject: gdb-vla-intel-stringbt-fix.patch
|
||||
|
||||
;;=push+jan
|
||||
|
||||
http://sourceware.org/ml/gdb-patches/2014-08/msg00025.html
|
||||
|
||||
On Fri, 01 Aug 2014 09:20:19 +0200, Keven Boell wrote:
|
||||
> I just tried it on Fedora 20 i686. Applied the patch, you mentioned, on top of
|
||||
> the Fortran VLA series and executed your dynamic-other-frame test. Everything
|
||||
> is working fine here, I cannot reproduce the crash.
|
||||
|
||||
I have it reproducible on Fedora 20 i686 with plain
|
||||
CFLAGS=-g ./configure;make;cd gdb/testsuite;make site.exp;runtest gdb.fortran/dynamic-other-frame.exp
|
||||
|
||||
Besides that I have updated the testcase with
|
||||
gdb_test_no_output "set print frame-arguments all"
|
||||
so that there is no longer needed the patch:
|
||||
[patch] Display Fortran strings in backtraces
|
||||
https://sourceware.org/ml/gdb-patches/2014-07/msg00709.html
|
||||
|
||||
The fix below has no regressions for me. Unfortunately I do not see why you
|
||||
cannot reproduce it.
|
||||
|
||||
Thanks,
|
||||
Jan
|
||||
|
||||
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
|
||||
--- a/gdb/dwarf2loc.c
|
||||
+++ b/gdb/dwarf2loc.c
|
||||
@@ -2154,6 +2154,20 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
|
||||
ctx.per_cu = per_cu;
|
||||
ctx.obj_address = 0;
|
||||
|
||||
+frame_id old_frame_id (get_frame_id (deprecated_safe_get_selected_frame ()));
|
||||
+class RestoreCall {
|
||||
+private:
|
||||
+ const std::function<void ()> func;
|
||||
+public:
|
||||
+ RestoreCall(std::function<void ()> func_):func(func_) {}
|
||||
+ ~RestoreCall() { func(); }
|
||||
+} restore_frame([=]() {
|
||||
+ frame_info *old_frame (frame_find_by_id (old_frame_id));
|
||||
+ if (old_frame != NULL)
|
||||
+ select_frame (old_frame);
|
||||
+});
|
||||
+if (frame != NULL) select_frame (frame);
|
||||
+
|
||||
scoped_value_mark free_values;
|
||||
|
||||
ctx.gdbarch = get_objfile_arch (objfile);
|
||||
diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90
|
||||
@@ -0,0 +1,24 @@
|
||||
+! Copyright 2010 Free Software Foundation, Inc.
|
||||
+!
|
||||
+! This program is free software; you can redistribute it and/or modify
|
||||
+! it under the terms of the GNU General Public License as published by
|
||||
+! the Free Software Foundation; either version 2 of the License, or
|
||||
+! (at your option) any later version.
|
||||
+!
|
||||
+! This program is distributed in the hope that it will be useful,
|
||||
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+! GNU General Public License for more details.
|
||||
+!
|
||||
+! You should have received a copy of the GNU General Public License
|
||||
+! along with this program; if not, write to the Free Software
|
||||
+! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+!
|
||||
+! Ihis file is the Fortran source file for dynamic.exp.
|
||||
+! Original file written by Jakub Jelinek <jakub@redhat.com>.
|
||||
+! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||||
+
|
||||
+subroutine bar
|
||||
+ real :: dummy
|
||||
+ dummy = 1
|
||||
+end subroutine bar
|
||||
diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp
|
||||
@@ -0,0 +1,39 @@
|
||||
+# Copyright 2010 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 2 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program; if not, write to the Free Software
|
||||
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+
|
||||
+set testfile "dynamic-other-frame"
|
||||
+set srcfile1 ${testfile}.f90
|
||||
+set srcfile2 ${testfile}-stub.f90
|
||||
+set objfile2 [standard_output_file ${testfile}-stub.o]
|
||||
+set executable ${testfile}
|
||||
+set binfile [standard_output_file ${executable}]
|
||||
+
|
||||
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${objfile2}" object {f90}] != ""
|
||||
+ || [gdb_compile "${srcdir}/${subdir}/${srcfile1} ${objfile2}" "${binfile}" executable {debug f90}] != "" } {
|
||||
+ untested "Couldn't compile ${srcfile1} or ${srcfile2}"
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+clean_restart ${executable}
|
||||
+
|
||||
+gdb_test_no_output "set print frame-arguments all"
|
||||
+
|
||||
+if ![runto bar_] then {
|
||||
+ perror "couldn't run to bar_"
|
||||
+ continue
|
||||
+}
|
||||
+
|
||||
+gdb_test "bt" {foo \(string='hello'.*}
|
||||
diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90
|
||||
@@ -0,0 +1,36 @@
|
||||
+! Copyright 2010 Free Software Foundation, Inc.
|
||||
+!
|
||||
+! This program is free software; you can redistribute it and/or modify
|
||||
+! it under the terms of the GNU General Public License as published by
|
||||
+! the Free Software Foundation; either version 2 of the License, or
|
||||
+! (at your option) any later version.
|
||||
+!
|
||||
+! This program is distributed in the hope that it will be useful,
|
||||
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+! GNU General Public License for more details.
|
||||
+!
|
||||
+! You should have received a copy of the GNU General Public License
|
||||
+! along with this program; if not, write to the Free Software
|
||||
+! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+!
|
||||
+! Ihis file is the Fortran source file for dynamic.exp.
|
||||
+! Original file written by Jakub Jelinek <jakub@redhat.com>.
|
||||
+! Modified for the GDB testcase by Jan Kratochvil <jan.kratochvil@redhat.com>.
|
||||
+
|
||||
+subroutine foo (string)
|
||||
+ interface
|
||||
+ subroutine bar
|
||||
+ end subroutine
|
||||
+ end interface
|
||||
+ character string*(*)
|
||||
+ call bar ! stop-here
|
||||
+end subroutine foo
|
||||
+program test
|
||||
+ interface
|
||||
+ subroutine foo (string)
|
||||
+ character string*(*)
|
||||
+ end subroutine
|
||||
+ end interface
|
||||
+ call foo ('hello')
|
||||
+end
|
|
@ -1,347 +0,0 @@
|
|||
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||||
From: Fedora GDB patches <invalid@email.com>
|
||||
Date: Fri, 27 Oct 2017 21:07:50 +0200
|
||||
Subject: gdb-vla-intel-tests.patch
|
||||
|
||||
;;=fedoratest
|
||||
|
||||
diff --git a/gdb/testsuite/gdb.fortran/ptr-indentation.exp b/gdb/testsuite/gdb.fortran/ptr-indentation.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/ptr-indentation.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/ptr-indentation.exp
|
||||
@@ -37,5 +37,5 @@ gdb_continue_to_breakpoint "BP1"
|
||||
gdb_test "ptype tinsta" \
|
||||
[multi_line "type = Type tuserdef" \
|
||||
" $int :: i" \
|
||||
- " PTR TO -> \\( $real :: ptr \\)" \
|
||||
+ " PTR TO -> \\( $real :: ptr\\)" \
|
||||
"End Type tuserdef"]
|
||||
diff --git a/gdb/testsuite/gdb.fortran/ptype-on-functions.exp b/gdb/testsuite/gdb.fortran/ptype-on-functions.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/ptype-on-functions.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/ptype-on-functions.exp
|
||||
@@ -42,4 +42,4 @@ gdb_test "ptype say_numbers" \
|
||||
"type = void \\(integer\\(kind=4\\), integer\\(kind=4\\), integer\\(kind=4\\)\\)"
|
||||
|
||||
gdb_test "ptype fun_ptr" \
|
||||
- "type = PTR TO -> \\( integer\\(kind=4\\) \\(\\) \\(REF TO -> \\( integer\\(kind=4\\) \\)\\) \\)"
|
||||
+ "type = PTR TO -> \\( integer\\(kind=4\\) \\(\\) \\(REF TO -> \\( integer\\(kind=4\\)\\)\\)\\)"
|
||||
diff --git a/gdb/testsuite/gdb.fortran/vla-func.exp b/gdb/testsuite/gdb.fortran/vla-func.exp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/vla-func.exp
|
||||
@@ -0,0 +1,61 @@
|
||||
+# Copyright 2014 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+standard_testfile ".f90"
|
||||
+
|
||||
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
|
||||
+ {debug f90 quiet}] } {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+if ![runto MAIN__] then {
|
||||
+ perror "couldn't run to breakpoint MAIN__"
|
||||
+ continue
|
||||
+}
|
||||
+
|
||||
+# Check VLA passed to first Fortran function.
|
||||
+gdb_breakpoint [gdb_get_line_number "func1-vla-passed"]
|
||||
+gdb_continue_to_breakpoint "func1-vla-passed"
|
||||
+gdb_test "print vla" " = \\( *\\( *22, *22, *22,\[()22, .\]*\\)" \
|
||||
+ "print vla (func1)"
|
||||
+gdb_test "ptype vla" "type = integer\\\(kind=4\\\), allocatable \\\(10,10\\\)" \
|
||||
+ "ptype vla (func1)"
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "func1-vla-modified"]
|
||||
+gdb_continue_to_breakpoint "func1-vla-modified"
|
||||
+gdb_test "print vla(5,5)" " = 55" "print vla(5,5) (func1)"
|
||||
+gdb_test "print vla(7,7)" " = 77" "print vla(5,5) (func1)"
|
||||
+
|
||||
+# Check if the values are correct after returning from func1
|
||||
+gdb_breakpoint [gdb_get_line_number "func1-returned"]
|
||||
+gdb_continue_to_breakpoint "func1-returned"
|
||||
+gdb_test "print ret" " = .TRUE." "print ret after func1 returned"
|
||||
+
|
||||
+# Check VLA passed to second Fortran function
|
||||
+gdb_breakpoint [gdb_get_line_number "func2-vla-passed"]
|
||||
+gdb_continue_to_breakpoint "func2-vla-passed"
|
||||
+gdb_test "print vla" \
|
||||
+ " = \\\(44, 44, 44, 44, 44, 44, 44, 44, 44, 44\\\)" \
|
||||
+ "print vla (func2)"
|
||||
+gdb_test "ptype vla" "type = integer\\\(kind=4\\\) \\\(10\\\)" \
|
||||
+ "ptype vla (func2)"
|
||||
+
|
||||
+# Check if the returned VLA has the correct values and ptype.
|
||||
+gdb_breakpoint [gdb_get_line_number "func2-returned"]
|
||||
+gdb_continue_to_breakpoint "func2-returned"
|
||||
+gdb_test "print vla3" " = \\\(1, 2, 44, 4, 44, 44, 44, 8, 44, 44\\\)" \
|
||||
+ "print vla3 (after func2)"
|
||||
+gdb_test "ptype vla3" "type = integer\\\(kind=4\\\), allocatable \\\(10\\\)" \
|
||||
+ "ptype vla3 (after func2)"
|
||||
diff --git a/gdb/testsuite/gdb.fortran/vla-func.f90 b/gdb/testsuite/gdb.fortran/vla-func.f90
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/vla-func.f90
|
||||
@@ -0,0 +1,71 @@
|
||||
+! Copyright 2014 Free Software Foundation, Inc.
|
||||
+!
|
||||
+! This program is free software; you can redistribute it and/or modify
|
||||
+! it under the terms of the GNU General Public License as published by
|
||||
+! the Free Software Foundation; either version 2 of the License, or
|
||||
+! (at your option) any later version.
|
||||
+!
|
||||
+! This program is distributed in the hope that it will be useful,
|
||||
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+! GNU General Public License for more details.
|
||||
+!
|
||||
+! You should have received a copy of the GNU General Public License
|
||||
+! along with this program; if not, write to the Free Software
|
||||
+! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+
|
||||
+logical function func1 (vla)
|
||||
+ implicit none
|
||||
+ integer, allocatable :: vla (:, :)
|
||||
+ func1 = allocated(vla)
|
||||
+ vla(5,5) = 55 ! func1-vla-passed
|
||||
+ vla(7,7) = 77
|
||||
+ return ! func1-vla-modified
|
||||
+end function func1
|
||||
+
|
||||
+function func2(vla)
|
||||
+ implicit none
|
||||
+ integer :: vla (:)
|
||||
+ integer :: func2(size(vla))
|
||||
+ integer :: k
|
||||
+
|
||||
+ vla(1) = 1 ! func2-vla-passed
|
||||
+ vla(2) = 2
|
||||
+ vla(4) = 4
|
||||
+ vla(8) = 8
|
||||
+
|
||||
+ func2 = vla
|
||||
+end function func2
|
||||
+
|
||||
+program vla_func
|
||||
+ implicit none
|
||||
+ interface
|
||||
+ logical function func1 (vla)
|
||||
+ integer, allocatable :: vla (:, :)
|
||||
+ end function
|
||||
+ end interface
|
||||
+ interface
|
||||
+ function func2 (vla)
|
||||
+ integer :: vla (:)
|
||||
+ integer func2(size(vla))
|
||||
+ end function
|
||||
+ end interface
|
||||
+
|
||||
+ logical :: ret
|
||||
+ integer, allocatable :: vla1 (:, :)
|
||||
+ integer, allocatable :: vla2 (:)
|
||||
+ integer, allocatable :: vla3 (:)
|
||||
+
|
||||
+ ret = .FALSE.
|
||||
+
|
||||
+ allocate (vla1 (10,10))
|
||||
+ vla1(:,:) = 22
|
||||
+
|
||||
+ allocate (vla2 (10))
|
||||
+ vla2(:) = 44
|
||||
+
|
||||
+ ret = func1(vla1)
|
||||
+ vla3 = func2(vla2) ! func1-returned
|
||||
+
|
||||
+ ret = .TRUE. ! func2-returned
|
||||
+end program vla_func
|
||||
diff --git a/gdb/testsuite/gdb.fortran/vla-ptr-info.exp b/gdb/testsuite/gdb.fortran/vla-ptr-info.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/vla-ptr-info.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/vla-ptr-info.exp
|
||||
@@ -28,5 +28,5 @@ if ![runto_main] {
|
||||
# Check the status of a pointer to a dynamic array.
|
||||
gdb_breakpoint [gdb_get_line_number "pvla-associated"]
|
||||
gdb_continue_to_breakpoint "pvla-associated"
|
||||
-gdb_test "print &pvla" " = \\(PTR TO -> \\( real\\(kind=4\\) \\(10,10,10\\) \\)\\) ${hex}" \
|
||||
+gdb_test "print &pvla" " = \\(PTR TO -> \\( real\\(kind=4\\) \\(10,10,10\\)\\)\\) ${hex}" \
|
||||
"print pvla pointer information"
|
||||
diff --git a/gdb/testsuite/gdb.fortran/vla-stringsold.exp b/gdb/testsuite/gdb.fortran/vla-stringsold.exp
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/vla-stringsold.exp
|
||||
@@ -0,0 +1,101 @@
|
||||
+# Copyright 2014 Free Software Foundation, Inc.
|
||||
+
|
||||
+# This program is free software; you can redistribute it and/or modify
|
||||
+# it under the terms of the GNU General Public License as published by
|
||||
+# the Free Software Foundation; either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+standard_testfile ".f90"
|
||||
+
|
||||
+if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \
|
||||
+ {debug f90 quiet}] } {
|
||||
+ return -1
|
||||
+}
|
||||
+
|
||||
+# check that all fortran standard datatypes will be
|
||||
+# handled correctly when using as VLA's
|
||||
+
|
||||
+if ![runto MAIN__] then {
|
||||
+ perror "couldn't run to breakpoint MAIN__"
|
||||
+ continue
|
||||
+}
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "var_char-allocated-1"]
|
||||
+gdb_continue_to_breakpoint "var_char-allocated-1"
|
||||
+gdb_test "print var_char" \
|
||||
+ " = \\(PTR TO -> \\( character\\*10\\)\\) ${hex}" \
|
||||
+ "print var_char after allocated first time"
|
||||
+gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*10\\)" \
|
||||
+ "whatis var_char first time"
|
||||
+gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*10\\)" \
|
||||
+ "ptype var_char first time"
|
||||
+gdb_test "next" "\\d+.*var_char = 'foo'.*" \
|
||||
+ "next to allocation status of var_char"
|
||||
+gdb_test "print l" " = .TRUE." "print allocation status first time"
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "var_char-filled-1"]
|
||||
+gdb_continue_to_breakpoint "var_char-filled-1"
|
||||
+gdb_test "print var_char" \
|
||||
+ " = \\(PTR TO -> \\( character\\*3\\)\\) ${hex}" \
|
||||
+ "print var_char after filled first time"
|
||||
+gdb_test "print *var_char" " = 'foo'" \
|
||||
+ "print *var_char after filled first time"
|
||||
+gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*3\\)" \
|
||||
+ "whatis var_char after filled first time"
|
||||
+gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*3\\)" \
|
||||
+ "ptype var_char after filled first time"
|
||||
+gdb_test "print var_char(1)" " = 102 'f'" "print var_char(1)"
|
||||
+gdb_test "print var_char(3)" " = 111 'o'" "print var_char(3)"
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "var_char-filled-2"]
|
||||
+gdb_continue_to_breakpoint "var_char-filled-2"
|
||||
+gdb_test "print var_char" \
|
||||
+ " = \\(PTR TO -> \\( character\\*6\\)\\) ${hex}" \
|
||||
+ "print var_char after allocated second time"
|
||||
+gdb_test "print *var_char" " = 'foobar'" \
|
||||
+ "print *var_char after allocated second time"
|
||||
+gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*6\\)" \
|
||||
+ "whatis var_char second time"
|
||||
+gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*6\\)" \
|
||||
+ "ptype var_char second time"
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "var_char-empty"]
|
||||
+gdb_continue_to_breakpoint "var_char-empty"
|
||||
+gdb_test "print var_char" \
|
||||
+ " = \\(PTR TO -> \\( character\\*0\\)\\) ${hex}" \
|
||||
+ "print var_char after set empty"
|
||||
+gdb_test "print *var_char" " = \"\"" "print *var_char after set empty"
|
||||
+gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*0\\)" \
|
||||
+ "whatis var_char after set empty"
|
||||
+gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*0\\)" \
|
||||
+ "ptype var_char after set empty"
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "var_char-allocated-3"]
|
||||
+gdb_continue_to_breakpoint "var_char-allocated-3"
|
||||
+gdb_test "print var_char" \
|
||||
+ " = \\(PTR TO -> \\( character\\*21\\)\\) ${hex}" \
|
||||
+ "print var_char after allocated third time"
|
||||
+gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*21\\)" \
|
||||
+ "whatis var_char after allocated third time"
|
||||
+gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*21\\)" \
|
||||
+ "ptype var_char after allocated third time"
|
||||
+
|
||||
+gdb_breakpoint [gdb_get_line_number "var_char_p-associated"]
|
||||
+gdb_continue_to_breakpoint "var_char_p-associated"
|
||||
+gdb_test "print var_char_p" \
|
||||
+ " = \\(PTR TO -> \\( character\\*7\\)\\) ${hex}" \
|
||||
+ "print var_char_p after associated"
|
||||
+gdb_test "print *var_char_p" " = 'johndoe'" \
|
||||
+ "print *var_char_ after associated"
|
||||
+gdb_test "whatis var_char_p" "type = PTR TO -> \\( character\\*7\\)" \
|
||||
+ "whatis var_char_p after associated"
|
||||
+gdb_test "ptype var_char_p" "type = PTR TO -> \\( character\\*7\\)" \
|
||||
+ "ptype var_char_p after associated"
|
||||
diff --git a/gdb/testsuite/gdb.fortran/vla-stringsold.f90 b/gdb/testsuite/gdb.fortran/vla-stringsold.f90
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/gdb/testsuite/gdb.fortran/vla-stringsold.f90
|
||||
@@ -0,0 +1,40 @@
|
||||
+! Copyright 2014 Free Software Foundation, Inc.
|
||||
+!
|
||||
+! This program is free software; you can redistribute it and/or modify
|
||||
+! it under the terms of the GNU General Public License as published by
|
||||
+! the Free Software Foundation; either version 2 of the License, or
|
||||
+! (at your option) any later version.
|
||||
+!
|
||||
+! This program is distributed in the hope that it will be useful,
|
||||
+! but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+! GNU General Public License for more details.
|
||||
+!
|
||||
+! You should have received a copy of the GNU General Public License
|
||||
+! along with this program; if not, write to the Free Software
|
||||
+! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
+
|
||||
+program vla_strings
|
||||
+ character(len=:), target, allocatable :: var_char
|
||||
+ character(len=:), pointer :: var_char_p
|
||||
+ logical :: l
|
||||
+
|
||||
+ allocate(character(len=10) :: var_char)
|
||||
+ l = allocated(var_char) ! var_char-allocated-1
|
||||
+ var_char = 'foo'
|
||||
+ deallocate(var_char) ! var_char-filled-1
|
||||
+ l = allocated(var_char) ! var_char-deallocated
|
||||
+ allocate(character(len=42) :: var_char)
|
||||
+ l = allocated(var_char)
|
||||
+ var_char = 'foobar'
|
||||
+ var_char = '' ! var_char-filled-2
|
||||
+ var_char = 'bar' ! var_char-empty
|
||||
+ deallocate(var_char)
|
||||
+ allocate(character(len=21) :: var_char)
|
||||
+ l = allocated(var_char) ! var_char-allocated-3
|
||||
+ var_char = 'johndoe'
|
||||
+ var_char_p => var_char
|
||||
+ l = associated(var_char_p) ! var_char_p-associated
|
||||
+ var_char_p => null()
|
||||
+ l = associated(var_char_p) ! var_char_p-not-associated
|
||||
+end program vla_strings
|
||||
diff --git a/gdb/testsuite/gdb.fortran/whatis_type.exp b/gdb/testsuite/gdb.fortran/whatis_type.exp
|
||||
--- a/gdb/testsuite/gdb.fortran/whatis_type.exp
|
||||
+++ b/gdb/testsuite/gdb.fortran/whatis_type.exp
|
||||
@@ -44,7 +44,7 @@ gdb_test "whatis t2" "type = Type t2"
|
||||
gdb_test "whatis t2v" "type = Type t2"
|
||||
gdb_test "whatis t3" "type = Type t3"
|
||||
gdb_test "whatis t3v" "type = Type t3"
|
||||
-gdb_test "whatis t3p" "type = PTR TO -> \\( Type t3 \\)"
|
||||
+gdb_test "whatis t3p" "type = PTR TO -> \\( Type t3\\)"
|
||||
|
||||
gdb_test "ptype t1" \
|
||||
[multi_line "type = Type t1" \
|
||||
@@ -73,4 +73,4 @@ gdb_test "ptype t3p" \
|
||||
[multi_line "type = PTR TO -> \\( Type t3" \
|
||||
" $int :: t3_i" \
|
||||
" Type t2 :: t2_n" \
|
||||
- "End Type t3 \\)"]
|
||||
+ "End Type t3\\)"]
|
142
gdb.spec
142
gdb.spec
|
@ -29,15 +29,15 @@
|
|||
Name: %{?scl_prefix}gdb
|
||||
|
||||
# Freeze it when GDB gets branched
|
||||
%global snapsrc 20200208
|
||||
%global snapsrc 20201024
|
||||
# See timestamp of source gnulib installed into gnulib/ .
|
||||
%global snapgnulib 20191216
|
||||
%global snapgnulib 20200630
|
||||
%global tarname gdb-%{version}
|
||||
Version: 9.2
|
||||
Version: 10.2
|
||||
|
||||
# The release always contains a leading reserved number, start it at 1.
|
||||
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
|
||||
Release: 6%{?dist}
|
||||
Release: 4%{?dist}
|
||||
|
||||
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL
|
||||
# Do not provide URL for snapshots as the file lasts there only for 2 days.
|
||||
|
@ -189,26 +189,12 @@ Source5: %{libstdcxxpython}.tar.xz
|
|||
Source6: gdbtui
|
||||
|
||||
# libipt: Intel Processor Trace Decoder Library
|
||||
%global libipt_version 2.0.2
|
||||
%global libipt_version 2.0.4
|
||||
#=fedora
|
||||
Source7: v%{libipt_version}.tar.gz
|
||||
#=fedora
|
||||
Patch1142: v1.5-libipt-static.patch
|
||||
|
||||
## [testsuite] Fix false selftest.exp FAIL from system readline-6.3+ (Patrick Palka).
|
||||
##=fedoratest
|
||||
#Patch1075: gdb-testsuite-readline63-sigint.patch
|
||||
##=fedoratest
|
||||
Patch1119: gdb-testsuite-readline63-sigint-revert.patch
|
||||
|
||||
# Fix broken configure tests compromised by LTO
|
||||
#push=Should be pushed upstream.
|
||||
Patch2000: gdb-config.patch
|
||||
|
||||
# Fix type mismatch issue exposed by LTO
|
||||
#push=Should be pushed upstream.
|
||||
Patch2001: gdb-ltofix.patch
|
||||
|
||||
# Include the auto-generated file containing the "Patch:" directives.
|
||||
# See README.local-patches for more details.
|
||||
Patch9998: _gdb.spec.Patch.include
|
||||
|
@ -481,24 +467,6 @@ find -name "*.info*"|xargs rm -f
|
|||
# See README.local-patches for more details.
|
||||
%include %{PATCH9999}
|
||||
|
||||
%if 0%{!?el6:1}
|
||||
for i in \
|
||||
gdb/python/lib/gdb/FrameWrapper.py \
|
||||
gdb/python/lib/gdb/backtrace.py \
|
||||
gdb/python/lib/gdb/command/backtrace.py \
|
||||
;do
|
||||
test -e $i
|
||||
: >$i
|
||||
done
|
||||
%endif
|
||||
|
||||
%if 0%{?rhel:1} && 0%{?rhel} <= 7
|
||||
%patch1119 -p1
|
||||
%endif
|
||||
|
||||
%patch2000 -p1
|
||||
%patch2001 -p1
|
||||
|
||||
# The above patches twiddle a .m4 file for configure, so update the affected
|
||||
# configure files
|
||||
pushd libiberty
|
||||
|
@ -793,8 +761,6 @@ perl -i.relocatable -pe 's/^(D\[".*_RELOCATABLE"\]=" )1(")$/${1}0$2/' gdb/config
|
|||
%make_build CFLAGS="$CFLAGS $FPROFILE_CFLAGS" LDFLAGS="$LDFLAGS $FPROFILE_CFLAGS" V=1
|
||||
|
||||
! grep '_RELOCATABLE.*1' gdb/config.h
|
||||
grep '^#define HAVE_LIBSELINUX 1$' gdb/config.h
|
||||
grep '^#define HAVE_SELINUX_SELINUX_H 1$' gdb/config.h
|
||||
|
||||
if [ "$fprofile" = "-fprofile" ]
|
||||
then
|
||||
|
@ -1076,13 +1042,6 @@ rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/system-gdbinit/elinos.py
|
|||
rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/system-gdbinit/wrs-linux.py
|
||||
rmdir $RPM_BUILD_ROOT%{_datadir}/gdb/system-gdbinit
|
||||
|
||||
# Patch848: gdb-dts-rhel6-python-compat.patch
|
||||
%if 0%{!?el6:1}
|
||||
rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/FrameWrapper.py
|
||||
rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/backtrace.py
|
||||
rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/command/backtrace.py
|
||||
%endif
|
||||
|
||||
%files
|
||||
# File must begin with "/": {GFDL,COPYING3,COPYING,COPYING.LIB,COPYING3.LIB}
|
||||
%if 0%{!?el6:1}
|
||||
|
@ -1189,6 +1148,97 @@ fi
|
|||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Oct 11 2021 Alexandra Hájková <ahajkova@redhat.com> - 10.2-4
|
||||
- Fix RHBZ 1874275 by modifying gdb-6.6-buildid-locate-rpm.patch (Alexandra Hájková).
|
||||
|
||||
* Fri Sep 24 2021 Alexandra Hájková <ahajkova@redhat.com> - 10.2-3
|
||||
- Backport test for RHBZ 1976887 (Kevin Buettner).
|
||||
|
||||
* Fri Sep 24 2021 Alexandra Hájková <ahajkova@redhat.com> - 10.2-3
|
||||
- Backport upstream patch which fixes internal-error: Unexpected
|
||||
type field location kind (RHBZ 1976887, Alexandra Hájková).
|
||||
|
||||
* Thu Sep 23 2021 Bruno Larsen <blarsen@redhat.com> - 10.2-2
|
||||
- Backport "[gdb] Improve early exits for env var in debuginfod-support.c"
|
||||
(Tom de Vries)
|
||||
|
||||
* Thu Sep 23 2021 Bruno Larsen <blarsen@redhat.com> - 10.2-2
|
||||
- Backport "[gdb/cli] Don't assert on empty string for core-file"
|
||||
(Tom de Vries)
|
||||
|
||||
* Thu Jun 24 2021 Kevin Buettner <kevinb@redhat.com> - 10.2-1
|
||||
- Rebase to FSF GDB 10.2.
|
||||
- Drop gdb-6.3-test-pie-20050107.patch.
|
||||
- Drop gdb-6.3-test-self-20050110.patch.
|
||||
- Drop gdb-6.5-bz218379-ppc-solib-trampoline-test.patch.
|
||||
- Drop gdb-6.6-buildid-locate-core-as-arg.patch.
|
||||
- Drop gdb-6.8-quit-never-aborts.patch.
|
||||
- Drop gdb-archer-pie-addons-keep-disabled.patch.
|
||||
- Drop gdb-archer-pie-addons.patch.
|
||||
- Drop gdb-archer-vla-tests.patch.
|
||||
- Drop gdb-archer.patch.
|
||||
- Drop gdb-attach-fail-reasons-5of5.patch.
|
||||
- Drop gdb-btrobust.patch.
|
||||
- Drop gdb-bz1219747-attach-kills.patch.
|
||||
- Drop gdb-bz533176-fortran-omp-step.patch.
|
||||
- Drop gdb-dts-rhel6-python-compat.patch.
|
||||
- Drop gdb-gnat-dwarf-crash-3of3.patch.
|
||||
- Drop gdb-jit-reader-multilib.patch.
|
||||
- Drop gdb-moribund-utrace-workaround.patch.
|
||||
- Drop gdb-rhbz1930528-fix-gnulib-build-error.patch.
|
||||
- Drop gdb-rhbz1932645-aarch64-ptrace-header-order.patch.
|
||||
- Drop gdb-vla-intel-fix-print-char-array.patch.
|
||||
- Drop gdb-vla-intel-fortran-strides.patch.
|
||||
- Drop gdb-vla-intel-stringbt-fix.patch.
|
||||
- Drop gdb-vla-intel-tests.patch.
|
||||
- Drop process_psymtab_comp_unit-type-unit.patch.
|
||||
- Drop gdb-testsuite-readline63-sigint-revert.patch.
|
||||
- Drop gdb-config.patch.
|
||||
- Add following upstream patches for Fortran stride / slice support:
|
||||
gdb-rhbz1964167-convert-enum-range_type.patch
|
||||
gdb-rhbz1964167-fortran-array-slices-at-prompt.patch
|
||||
gdb-rhbz1964167-fortran-array-strides-in-expressions.patch
|
||||
gdb-rhbz1964167-fortran-clean-up-array-expression-evaluation.patch
|
||||
gdb-rhbz1964167-fortran-range_type-to-range_flag.patch
|
||||
gdb-rhbz1964167-fortran-whitespace_array.patch
|
||||
gdb-rhbz1964167-move-fortran-expr-handling.patch
|
||||
- Backport "Exclude debuginfo files from 'outside ELF segments' warning".
|
||||
(Keith Seitz, RH BZ 1898252)
|
||||
- Backport "Fix crash when expanding partial symtab..."
|
||||
(Tom Tromey. gdb/27743)
|
||||
- Backport "[gdb/server] Don't overwrite fs/gs_base with -m32"
|
||||
- (Tom de Vries)
|
||||
|
||||
* Thu Mar 11 2021 Kevin Buettner <kevinb@redhat.com> - 10.1-4
|
||||
- Update libipt to version 2.0.4.
|
||||
|
||||
* Fri Mar 05 2021 Kevin Buettner <kevinb@redhat.com> - 10.1-3
|
||||
- Backport patches which fix frame_id_p assertion failure (RHBZ 1909902,
|
||||
Pedro Alves).
|
||||
|
||||
* Wed Nov 04 2020 Kevin Buettner <kevinb@redhat.com> - 10.1-2
|
||||
- Fix bug in local patch gdb-6.6-buildid-locate.patch which prevented
|
||||
debuginfod from working.
|
||||
|
||||
* Tue Nov 03 2020 Kevin Buettner <kevinb@redhat.com> - 10.1-1
|
||||
- Rebase to FSF GDB 10.1.
|
||||
- Bump 'snapgnulib' date.
|
||||
- Drop gdb-rhbz1818011-bfd-gcc10-error.patch.
|
||||
- Drop gdb-rhbz1822715-fix-python-deprecation.patch.
|
||||
- Drop gdb-rhbz1829702-fix-python39.patch.
|
||||
- Drop gdb-rhbz1838777-debuginfod.patch.
|
||||
- Drop gdb-rhbz1844458-use-fputX_unfiltered.patch.
|
||||
- Drop gdb-rhbz1869484-deleted-working-directory.
|
||||
- Adjust build-id related patches.
|
||||
- Ajust VLA patches.
|
||||
|
||||
* Mon Nov 2 2020 Keith Seitz <keiths@redhat.com> - 9.2-8
|
||||
- Fix missing debuginfo messages. (RH BZ 1887025)
|
||||
|
||||
* Thu Aug 20 2020 Kevin Buettner <kevinb@redhat.com> - 9.1-6
|
||||
- Backport patches fixing abort when working directory is deleted.
|
||||
(RHBZ 1869484, Sergio Durigan Junior)
|
||||
|
||||
* Mon Aug 10 2020 Keith Seitz <keiths@redhat.com>
|
||||
- Disable LTO until upstream sorts out ODR problems.
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
summary: CI Gating Plan
|
||||
discover:
|
||||
how: fmf
|
||||
directory: tests
|
||||
execute:
|
||||
how: beakerlib
|
4
sources
4
sources
|
@ -1,3 +1,3 @@
|
|||
SHA512 (gdb-libstdc++-v3-python-8.1.1-20180626.tar.xz) = a8b1c54dd348cfeb37da73f968742896be3dd13a4215f8d8519870c2abea915f5176c3fa6989ddd10f20020a16f0fab20cbae68ee8d58a82234d8778023520f8
|
||||
SHA512 (v2.0.2.tar.gz) = bc256a57a8481e0be8220624da3ccf1fe4bf0ea83e9808fdf0aad6db865aee402a36e78285efb0316c016f57e0d6fc56b647ee8e9a2ad4b05bfc1ad68ddde535
|
||||
SHA512 (gdb-9.2.tar.xz) = 73635f00f343117aa5e2436f1e1597099e2bfb31ef7bb162b273fa1ea282c3fa9b0f52762e70bfc7ad0334addb8d159e9ac7cbe5998ca4f755ea8cf90714d274
|
||||
SHA512 (v2.0.4.tar.gz) = 596d2dac25fdbd3e5660d7e1feeb7e8d5d359d1d0e19b62ef593449037df236db1d4d98820f0031061b5573ed67797a85a77fb9991e215abaabc4bfe16ceaec8
|
||||
SHA512 (gdb-10.2.tar.xz) = 3653762ac008e065c37cd641653184c9ff7ce51ee2222ade1122bec9d6cc64dffd4fb74888ef11ac1942064a08910e96b7865112ad37f4602eb0a16bed074caa
|
||||
|
|
31
tests/README
31
tests/README
|
@ -1,31 +0,0 @@
|
|||
Justification
|
||||
|
||||
Adds tests according to the CI wiki specifically the standard test
|
||||
interface in the spec.
|
||||
|
||||
The playbook includes Tier1 level test cases that have been tested in
|
||||
the following contexts and is passing reliably: Classic and
|
||||
Container. Test logs are stored in the artifacts directory.
|
||||
|
||||
The following steps are used to execute the tests using the standard
|
||||
test interface: Test environment
|
||||
|
||||
Make sure you have installed packages from the spec
|
||||
|
||||
# rpm -q ansible python2-dnf libselinux-python standard-test-roles
|
||||
ansible-2.3.2.0-1.fc26.noarch
|
||||
python2-dnf-2.6.3-11.fc26.noarch
|
||||
libselinux-python-2.6-7.fc26.x86_64
|
||||
standard-test-roles-2.4-1.fc26.noarch
|
||||
|
||||
Run tests for Classic (must be run as root)
|
||||
|
||||
# export ANSIBLE_INVENTORY=$(test -e inventory && echo inventory || echo /usr/share/ansible/inventory)
|
||||
# ansible-playbook --tags=classic tests.yml
|
||||
|
||||
Run tests for Container (must be run as root)
|
||||
|
||||
# export ANSIBLE_INVENTORY=$(test -e inventory && echo inventory || echo /usr/share/ansible/inventory)
|
||||
# export TEST_SUBJECTS=docker:docker.io/library/fedora:26
|
||||
# ansible-playbook --tags=container tests.yml
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
sta
|
||||
start
|
||||
si 30
|
||||
n 10
|
||||
up
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
summary: Debug a system binary.
|
||||
description: ''
|
||||
contact:
|
||||
- Marek Polacek <mpolacek@redhat.com>
|
||||
component:
|
||||
- gdb
|
||||
test: ./runtest.sh
|
||||
framework: beakerlib
|
||||
recommend:
|
||||
- gdb
|
||||
- coreutils
|
||||
- coreutils-debuginfo
|
||||
- glibc
|
||||
- glibc-debuginfo
|
||||
duration: 5m
|
||||
extra-summary: /tools/gdb/Sanity/debug-system-binary
|
||||
extra-task: /tools/gdb/Sanity/debug-system-binary
|
|
@ -27,8 +27,7 @@
|
|||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# Include Beaker environment
|
||||
. /usr/bin/rhts-environment.sh || exit 1
|
||||
. /usr/lib/beakerlib/beakerlib.sh || exit 1
|
||||
. /usr/share/beakerlib/beakerlib.sh || exit 1
|
||||
|
||||
CMD="gdb"
|
||||
BIN="$(which $CMD)"
|
||||
|
|
|
@ -14,5 +14,4 @@ frame 1
|
|||
b xexit
|
||||
c
|
||||
c
|
||||
c
|
||||
q
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
summary: We debug a binary that is delivered via the Toolset.
|
||||
description: ''
|
||||
contact:
|
||||
- Marek Polacek <mpolacek@redhat.com>
|
||||
component:
|
||||
- gdb
|
||||
test: ./runtest.sh
|
||||
framework: beakerlib
|
||||
recommend:
|
||||
- gdb
|
||||
- coreutils
|
||||
- binutils
|
||||
- binutils-debuginfo
|
||||
- glibc
|
||||
- glibc-debuginfo
|
||||
- gcc
|
||||
- gcc-debuginfo
|
||||
- zlib
|
||||
- zlib-debuginfo
|
||||
duration: 5m
|
||||
extra-summary: /tools/gdb/Sanity/debug-toolset-binary
|
||||
extra-task: /tools/gdb/Sanity/debug-toolset-binary
|
|
@ -32,8 +32,7 @@
|
|||
# but in fact, it doesn't have to. It should not fail either way.
|
||||
|
||||
# Include Beaker environment
|
||||
. /usr/bin/rhts-environment.sh || exit 1
|
||||
. /usr/lib/beakerlib/beakerlib.sh || exit 1
|
||||
. /usr/share/beakerlib/beakerlib.sh || exit 1
|
||||
|
||||
CMD="gdb"
|
||||
BIN="$(which $CMD)"
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
export TEST_DOCKER_EXTRA_ARGS="--privileged"
|
||||
exec merge-standard-inventory "$@"
|
|
@ -1,24 +0,0 @@
|
|||
---
|
||||
# This first play always runs on the local staging system
|
||||
- hosts: localhost
|
||||
roles:
|
||||
- role: standard-test-beakerlib
|
||||
tags:
|
||||
- classic
|
||||
- container
|
||||
tests:
|
||||
- debug-toolset-binary
|
||||
- debug-system-binary
|
||||
required_packages:
|
||||
- gdb
|
||||
- coreutils
|
||||
- binutils
|
||||
- binutils-debuginfo
|
||||
- glibc
|
||||
- glibc-debuginfo
|
||||
- gcc
|
||||
- gcc-debuginfo
|
||||
- zlib
|
||||
- zlib-debuginfo
|
||||
- coreutils-debuginfo
|
||||
- which
|
Loading…
Reference in New Issue