summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.base
Commit message (Collapse)AuthorAgeFilesLines
...
* [gdb/testsuite] Use set always-read-ctf on instead of --strip-debugTom de Vries2023-03-034-7/+19
| | | | | | Use "set always-read-ctf on" instead of --strip-debug in the ctf test-cases. Tested on x86_64-linux.
* Update expected results in long_long.expTom Tromey2023-03-031-2/+2
| | | | | | Simon pointed out that the recent patch to add half-float support to 'x/f' caused a couple of regressions in long_long.exp. This patch fixes these by updating the expected results.
* gdb: update some copyright years (2022 -> 2023)Simon Marchi2023-03-014-4/+4
| | | | | | | | | | | The copyright years in the ROCm files (e.g. solib-rocm.c) are wrong, they end in 2022 instead of 2023. I suppose because I posted (or at least prepared) the patches in 2022 but merged them in 2023, and forgot to update the year. I found a bunch of other files that are in the same situation. Fix them all up. Change-Id: Ia55f5b563606c2ba6a89046f22bc0bf1c0ff2e10 Reviewed-By: Tom Tromey <tom@tromey.com>
* gdb/testsuite: introduce is_target_non_stop helper procAndrew Burgess2023-02-282-15/+6
| | | | | | | | | | | | | | I noticed that several tests included copy & pasted code to run the 'maint show target-non-stop' command, and then switch based on the result. In this commit I factor this code out into a helper proc in lib/gdb.exp, and update all the places I could find that used this pattern to make use of the helper proc. There should be no change in what is tested after this commit. Reviewed-By: Pedro Alves <pedro@palves.net>
* Make follow_fork not rely on get_last_target_statusPedro Alves2023-02-271-2/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently, if - you're in all-stop mode, - the inferior last stopped because of a fork catchpoint, when you next resume the program, gdb checks whether it had last stopped for a fork/vfork, and if so, a) if the current thread is the one that forked, gdb follows the parent/child, depending on "set follow-fork" mode. b) if the current thread is some other thread (because you switched threads meanwhile), gdb switches back to that thread, gdb follows the parent/child, and stops the resumption command. There's a problem in b), however -- if you have "set schedule-multiple off", which is the default, or "set scheduler-locking on", gdb will still switch back to the forking thread, even if you didn't want to resume it. For example, with: (gdb) catch fork (gdb) c * thread 1 stops for fork (gdb) thread 2 (gdb) set scheduler-locking on (gdb) c gdb switches back to thread 1, and follows the fork. Or with: (gdb) add-inferior -exec prog (gdb) inferior 2 (gdb) start (gdb) inferior 1 (gdb) catch fork (gdb) c * thread 1.1 stops for fork (gdb) inferior 2 (gdb) set schedule-multiple off # this is the default (gdb) c gdb switches back to thread 1.1, and follows the fork. Another issue is that, because follow_fork relies on get_last_target_status to find the thread that has a pending fork, it is possible to confuse it. For example, "run" or "start" call init_wait_for_inferior, which clears the last target status, so this: (gdb) catch fork (gdb) c * thread 1 stops for fork (gdb) add-inferior -exec prog (gdb) inferior 2 (gdb) start (gdb) set follow-fork child (gdb) inferior 1 (gdb) n ... does not follow to the fork child of inferior 1, because the get_last_target_status call in follow_fork doesn't return a TARGET_WAITKIND_FORKED. Thanks to Simon for this example. All of the above are fixed by this patch. It changes follow_fork to not look at get_last_target_status, but to instead iterate over the set of threads that the user is resuming, and find the one that has a pending_follow kind of fork/vfork. gdb.base/foll-fork.exp is augmented to exercise the last "start" scenario described above. The other cases will be exercised in the testcase added by the following patch. Change-Id: Ifcca77e7b2456277387f40660ef06cec2b93b97e
* Improve "info program"Pedro Alves2023-02-273-23/+191
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | With gdb.base/catch-follow-exec.exp, we currently see: ~~~~~~~~~~~~~~~ (gdb) continue Continuing. process 693251 is executing new program: /usr/bin/ls [New inferior 2] [New process 693251] [Switching to process 693251] Thread 2.1 "ls" hit Catchpoint 2 (exec'd /usr/bin/ls), 0x00007ffff7fd0100 in _start () from /lib64/ld-linux-x86-64.so.2 (gdb) info prog No selected thread. ~~~~~~~~~~~~~~~ Note the "No selected thread" output. That is totally bogus, because there _is_ a selected thread. What GDB really means, is that it can't find the thread that had the latest (user-visible) stop. And that happens because "info program" gets that info from get_last_target_status, and the last target status has been cleared. However, GDB also checks if there is a selected thread, here: if (ptid == null_ptid || ptid == minus_one_ptid) error (_("No selected thread.")); .. the null_ptid part. That is also bogus, because what matters is the thread that last reported a stop, not the current thread: - in all-stop mode, "info program" displays info about the last stop. That may have happened on a thread different from the selected thread. - in non-stop mode, because all threads are controlled individually, "info program" shows info about the last stop of the selected thread. The current code already behaves this way, though in a poor way. This patch reimplements it, such that the all-stop version now finds the thread that last reported an event via the 'previous_thread' strong reference. Being a strong reference means that if that thread has exited since the event was reported, 'previous_thread' will still point to it, so we can say that the thread exited meanwhile. The patch also extends "info program" output a little, to let the user know which thread we are printing info for. For example, for the gdb.base/catch-follow-exec.exp case we shown above, we now get: (gdb) info prog Last stopped for thread 2.1 (process 710867). Using the running image of child process 710867. Program stopped at 0x7ffff7fd0100. It stopped at breakpoint 2. Type "info stack" or "info registers" for more information. (gdb) while in non-stop mode, we get: (gdb) info prog Selected thread 2.1 (process 710867). Using the running image of child process 710867. Program stopped at 0x7ffff7fd0100. It stopped at breakpoint 2. Type "info stack" or "info registers" for more information. (gdb) In both cases, the first line of output is new. The existing code considered these running/exited cases as an error, but I think that that's incorrect, since this is IMO just plain execution info as well. So the patch makes those cases regular prints, not errors. If the thread is running, we get, in non-stop mode: (gdb) info prog Selected thread 2.1 (process 710867). Selected thread is running. ... and in all-stop: (gdb) info prog Last stopped for thread 2.1 (process 710867). Thread is now running. If the thread has exited, we get, in non-stop mode: (gdb) info prog Selected thread 2.1 (process 710867). Selected thread has exited. ... and in all-stop: (gdb) info prog Last stopped for thread 2.1 (process 710867). Thread has since exited. The gdb.base/info-program.exp testcase was much extended to test all-stop/non-stop and single-threaded/multi-threaded. Change-Id: I51d9d445f772d872af3eead3449ad4aa445781b1
* [gdb/testsuite] Cleanup unnecessary expr from require lineTom de Vries2023-02-241-1/+1
| | | | | | | | | | | | | In a recent commit I've added: ... require {expr [have_compile_flag -fsplit-stack]} ... but actually the expr bit is unnecessary, and we can just use: ... require {have_compile_flag -fsplit-stack} ... Reported-By: Tom Tromey <tom@tromey.com>
* Fix Tcl quoting in gdb_assertTom Tromey2023-02-232-4/+4
| | | | | | | | | | | | The gdb_assert proc under-quotes the expression that is passed in. This leads to weird code in a couple of spots that tries to compensate: gdb_assert {{$all_regs eq $completed_regs}} ... The fix is to add a bit of quoting when evaluating the expression.
* Issue error on erroneous expressionTom Tromey2023-02-211-0/+8
| | | | | | | | | | | | | | | A while back I discovered that this does not issue an error: (gdb) p $x = (void * ) 57 $3 = (void *) 0x39 (gdb) p $x + 7 = 3 $6 = (void *) 0x3 This patch fixes the bug. Regression tested on x86-64 Fedora 36. Reviewed-By: Bruno Larsen <blarsen@redhat.com> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=19312
* [gdb/testsuite] Require -fsplit-stack in gdb.base/morestack.expTom de Vries2023-02-211-0/+2
| | | | | | | | | | | | | | | | | On aarch64-linux, I run into: ... gdb compile failed, cc1: error: '-fsplit-stack' is not supported by this \ compiler configuration UNTESTED: gdb.base/morestack.exp: failed to prepare ... Fix this by requiring -fsplit-stack, such that we have instead: ... UNSUPPORTED: gdb.base/morestack.exp: require failed: \ expr [have_compile_flag -fsplit-stack] ... Tested on x86_64-linux and aarch64-linux.
* [gdb/symtab] Trust epilogue unwind info for unknown producer (-g0 case)Tom de Vries2023-02-202-0/+106
| | | | | | | | | | For a -g0 -fasynchronous-unwind-tables exec (without .debug_info but with .eh_frame section), start using the dwarf2 unwinder instead of the "amd64 epilogue override" unwinder, by returning true in compunit_epilogue_unwind_valid for cust == nullptr. This has effect both on the amd64 and i386 targets, but only add amd64 test-case gdb.base/unwind-on-each-insn-amd64-2.exp.
* Don't throw quit while handling inferior events, part IIPedro Alves2023-02-152-3/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I noticed that if Ctrl-C was typed just while GDB is evaluating a breakpoint condition in the background, and GDB ends up reaching out to the Python interpreter, then the breakpoint condition would still fail, like: c& Continuing. (gdb) Error in testing breakpoint condition: Quit That happens because while evaluating the breakpoint condition, we enter Python, and end up calling PyErr_SetInterrupt (it's called by gdbpy_set_quit_flag, in frame #0): (top-gdb) bt #0 gdbpy_set_quit_flag (extlang=0x558c68f81900 <extension_language_python>) at ../../src/gdb/python/python.c:288 #1 0x0000558c6845f049 in set_quit_flag () at ../../src/gdb/extension.c:785 #2 0x0000558c6845ef98 in set_active_ext_lang (now_active=0x558c68f81900 <extension_language_python>) at ../../src/gdb/extension.c:743 #3 0x0000558c686d3e56 in gdbpy_enter::gdbpy_enter (this=0x7fff2b70bb90, gdbarch=0x558c6ab9eac0, language=0x0) at ../../src/gdb/python/python.c:212 #4 0x0000558c68695d49 in python_on_memory_change (inferior=0x558c6a830b00, addr=0x555555558014, len=4, data=0x558c6af8a610 "") at ../../src/gdb/python/py-inferior.c:146 #5 0x0000558c6823a071 in std::__invoke_impl<void, void (*&)(inferior*, unsigned long, long, unsigned char const*), inferior*, unsigned long, long, unsigned char const*> (__f=@0x558c6a8ecd98: 0x558c68695d01 <python_on_memory_change(inferior*, CORE_ADDR, ssize_t, bfd_byte const*)>) at /usr/include/c++/11/bits/invoke.h:61 #6 0x0000558c68237591 in std::__invoke_r<void, void (*&)(inferior*, unsigned long, long, unsigned char const*), inferior*, unsigned long, long, unsigned char const*> (__fn=@0x558c6a8ecd98: 0x558c68695d01 <python_on_memory_change(inferior*, CORE_ADDR, ssize_t, bfd_byte const*)>) at /usr/include/c++/11/bits/invoke.h:111 #7 0x0000558c68233e64 in std::_Function_handler<void (inferior*, unsigned long, long, unsigned char const*), void (*)(inferior*, unsigned long, long, unsigned char const*)>::_M_invoke(std::_Any_data const&, inferior*&&, unsigned long&&, long&&, unsigned char const*&&) (__functor=..., __args#0=@0x7fff2b70bd40: 0x558c6a830b00, __args#1=@0x7fff2b70bd38: 93824992247828, __args#2=@0x7fff2b70bd30: 4, __args#3=@0x7fff2b70bd28: 0x558c6af8a610 "") at /usr/include/c++/11/bits/std_function.h:290 #8 0x0000558c6830a96e in std::function<void (inferior*, unsigned long, long, unsigned char const*)>::operator()(inferior*, unsigned long, long, unsigned char const*) const (this=0x558c6a8ecd98, __args#0=0x558c6a830b00, __args#1=93824992247828, __args#2=4, __args#3=0x558c6af8a610 "") at /usr/include/c++/11/bits/std_function.h:590 #9 0x0000558c6830a620 in gdb::observers::observable<inferior*, unsigned long, long, unsigned char const*>::notify (this=0x558c690828c0 <gdb::observers::memory_changed>, args#0=0x558c6a830b00, args#1=93824992247828, args#2=4, args#3=0x558c6af8a610 "") at ../../src/gdb/../gdbsupport/observable.h:166 #10 0x0000558c68309d95 in write_memory_with_notification (memaddr=0x555555558014, myaddr=0x558c6af8a610 "", len=4) at ../../src/gdb/corefile.c:363 #11 0x0000558c68904224 in value_assign (toval=0x558c6afce910, fromval=0x558c6afba6c0) at ../../src/gdb/valops.c:1190 #12 0x0000558c681e3869 in expr::assign_operation::evaluate (this=0x558c6af8e150, expect_type=0x0, exp=0x558c6afcfe60, noside=EVAL_NORMAL) at ../../src/gdb/expop.h:1902 #13 0x0000558c68450c89 in expr::logical_or_operation::evaluate (this=0x558c6afab060, expect_type=0x0, exp=0x558c6afcfe60, noside=EVAL_NORMAL) at ../../src/gdb/eval.c:2330 #14 0x0000558c6844a896 in expression::evaluate (this=0x558c6afcfe60, expect_type=0x0, noside=EVAL_NORMAL) at ../../src/gdb/eval.c:110 #15 0x0000558c6844a95e in evaluate_expression (exp=0x558c6afcfe60, expect_type=0x0) at ../../src/gdb/eval.c:124 #16 0x0000558c682061ef in breakpoint_cond_eval (exp=0x558c6afcfe60) at ../../src/gdb/breakpoint.c:4971 ... The fix is to disable cooperative SIGINT handling while handling inferior events, so that SIGINT is saved in the global quit flag, and not in the extension language, while handling an event. This commit augments the testcase added by the previous commit to test this scenario as well. Approved-By: Tom Tromey <tom@tromey.com> Change-Id: Idf8ab815774ee6f4b45ca2d0caaf30c9b9f127bb
* Don't throw quit while handling inferior eventsPedro Alves2023-02-152-0/+110
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This implements what I suggested here: https://inbox.sourceware.org/gdb-patches/ab97c553-f406-b094-cdf3-ba031fdea925@palves.net/ Here is the current default quit_handler, a function that ends up called by the QUIT macro: void default_quit_handler (void) { if (check_quit_flag ()) { if (target_terminal::is_ours ()) quit (); else target_pass_ctrlc (); } } As we can see above, when the inferior is running in the foreground, then a Ctrl-C is translated into a call to target_pass_ctrlc(). The target_terminal::is_ours() case above is there to handle the scenario where GDB has the terminal, meaning it is handling some command the user typed, like "list", or "p a + b" or some such. However, when the inferior is running on the background, say with "c&", GDB also has the terminal. Run control handling is now done in the "background". The CLI is responsive to user commands. If users type Ctrl-C, they're expecting it to interrupt whatever command they next type in the CLI, which again, could be "list", "p a + b", etc. It's as if background run control was handled by a separate thread, and the Ctrl-C is meant to go to the main thread, handling the CLI. However, when handling an event, inside fetch_inferior_event & friends, a Ctrl-C _also_ results in a Quit exception, from the same default_quit_handler function shown above. This quit aborts run control handling, breakpoint condition evaluation, etc., and may even leave run control in an inconsistent state. The testcase added by this patch illustrates this. The test program just loops a number of times calling the "foo" function. The idea is to set a breakpoint in the "foo" function with a condition that sends SIGINT to GDB, and then evaluates to false, which results in the program being re-resumed in the background. The SIGINT-sending emulates pressing Ctrl-C just while GDB was evaluating the breakpoint condition, except, it's more deterministic. It looks like this: (gdb) p $counter = 0 $1 = 0 (gdb) b foo if $counter++ == 10 || $_shell("kill -SIGINT `pidof gdb`") != 0 Breakpoint 2 at 0x555555555131: file gdb.base/bg-exec-sigint-bp-cond.c, line 21. (gdb) c& Continuing. (gdb) After that background continue, the breakpoint should be hit 10 times, and we should see 10 "Quit" being printed on the screen. As if the user typed Ctrl-C on the prompt a number of times with no inferior running: (gdb) <<< Ctrl-C (gdb) Quit <<< Ctrl-C (gdb) Quit <<< Ctrl-C (gdb) However, here's what you see instead: (gdb) c& Continuing. (gdb) Quit (gdb) Just one Quit, and nothing else. If we look at the thread's state, we see: (gdb) info threads Id Target Id Frame * 1 Thread 0x7ffff7d6f740 (LWP 112192) "bg-exec-sigint-" foo () at gdb.base/bg-exec-sigint-bp-cond.c:21 So the thread stopped, but we didn't report a stop... Issuing another continue shows the same immediate-and-silent-stop: (gdb) c& Continuing. (gdb) Quit (gdb) p $counter $2 = 2 As mentioned, since the run control handling, and breakpoint and watchpoint evaluation, etc. are running in the background from the perspective of the CLI, when users type Ctrl-C in this situation, they're thinking of aborting whatever other command they were typing or running at the prompt, not the run control side, not the previous "c&" command. So I think that we should install a custom quit_handler while inside fetch_inferior_event, where we already disable pagination and other things for a similar reason. This custom quit handler does nothing if GDB has the terminal, and forwards Ctrl-C to the inferior otherwise. With the patch implementing that, and the same testcase, here's what you see instead: (gdb) p $counter = 0 $1 = 0 (gdb) b foo if $counter++ == 10 || $_shell("kill -SIGINT `pidof gdb`") != 0 Breakpoint 2 at 0x555555555131: file gdb.base/bg-exec-sigint-bp-cond.c, line 21. (gdb) c& Continuing. (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Quit (gdb) Breakpoint 2, foo () at gdb.base/bg-exec-sigint-bp-cond.c:21 21 return 0; Approved-By: Tom Tromey <tom@tromey.com> Change-Id: I1f10d99496a7d67c94b258e45963e83e439e1778
* Add new "$_shell(CMD)" internal functionPedro Alves2023-02-152-0/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For testing a following patch, I wanted a way to send a SIGINT to GDB from a breakpoint condition. And I didn't want to do it from a Python breakpoint or Python function, as I wanted to exercise non-Python code paths. So I thought I'd add a new $_shell internal function, that runs a command under the shell, and returns the exit code. With this, I could write: (gdb) b foo if $_shell("kill -SIGINT $gdb_pid") != 0 || <other condition> I think this is generally useful, hence I'm proposing it here. Here's the new function in action: (gdb) p $_shell("true") $1 = 0 (gdb) p $_shell("false") $2 = 1 (gdb) p $_shell("echo hello") hello $3 = 0 (gdb) p $_shell("foobar") bash: line 1: foobar: command not found $4 = 127 (gdb) help function _shell $_shell - execute a shell command and returns the result. Usage: $_shell (command) Returns the command's exit code: zero on success, non-zero otherwise. (gdb) NEWS and manual changes included. Approved-By: Andrew Burgess <aburgess@redhat.com> Approved-By: Tom Tromey <tom@tromey.com> Approved-By: Eli Zaretskii <eliz@gnu.org> Change-Id: I7e36d451ee6b428cbf41fded415ae2d6b4efaa4e
* Make "ptype INTERNAL_FUNCTION" in Ada print like other languagesPedro Alves2023-02-151-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently, printing the type of an internal function in Ada shows double <>s, like: (gdb) with language ada -- ptype $_isvoid type = <<internal function>> while all other languages print it with a single <>, like: (gdb) with language c -- ptype $_isvoid type = <internal function> I don't think there's a reason that Ada needs to be different. We currently print the double <>s because we take this path in ada_print_type: switch (type->code ()) { default: gdb_printf (stream, "<"); c_print_type (type, "", stream, show, level, language_ada, flags); gdb_printf (stream, ">"); break; ... and the type's name already has the <>s. Fix this by simply adding an early check for TYPE_CODE_INTERNAL_FUNCTION. Approved-By: Andrew Burgess <aburgess@redhat.com> Approved-By: Tom Tromey <tom@tromey.com> Change-Id: Ic2b6527b9240a367471431023f6e27e6daed5501 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30105
* Fix "ptype INTERNAL_FUNC" (PR gdb/30105)Pedro Alves2023-02-151-0/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently, looking at the type of an internal function, like below, hits an odd error: (gdb) ptype $_isvoid type = <internal function>type not handled in c_type_print_varspec_prefix() That is an error thrown from c-typeprint.c:c_type_print_varspec_prefix, where it reads: ... case TYPE_CODE_DECFLOAT: case TYPE_CODE_FIXED_POINT: /* These types need no prefix. They are listed here so that gcc -Wall will reveal any types that haven't been handled. */ break; default: error (_("type not handled in c_type_print_varspec_prefix()")); break; Internal function types have type code TYPE_CODE_INTERNAL_FUNCTION, which is not explicitly handled by that switch. That comment quoted above says that gcc -Wall will reveal any types that haven't been handled, but that's not actually true, at least with modern GCCs. You would need to enable -Wswitch-enum for that, which we don't. If I do enable that warning, then I see that we're missing handling for the following type codes: TYPE_CODE_INTERNAL_FUNCTION, TYPE_CODE_MODULE, TYPE_CODE_NAMELIST, TYPE_CODE_XMETHOD TYPE_CODE_MODULE and TYPE_CODE_NAMELIST and Fortran-specific, so it'd be a little weird to handle them here. I tried to reach this code with TYPE_CODE_XMETHOD, but couldn't figure out how to. ptype on an xmethod isn't treated specially, it just complains that the method doesn't exist. I've extended the gdb.python/py-xmethods.exp testcase to make sure of that. My thinking is that whatever type code we add next, the most likely scenario is that it won't need any special handling, so we'd just be adding another case to that "do nothing" list. If we do need special casing for whatever type code, I think that tests added at the same time as the feature would uncover it anyhow. If we do miss adding the special casing, then it still looks better to me to print the type somewhat incompletely than to error out and make it harder for users to debug whatever they need. So I think that the best thing to do here is to just remove all those explicit "do nothing" cases, along with the error default case. After doing that, I decided to write a testcase that iterates over all supported languages doing "ptype INTERNAL_FUNC". That revealed that Pascal has a similar problem, except the default case hits a gdb_assert instead of an error: (gdb) with language pascal -- ptype $_isvoid type = ../../src/gdb/p-typeprint.c:268: internal-error: type_print_varspec_prefix: unexpected type A problem internal to GDB has been detected, further debugging may prove unreliable. That is fixed by this patch in the same way. You'll notice that the new testcase special-cases the Ada expected output: } elseif {$lang == "ada"} { gdb_test "ptype \$_isvoid" "<<internal function>>" } else { gdb_test "ptype \$_isvoid" "<internal function>" } That will be subject of the following patch. Approved-By: Andrew Burgess <aburgess@redhat.com> Change-Id: I81aec03523cceb338b5180a0b4c2e4ad26b4c4db Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30105
* gdb: add test for readline handling very long commandsAndrew Burgess2023-02-111-0/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The test added in this commit tests for a long fixed readline issue relating to long command lines. A similar patch has existed in the Fedora GDB tree for several years, but I don't see any reason why this test would not be suitable for inclusion in upstream GDB. I've updated the patch to current testsuite standards. The test is checking for an issue that was fixed by this readline patch: https://lists.gnu.org/archive/html/bug-readline/2006-11/msg00002.html Which was merged into readline 6.0 (released ~2010). The issue was triggered when the user enters a long command line, which wrapped over multiple terminal lines. The crash looks like this: free(): invalid pointer Fatal signal: Aborted ----- Backtrace ----- 0x4fb583 gdb_internal_backtrace_1 ../../src/gdb/bt-utils.c:122 0x4fb583 _Z22gdb_internal_backtracev ../../src/gdb/bt-utils.c:168 0x6047b9 handle_fatal_signal ../../src/gdb/event-top.c:964 0x7f26e0cc56af ??? 0x7f26e0cc5625 ??? 0x7f26e0cae8d8 ??? 0x7f26e0d094be ??? 0x7f26e0d10aab ??? 0x7f26e0d124ab ??? 0x7f26e1d32e12 rl_free_undo_list ../../readline-5.2/undo.c:119 0x7f26e1d229eb readline_internal_teardown ../../readline-5.2/readline.c:405 0x7f26e1d3425f rl_callback_read_char ../../readline-5.2/callback.c:197 0x604c0d gdb_rl_callback_read_char_wrapper_noexcept ../../src/gdb/event-top.c:192 0x60581d gdb_rl_callback_read_char_wrapper ../../src/gdb/event-top.c:225 0x60492f stdin_event_handler ../../src/gdb/event-top.c:545 0xa60015 gdb_wait_for_event ../../src/gdbsupport/event-loop.cc:694 0xa6078d gdb_wait_for_event ../../src/gdbsupport/event-loop.cc:593 0xa6078d _Z16gdb_do_one_eventi ../../src/gdbsupport/event-loop.cc:264 0x6fc459 start_event_loop ../../src/gdb/main.c:411 0x6fc459 captured_command_loop ../../src/gdb/main.c:471 0x6fdce4 captured_main ../../src/gdb/main.c:1310 0x6fdce4 _Z8gdb_mainP18captured_main_args ../../src/gdb/main.c:1325 0x44f694 main ../../src/gdb/gdb.c:32 --------------------- I recreated the above crash by a little light hacking on GDB, and then linking GDB against readline 5.2. The above stack trace was generated from the test included in this patch, and matches the trace that was included in the original bug report. It is worth acknowledging that without hacking things GDB has a minimum requirement of readline 7.0. This test is not about checking whether GDB has been built against an older version of readline, it is about checking that readline doesn't regress in this area. Reviewed-By: Tom Tromey <tom@tromey.com>
* GDB: Introduce limited array lengths while printing valuesAndrew Burgess2023-02-102-0/+290
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit introduces the idea of loading only part of an array in order to print it, what I call "limited length" arrays. The motivation behind this work is to make it possible to print slices of very large arrays, where very large means bigger than `max-value-size'. Consider this GDB session with the current GDB: (gdb) set max-value-size 100 (gdb) p large_1d_array value requires 400 bytes, which is more than max-value-size (gdb) p -elements 10 -- large_1d_array value requires 400 bytes, which is more than max-value-size notice that the request to print 10 elements still fails, even though 10 elements should be less than the max-value-size. With a patched version of GDB: (gdb) p -elements 10 -- large_1d_array $1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...} So now the print has succeeded. It also has loaded `max-value-size' worth of data into value history, so the recorded value can be accessed consistently: (gdb) p -elements 10 -- $1 $2 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9...} (gdb) p $1 $3 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, <unavailable> <repeats 75 times>} (gdb) Accesses with other languages work similarly, although for Ada only C-style [] array element/dimension accesses use history. For both Ada and Fortran () array element/dimension accesses go straight to the inferior, bypassing the value history just as with C pointers. Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com>
* GDB: Only make data actually retrieved into value history availableMaciej W. Rozycki2023-02-102-0/+102
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | While it makes sense to allow accessing out-of-bounds elements in the debuggee and see whatever there might happen to be there in memory (we are a debugger and not a programming rules enforcement facility and we want to make people's life easier in chasing bugs), e.g.: (gdb) print one_hundred[-1] $1 = 0 (gdb) print one_hundred[100] $2 = 0 (gdb) we shouldn't really pretend that we have any meaningful data around values recorded in history (what these commands really retrieve are current debuggee memory contents outside the original data accessed, really confusing in my opinion). Mark values recorded in history as such then and verify accesses to be in-range for them: (gdb) print one_hundred[-1] $1 = <unavailable> (gdb) print one_hundred[100] $2 = <unavailable> Add a suitable test case, which also covers integer overflows in data location calculation. Approved-By: Tom Tromey <tom@tromey.com>
* GDB: Ignore `max-value-size' setting with value history accessesMaciej W. Rozycki2023-02-101-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We have an inconsistency in value history accesses where array element accesses cause an error for entries exceeding the currently selected `max-value-size' setting even where such accesses successfully complete for elements located in the inferior, e.g.: (gdb) p/d one $1 = 0 (gdb) p/d one_hundred $2 = {0 <repeats 100 times>} (gdb) p/d one_hundred[99] $3 = 0 (gdb) set max-value-size 25 (gdb) p/d one_hundred value requires 100 bytes, which is more than max-value-size (gdb) p/d one_hundred[99] $7 = 0 (gdb) p/d $2 value requires 100 bytes, which is more than max-value-size (gdb) p/d $2[99] value requires 100 bytes, which is more than max-value-size (gdb) According to our documentation the `max-value-size' setting is a safety guard against allocating an overly large amount of memory. Moreover a statement in documentation says, concerning this setting, that: "Setting this variable does not affect values that have already been allocated within GDB, only future allocations." While in the implementer-speak the sentence may be unambiguous I think the outside user may well infer that the setting does not apply to values previously printed. Therefore rather than just fixing this inconsistency it seems reasonable to lift the setting for value history accesses, under an implication that by having been retrieved from the debuggee they have already passed the safety check. Do it then, by suppressing the value size check in `value_copy' -- under an observation that if the original value has been already loaded (i.e. it's not lazy), then it must have previously passed said check -- making the last two commands succeed: (gdb) p/d $2 $8 = {0 <repeats 100 times>} (gdb) p/d $2 [99] $9 = 0 (gdb) Expand the testsuite accordingly, covering both value history handling and the use of `value_copy' by `make_cv_value', used by Python code.
* [gdb/testsuite] Fix linespec ambiguity in gdb.base/longjmp.expTom de Vries2023-02-101-5/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PR testsuite/30103 reports the following failure on aarch64-linux (ubuntu 22.04): ... (gdb) PASS: gdb.base/longjmp.exp: with_probes=0: pattern 1: next to longjmp next warning: Breakpoint address adjusted from 0x83dc305fef755015 to \ 0xffdc305fef755015. Warning: Cannot insert breakpoint 0. Cannot access memory at address 0xffdc305fef755015 __libc_siglongjmp (env=0xaaaaaaab1018 <env>, val=1) at ./setjmp/longjmp.c:30 30 } (gdb) KFAIL: gdb.base/longjmp.exp: with_probes=0: pattern 1: gdb/26967 \ (PRMS: next over longjmp) delete breakpoints Delete all breakpoints? (y or n) y (gdb) info breakpoints No breakpoints or watchpoints. (gdb) break 63 No line 63 in the current file. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) FAIL: gdb.base/longjmp.exp: with_probes=0: pattern 2: setup: breakpoint \ at pattern start (got interactive prompt) ... The test-case intends to set the breakpoint on line number 63 in gdb.base/longjmp.c. It tries to do so by specifying "break 63", which specifies a line in the "current source file". Due to the KFAIL PR, gdb stopped in __libc_siglongjmp, and because of presence of debug info, the "current source file" becomes glibc's ./setjmp/longjmp.c. Consequently, setting the breakpoint fails. Fix this by adding a $subdir/$srcfile: prefix to the breakpoint linespecs. I've managed to reproduce the FAIL on x86_64/-m32, by installing the glibc-32bit-debuginfo package. This allowed me to confirm the "current source file" that is used: ... (gdb) KFAIL: gdb.base/longjmp.exp: with_probes=0: pattern 1: gdb/26967 \ (PRMS: next over longjmp) info source^M Current source file is ../setjmp/longjmp.c^M ... Tested on x86_64-linux, target boards unix/{-m64,-m32}. Reported-By: Luis Machado <luis.machado@arm.com> Reviewed-By: Tom Tromey <tom@tromey.com> PR testsuite/30103 Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30103
* Don't let .gdb_history file cause failuresTom Tromey2023-02-081-0/+4
| | | | | | | | | I had a .gdb_history file in my testsuite directory in the build tree, and this provoked a failure in gdbhistsize-history.exp. It seems simple to prevent this file from causing a failure.
* [gdb/testsuite] Use maint ignore-probes in gdb.base/longjmp.expTom de Vries2023-02-081-138/+157
| | | | | | | | | | | Test-case gdb.base/longjmp.exp handles both the case that there is a libc longjmp probe, and the case that there isn't. However, it only tests one of the two cases. Use maint ignore-probes to test both cases, if possible. Tested on x86_64-linux.
* [gdb/testsuite] Use maint ignore-probes in gdb.base/solib-corrupted.expTom de Vries2023-02-081-12/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Test-case gdb.base/solib-corrupted.exp only works for a glibc without probes interface, otherwise we run into: ... XFAIL: gdb.base/solib-corrupted.exp: info probes UNTESTED: gdb.base/solib-corrupted.exp: GDB is using probes ... Fix this by using maint ignore-probes to simulate the absence of the relevant probes. Also, it requires glibc debuginfo, and if not present, it produces an XFAIL: ... XFAIL: gdb.base/solib-corrupted.exp: make solibs looping UNTESTED: gdb.base/solib-corrupted.exp: no _r_debug symbol has been found ... This is incorrect, because an XFAIL indicates a known problem in the environment. In this case, there is no problem: the environment is functioning as expected when glibc debuginfo is not installed. Fix this by using UNSUPPORTED instead, and make the message less cryptic: ... UNSUPPORTED: gdb.base/solib-corrupted.exp: make solibs looping \ (glibc debuginfo required) ... Finally, with glibc debuginfo present, we run into: ... (gdb) PASS: gdb.base/solib-corrupted.exp: make solibs looping info sharedlibrary^M warning: Corrupted shared library list: 0x7ffff7ffe750 != 0x0^M From To Syms Read Shared Object Library^M 0x00007ffff7dd4170 0x00007ffff7df4090 Yes /lib64/ld-linux-x86-64.so.2^M (gdb) FAIL: gdb.base/solib-corrupted.exp: corrupted list \ (shared library list corrupted) ... due to commit 44288716537 ("gdb, testsuite: extend gdb_test_multiple checks"). Fix this by rewriting into gdb_test_multiple and using -early. Tested on x86_64-linux, with and without glibc debuginfo installed.
* gdb: fix display of thread condition for multi-location breakpointsAndrew Burgess2023-02-073-1/+112
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit addresses the issue in PR gdb/30087. If a breakpoint with multiple locations has a thread condition, then the 'info breakpoints' output is a little messed up, here's an example of the current output: (gdb) break foo thread 1 Breakpoint 2 at 0x401114: foo. (3 locations) (gdb) break bar thread 1 Breakpoint 3 at 0x40110a: file /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c, line 32. (gdb) info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y <MULTIPLE> thread 1 stop only in thread 1 2.1 y 0x0000000000401114 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 2.2 y 0x0000000000401146 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 2.3 y 0x0000000000401168 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 3 breakpoint keep y 0x000000000040110a in bar at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:32 thread 1 stop only in thread 1 Notice that, at the end of the location for breakpoint 3, the 'thread 1' condition is printed, but this is then repeated on the next line with 'stop only in thread 1'. In contrast, for breakpoint 2, the 'thread 1' appears randomly, in the "What" column, though slightly offset, non of the separate locations have the 'thread 1' information. Additionally for breakpoint 2 we also get a 'stop only in thread 1' line. There's two things going on here. First the randomly placed 'thread 1' for breakpoint 2 is due to a bug in print_one_breakpoint_location, where we check the variable part_of_multiple instead of header_of_multiple. If I fix this oversight, then the output is now: (gdb) break foo thread 1 Breakpoint 2 at 0x401114: foo. (3 locations) (gdb) break bar thread 1 Breakpoint 3 at 0x40110a: file /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c, line 32. (gdb) info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y <MULTIPLE> stop only in thread 1 2.1 y 0x0000000000401114 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 thread 1 2.2 y 0x0000000000401146 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 thread 1 2.3 y 0x0000000000401168 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 thread 1 3 breakpoint keep y 0x000000000040110a in bar at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:32 thread 1 stop only in thread 1 The 'thread 1' condition is now displayed at the end of each location, which makes the output the same for single location breakpoints and multi-location breakpoints. However, there's still some duplication here. Both breakpoints 2 and 3 include a 'stop only in thread 1' line, and it feels like the additional 'thread 1' is redundant. In fact, there's a comment to this very effect in the code: /* FIXME: This seems to be redundant and lost here; see the "stop only in" line a little further down. */ So, lets fix this FIXME. The new plan is to remove all the trailing 'thread 1' markers from the CLI output, we now get this: (gdb) break foo thread 1 Breakpoint 2 at 0x401114: foo. (3 locations) (gdb) break bar thread 1 Breakpoint 3 at 0x40110a: file /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c, line 32. (gdb) info breakpoints Num Type Disp Enb Address What 2 breakpoint keep y <MULTIPLE> stop only in thread 1 2.1 y 0x0000000000401114 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 2.2 y 0x0000000000401146 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 2.3 y 0x0000000000401168 in foo at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:25 3 breakpoint keep y 0x000000000040110a in bar at /tmp/src/gdb/testsuite/gdb.base/thread-bp-multi-loc.c:32 stop only in thread 1 All of the above points are also true for the Ada 'task' breakpoint condition, and the changes I've made also update how the task information is printed, though in the case of the Ada task there was no 'stop only in task XXX' line printed, so I've added one of those. Obviously it can't be quite that easy. For MI backwards compatibility I've retained the existing code (but now only for MI like outputs), which ensures we should generate backwards compatible output. I've extended an Ada test to cover the new task related output, and updated all the tests I could find that checked for the old output. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30087 Approved-By: Pedro Alves <pedro@palves.net>
* gdb: Add per-remote target variables for memory read and write configChristina Schimpe2023-01-301-17/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds per-remote target variables for the configuration of memory read- and write packet size. It is a further change to commit "gdb: Make global feature array a per-remote target array" to apply the fixme notes described in commit 5b6d1e4 "Multi-target support". The former global variables for that configuration are still available to allow the command line configuration for all future remote connections. Similar to the command line configuration of the per- remote target feature array, the commands - set remotewritesize (deprecated) - set remote memory-read-packet-size - set remote memory-write-packet-size will configure the current target (if available). If no target is available, the default configuration for future remote connections is adapted. The show command will display the current remote target's packet size configuration. If no remote target is selected, the default configuration for future connections will be shown. It is required to adapt the test gdb.base/remote.exp which is failing for --target_board=native-extended-gdbserver. With that board GDB connects to gdbserver at gdb start time. Due to this patch two loggings "The target may not be able to.." are shown if the command 'set remote memory-write-packet-size fixed' is executed while a target is connected for the current inferior. To fix this, the clean_restart command is moved to a later time point of the test. It is sufficient to be connected to the server when "runto_main" is executed. Now the connection time is similar to a testrun with --target_board=native-gdbserver. To allow the user to distinguish between the packet-size configuration for future remote connections and for the currently selected target, the commands' loggings are adapted.
* gdb: Make global feature array a per-remote target arrayChristina Schimpe2023-01-305-6/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch applies the appropriate FIXME notes described in commit 5b6d1e4 "Multi-target support". "You'll notice that remote.c includes some FIXME notes. These refer to the fact that the global arrays that hold data for the remote packets supported are still globals. For example, if we connect to two different servers/stubs, then each might support different remote protocol features. They might even be different architectures, like e.g., one ARM baremetal stub, and a x86 gdbserver, to debug a host/controller scenario as a single program. That isn't going to work correctly today, because of said globals. I'm leaving fixing that for another pass, since it does not appear to be trivial, and I'd rather land the base work first. It's already useful to be able to debug multiple instances of the same server (e.g., a distributed cluster, where you have full control over the servers installed), so I think as is it's already reasonable incremental progress." Using this patch it is possible to configure per-remote targets' feature packets. Given the following setup for two gdbservers: ~~~~ gdbserver --multi :1234 gdbserver --disable-packet=vCont --multi :2345 ~~~~ Before this patch configuring of range-stepping was not possible for one of two connected remote targets with different support for the vCont packet. As one of the targets supports vCont, it should be possible to configure "set range-stepping". However, the output of GDB looks like: (gdb) target extended-remote :1234 Remote debugging using :1234 (gdb) add-inferior -no-connection [New inferior 2] Added inferior 2 (gdb) inferior 2 [Switching to inferior 2 [<null>] (<noexec>)] (gdb) target extended-remote :2345 Remote debugging using :2345 (gdb) set range-stepping on warning: Range stepping is not supported by the current target (gdb) inferior 1 [Switching to inferior 1 [<null>] (<noexec>)] (gdb) set range-stepping on warning: Range stepping is not supported by the current target ~~~~ Two warnings are shown. The warning for inferior 1 should not appear as it is connected to a target supporting the vCont package. ~~~~ (gdb) target extended-remote :1234 Remote debugging using :1234 (gdb) add-inferior -no-connection [New inferior 2] Added inferior 2 (gdb) inferior 2 [Switching to inferior 2 [<null>] (<noexec>)] (gdb) target extended-remote :2345 Remote debugging using :2345 (gdb) set range-stepping on warning: Range stepping is not supported by the current target (gdb) inferior 1 [Switching to inferior 1 [<null>] (<noexec>)] (gdb) set range-stepping on (gdb) ~~~~ Now only one warning is shown for inferior 2, which is connected to a target not supporting vCont. The per-remote target feature array is realized by a new class remote_features, which stores the per-remote target array and provides functions to determine supported features of the target. A remote_target object now has a new member of that class. Each time a new remote_target object is initialized, a new per-remote target array is constructed based on the global remote_protocol_packets array. The global array is initialized in the function _initialize_remote and can be configured using the command line. Before this patch the command line configuration affected current targets and future remote targets (due to the global feature array used by all remote targets). This behavior is different and the configuration applies as follows: - If a target is connected, the command line configuration affects the current connection. All other existing remote targets are not affected. - If not connected, the command line configuration affects future connections. The show command displays the current remote target's configuration. If no remote target is selected the default configuration for future connections is shown. If we have for instance the following setup with inferior 2 being selected: ~~~~ (gdb) info inferiors Num Description Connection Executable 1 <null> 1 (extended-remote :1234) * 2 <null> 2 (extended-remote :2345) ~~~~ Before this patch, if we run 'set remote multiprocess-feature-packet', the following configuration was set: The feature array of all remote targets (in this setup the two connected targets) and all future remote connections are affected. After this patch, it will be configured as follows: The feature array of target with port :2345 which is currently selected will be configured. All other existing remote targets are not affected. The show command 'show remote multiprocess-feature-packet' will display the configuration of target with port :2345. Due to this configuration change, it is required to adapt the test "gdb/testsuite/gdb.multi/multi-target-info-inferiors.exp" to configure the multiprocess-feature-packet before the connections are created. To inform the gdb user about the new behaviour of the 'show remote PACKET-NAME' commands and the new configuration impact for remote targets using the 'set remote PACKET-NAME' commands the commands' outputs are adapted. Due to this change it is required to adapt each test using the set/show remote 'PACKET-NAME' commands.
* [gdb/testsuite] Simplify gdb.base/unwind-on-each-insn.exp.tclTom de Vries2023-01-274-34/+14
| | | | | | | | | | | | | | | | | | | | | Recent commit 1d98e564c97 ("[gdb/testsuite] Add gdb.base/unwind-on-each-insn-{amd64,i386}.exp") broke commit eb015bf86b6 ("[gdb/testsuite] Avoid using .eh_frame in gdb.base/unwind-on-each-insn.exp"), in the sense that gdb.base/unwind-on-each-insn.exp no longer uses -fno-asynchronous-unwind-tables, due to trying to concatenate two lists using: ... lappend srcfile2_flags $nodebug_flags ... which should instead be: ... lappend srcfile2_flags {*}$nodebug_flags ... Fix this by simplifying gdb.base/unwind-on-each-insn.exp.tcl, completely leaving the responsibility to set srcfile_flags and srcfile2_flags to each includer. Tested on x86_64-linux.
* Use clean_restart in gdb.baseTom Tromey2023-01-2636-172/+44
| | | | | | | Change gdb.base to use clean_restart more consistently.
* Eliminate spurious returns from the test suiteTom Tromey2023-01-2641-78/+1
| | | | | | | | A number of tests end with "return". However, this is unnecessary. This patch removes all of these.
* [gdb/testsuite] Add gdb.base/unwind-on-each-insn-{amd64,i386}.expTom de Vries2023-01-266-153/+792
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The gcc 4.4.x (and earlier) compilers had the problem that the unwind info in the epilogue was inaccurate. In order to work around this in gdb, epilogue unwinders were added with a higher priority than the dwarf unwinders in the amd64 and i386 targets: - amd64_epilogue_frame_unwind, and - i386_epilogue_frame_unwind. Subsequently, the epilogue unwind info problem got fixed in gcc 4.5.0. However, the epilogue unwinders prevented gdb from taking advantage of the fixed epilogue unwind info, so the scope of the epilogue unwinders was limited, bailing out for gcc >= 4.5.0. There was no regression test added for this preference scheme, so if we now declare epilogue unwind info from all gcc versions as trusted, no test will start failing. Fix this by adding an amd64 and i386 regression test for this. I have no gcc 4.4.x lying around, so I fabricated the assembly files by: - commenting out some .cfi directives to break the epilogue unwind info, and - hand-editing the producer info to 4.4.7 to activate the fix. Tested on x86_64-linux, target boards unix/{-m64,-m32}.
* [gdb/testsuite] Add and use is_x86_64_m64_targetTom de Vries2023-01-261-4/+1
| | | | | | Add new proc is_x86_64_m64_target and use it where appropriate. Tested on x86_64-linux.
* Use require with is_remoteTom Tromey2023-01-2526-102/+41
| | | | | | | | | This changes some tests to use require with 'is_remote', rather than an explicit test. This adds uniformity helps clean up more spots where a test might exit early without any notification.
* Add unsupported calls where neededTom Tromey2023-01-252-0/+2
| | | | | | | | | | | | A number of tests will exit early without saying why. This patch adds "unsupported" at spots like this that I could readily find. There are definitely more of these; for example dw2-ranges.exp fails silently because a compilation fails. I didn't attempt to address these as that is a much larger task.
* Introduce and use is_any_targetTom Tromey2023-01-253-11/+3
| | | | | | | | | | | | A few tests work on two different targets that can't be detected with a single call to istarget -- that proc only accepts globs, not regular expressions. This patch introduces a new is_any_target proc and then converts these tests to use it in a 'require'.
* Use require with istargetTom Tromey2023-01-251-11/+1
| | | | | | | | | | | | This changes many tests to use require when checking 'istarget'. A few of these conversions were already done in earlier patches. No change was needed to 'require' to make this work, due to the way it is written. I think the result looks pretty clear, and it has the bonus of helping to ensure that the reason that a test is skipped is always logged.
* Rename skip_float_test to allow formTom Tromey2023-01-2512-40/+40
| | | | | | | | This renames skip_float_test to allow_float_test and updates its users to use require.
* [gdb/testsuite] Fix gdb.base/unwind-on-each-insn.exp for -m32Tom de Vries2023-01-251-1/+1
| | | | | | | | | | | | | | | | | | | With test-case gdb.base/unwind-on-each-insn.exp and target board unix/-m32, I now get: ... # of expected passes 25 ... instead of: ... # of expected passes 133 ... as I used to get before commit d25a8dbc7c3 ("[gdb/testsuite] Allow debug srcfile2 in gdb.base/unwind-on-each-insn.exp"), due to the test-case trying to match "rip = " and info frame printing "eip = " instead. Fix this by dropping "rip" from the regexp. Tested on x86_64-linux, target boards unix/{-m64,-m32}.
* [gdb/testsuite] Allow debug srcfile2 in gdb.base/unwind-on-each-insn.expTom de Vries2023-01-251-2/+4
| | | | | | | | | | | | | | | | | | Test-case gdb.base/unwind-on-each-insn.exp compiles $srcfile with debug info, and $srcfile2 without. Occasionally, I try both files with debug info: ... - $srcfile $debug_flags $srcfile2 $nodebug_flags]]} { + $srcfile $debug_flags $srcfile2 $debug_flags]]} { ... This shortcuts the test due to no longer recognizing that stepi still lands in foo. Fix this by determining whether still in foo by checking the info frame output. Tested on x86_64-linux.
* [gdb/testsuite] Allow nodebug srcfile in gdb.base/unwind-on-each-insn.expTom de Vries2023-01-251-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Test-case gdb.base/unwind-on-each-insn.exp compiles $srcfile with debug info, and $srcfile2 without. Occasionally, I try both files with debug info: ... - $srcfile $debug_flags $srcfile2 $nodebug_flags]]} { + $srcfile $debug_flags $srcfile2 $debug_flags]]} { ... and both files without: ... - $srcfile $debug_flags $srcfile2 $nodebug_flags]]} { + $srcfile $nodebug_flags $srcfile2 $nodebug_flags]]} { ... In the latter case, I run into: ... FAIL: gdb.base/unwind-on-each-insn.exp: foo: instruction 1: bt 2 FAIL: gdb.base/unwind-on-each-insn.exp: foo: instruction 1: up ... due to a mismatch between the regexp and the different output due to using nodebug. Fix this by making the regexp less strict. Tested on x86_64-linux.
* [gdb/testsuite] Analyze non-leaf fn in gdb.base/unwind-on-each-insn.expTom de Vries2023-01-253-59/+86
| | | | | | | | | | | | | | | | | | | | | | | | | In test-case gdb.base/unwind-on-each-insn.exp, we stepi through function foo to check various invariants at each insn, in particular hoping to excercise insns that modify stack and frame pointers. Function foo is a leaf function, so add a non-leaf function bar, and step through it as well (using nexti instead of stepi). With the updated test-case, on powerpc64le-linux, I run into PR tdep/30049: ... FAIL: bar: instruction 5: bt 2 FAIL: bar: instruction 5: up FAIL: bar: instruction 5: [string equal $fid $::main_fid] FAIL: bar: instruction 6: bt 2 FAIL: bar: instruction 6: up FAIL: bar: instruction 6: [string equal $fid $::main_fid] ... Tested on: - x86_64-linux (-m64 and -m32) - s390x-linux (-m64 and -m31) - aarch64-linux - powerpc64le-linux
* [gdb/testsuite] Improve leaf fn in gdb.base/unwind-on-each-insn.expTom de Vries2023-01-253-4/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In test-case gdb.base/unwind-on-each-insn.exp, we stepi through function foo to check various invariants at each insn, in particular hoping to excercise insns that modify stack and frame pointers. For x86_64-linux, we have a reasonably complex foo (and similar for -m32): ... 4004bc: 55 push %rbp 4004bd: 48 89 e5 mov %rsp,%rbp 4004c0: 90 nop 4004c1: 5d pop %rbp 4004c2: c3 ret ... Both stack pointer (%rsp) and frame pointer (%rbp) are modified. Also for s390x-linux (and similar for -m31): ... 0000000001000668 <foo>: 1000668: e3 b0 f0 58 00 24 stg %r11,88(%r15) 100066e: b9 04 00 bf lgr %r11,%r15 1000672: e3 b0 b0 58 00 04 lg %r11,88(%r11) 1000678: 07 fe br %r14 ... Frame pointer (%r11) is modified. Likewise for powerpc64le-linux: ... 00000000100006c8 <foo>: 100006c8: f8 ff e1 fb std r31,-8(r1) 100006cc: d1 ff 21 f8 stdu r1,-48(r1) 100006d0: 78 0b 3f 7c mr r31,r1 100006d4: 00 00 00 60 nop 100006d8: 30 00 3f 38 addi r1,r31,48 100006dc: f8 ff e1 eb ld r31,-8(r1) 100006e0: 20 00 80 4e blr ... Both stack pointer (r1) and frame pointer (r31) are modified. But for aarch64-linux, we have: ... 00000000004005fc <foo>: 4005fc: d503201f nop 400600: d65f03c0 ret ... There's no insn that modifies stack or frame pointer. Fix this by making foo more complex, adding an (unused) argument: ... 0000000000400604 <foo>: 400604: d10043ff sub sp, sp, #0x10 400608: f90007e0 str x0, [sp, #8] 40060c: d503201f nop 400610: 910043ff add sp, sp, #0x10 400614: d65f03c0 ret ... such that the stack pointer (sp) is modified. [ Note btw that we're seeing the effects of -momit-leaf-frame-pointer, with -mno-omit-leaf-frame-pointer we have instead: ... 0000000000400604 <foo>: 400604: a9be7bfd stp x29, x30, [sp, #-32]! 400608: 910003fd mov x29, sp 40060c: f9000fa0 str x0, [x29, #24] 400610: d503201f nop 400614: a8c27bfd ldp x29, x30, [sp], #32 400618: d65f03c0 ret ... such that also the frame pointer (x29) is modified. ] Having made foo more complex, we now run into the following fail on x86_64/-m32: ... FAIL: gdb.base/unwind-on-each-insn.exp: instruction 1: $sp_value == $main_sp .... The problem is that the stack pointer has changed inbetween the sampling of main_sp and *foo, in particular by the push insn: ... 804841a: 68 c0 84 04 08 push $0x80484c0 804841f: e8 10 00 00 00 call 8048434 <foo> ... Fix this by updating main_sp. On powerpc64le-linux, with gcc 7.5.0 I now run into PR tdep/30021: ... FAIL: gdb.base/unwind-on-each-insn.exp: insn 7: $fba_value == $main_fba FAIL: gdb.base/unwind-on-each-insn.exp: insn 7: [string equal $fid $main_fid] ... but I saw the same failure before this commit with gcc 4.8.5. Tested on: - x86_64-linux (-m64 and -m32) - s390x-linux (-m64 and -m31) - powerpc64le-linux - aarch64-linux Also I've checked that the test-case still functions as regression test for PR record/16678 on x86_64.
* [gdb/testsuite] Avoid using .eh_frame in gdb.base/unwind-on-each-insn.expTom de Vries2023-01-231-2/+12
| | | | | | | | | | | | | | | | | | | | | | | | | One purpose of the gdb.base/unwind-on-each-insn.exp test-case is to test the architecture-specific unwinders on foo, so unwind-on-each-insn-foo.c is compiled with nodebug, to prevent the dwarf unwinders from taking effect. For for instance gcc x86_64 though, -fasynchronous-unwind-tables is enabled by default, generating an .eh_frame section contribution which might enable the dwarf unwinders and bypass the architecture-specific unwinders. Currently, that happens to be not the case due to the current implementation of epilogue_unwind_valid, which assumes that in absence of debug info proving that the compiler is gcc >= 4.5.0, the .eh_frame contribution is invalid. That may change though, see PR30028, in which case gdb.base/unwind-on-each-insn.exp stops being a regression test for commit 49d7cd733a7 ("Change calculation of frame_id by amd64 epilogue unwinder"). Fix this by making sure that we don't use .eh_frame info regardless of epilogue_unwind_valid, simply by not generating it using -fno-asynchronous-unwind-tables. Tested on x86_64-linux, target boards unix/{-m64,-m32}, using compilers gcc 7.5.0 and clang 13.0.1.
* [gdb/testsuite] Simplify gdb.base/unwind-on-each-insn.expTom de Vries2023-01-231-51/+11
| | | | | | | | | | | | | | | | | | | | | | | In test-case gdb.base/unwind-on-each-insn.exp, we try to determine the last disassembled insn in function foo. This in it self is fragile, as demonstrated by commit 91836f41e20 ("Powerpc fix for gdb.base/unwind-on-each-insn.exp"). The use of the last disassembled insn in the test-case is to stop stepping in foo once reaching it. However, the intent is to stop stepping just before returning to main. There is no guarantee that the last disassembled insn: - is actually executed - is executed just before returning to main - is executed only once. Fix this by simplying the test-case to continue stepping till stepping out of foo. Tested on x86_64-linux.
* [gdb/testsuite] Fix untested in gdb.base/frame-view.expTom de Vries2023-01-231-1/+1
| | | | | | | | | | | | | | | When running test-case gdb.base/frame-view.exp, I see: ... gdb compile failed, ld: frame-view0.o: in function `main': frame-view.c:73: undefined reference to `pthread_create' ld: frame-view.c:76: undefined reference to `pthread_join' collect2: error: ld returned 1 exit status UNTESTED: gdb.base/frame-view.exp: failed to prepare ... Fix this by adding pthreads to the compilation flags. Tested on x86_64-linux.
* gdb: make user-created frames reinflatableSimon Marchi2023-01-203-4/+89
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch teaches frame_info_ptr to reinflate user-created frames (frames created through create_new_frame, with the "select-frame view" command). Before this patch, frame_info_ptr doesn't support reinflating user-created frames, because it currently reinflates by getting the current target frame (for frame 0) or frame_find_by_id (for other frames). To reinflate a user-created frame, we need to call create_new_frame, to make it lookup an existing user-created frame, or otherwise create one. So, in prepare_reinflate, get the frame id even if the frame has level 0, if it is user-created. In reinflate, if the saved frame id is user create it, call create_new_frame. In order to test this, I initially enhanced the gdb.base/frame-view.exp test added by the previous patch by setting a pretty-printer for the type of the function parameters, in which we do an inferior call. This causes print_frame_args to not reinflate its frame (which is a user-created one) properly. On one machine (my Arch Linux one), it properly catches the bug, as the frame is not correctly restored after printing the first parameter, so it messes up the second parameter: frame #0 baz (z1=hahaha, z2=<error reading variable: frame address is not available.>) at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:40 40 return z1.m + z2.n; (gdb) FAIL: gdb.base/frame-view.exp: with_pretty_printer=true: frame frame #0 baz (z1=hahaha, z2=<error reading variable: frame address is not available.>) at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:40 40 return z1.m + z2.n; (gdb) FAIL: gdb.base/frame-view.exp: with_pretty_printer=true: frame again However, on another machine (my Ubuntu 22.04 one), it just passes fine, without the appropriate fix. I then thought about writing a selftest for that, it's more reliable. I left the gdb.base/frame-view.exp pretty printer test there, it's already written, and we never know, it might catch some unrelated issue some day. Change-Id: I5849baf77991fc67a15bfce4b5e865a97265b386 Reviewed-By: Bruno Larsen <blarsen@redhat.com>
* gdb: make it possible to restore selected user-created framesSimon Marchi2023-01-202-0/+144
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I would like to improve frame_info_ptr to automatically grab the information needed to reinflate a frame, and automatically reinflate it as needed. One thing that is in the way is the fact that some frames can be created out of thin air by the create_new_frame function. These frames are not the fruit of unwinding from the target's current frame. These frames are created by the "select-frame view" command. These frames are not correctly handled by the frame save/restore functions, save_selected_frame, restore_selected_frame and lookup_selected_frame. This can be observed here, using the test included in this patch: $ ./gdb --data-directory=data-directory -nx -q testsuite/outputs/gdb.base/frame-view/frame-view Reading symbols from testsuite/outputs/gdb.base/frame-view/frame-view... (gdb) break thread_func Breakpoint 1 at 0x11a2: file /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c, line 42. (gdb) run Starting program: /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/frame-view/frame-view [Thread debugging using libthread_db enabled] Using host libthread_db library "/usr/lib/../lib/libthread_db.so.1". [New Thread 0x7ffff7cc46c0 (LWP 4171134)] [Switching to Thread 0x7ffff7cc46c0 (LWP 4171134)] Thread 2 "frame-view" hit Breakpoint 1, thread_func (p=0x0) at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:42 42 foo (11); (gdb) info frame Stack level 0, frame at 0x7ffff7cc3ee0: rip = 0x5555555551a2 in thread_func (/home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:42); saved rip = 0x7ffff7d4e8fd called by frame at 0x7ffff7cc3f80 source language c. Arglist at 0x7ffff7cc3ed0, args: p=0x0 Locals at 0x7ffff7cc3ed0, Previous frame's sp is 0x7ffff7cc3ee0 Saved registers: rbp at 0x7ffff7cc3ed0, rip at 0x7ffff7cc3ed8 (gdb) thread 1 [Switching to thread 1 (Thread 0x7ffff7cc5740 (LWP 4171122))] #0 0x00007ffff7d4b4b6 in ?? () from /usr/lib/libc.so.6 Here, we create a custom frame for thread 1 (using the stack from thread 2, for convenience): (gdb) select-frame view 0x7ffff7cc3f80 0x5555555551a2 The first calls to "frame" looks good: (gdb) frame #0 thread_func (p=0x7ffff7d4e630) at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:42 42 foo (11); But not the second one: (gdb) frame #0 0x00007ffff7d4b4b6 in ?? () from /usr/lib/libc.so.6 This second "frame" command shows the current target frame instead of the user-created frame. It's not totally clear how the "select-frame view" feature is expected to behave, especially since it's not tested. I heard accounts that it used to be possible to select a frame like this and do "up" and "down" to navigate the backtrace starting from that frame. The fact that create_new_frame calls frame_unwind_find_by_frame to install the right unwinder suggest that it used to be possible. But that doesn't work today: (gdb) select-frame view 0x7ffff7cc3f80 0x5555555551a2 (gdb) up Initial frame selected; you cannot go up. (gdb) down Bottom (innermost) frame selected; you cannot go down. and "backtrace" always shows the actual thread's backtrace, it ignores the user-created frame: (gdb) bt #0 0x00007ffff7d4b4b6 in ?? () from /usr/lib/libc.so.6 #1 0x00007ffff7d50403 in ?? () from /usr/lib/libc.so.6 #2 0x000055555555521a in main () at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/frame-view.c:56 I don't want to address all the `select-frame view` issues , but I think we can agree that the "frame" command changing the selected frame, as shown above, is a bug. I would expect that command to show the currently selected frame and not change it. This happens because of the scoped_restore_selected_frame object in print_frame_args. The frame information is saved in the constructor (the backtrace below), and restored in the destructor. #0 save_selected_frame (frame_id=0x7ffdc0020ad0, frame_level=0x7ffdc0020af0) at /home/simark/src/binutils-gdb/gdb/frame.c:1682 #1 0x00005631390242f0 in scoped_restore_selected_frame::scoped_restore_selected_frame (this=0x7ffdc0020ad0) at /home/simark/src/binutils-gdb/gdb/frame.c:324 #2 0x000056313993581e in print_frame_args (fp_opts=..., func=0x62100023bde0, frame=..., num=-1, stream=0x60b000000300) at /home/simark/src/binutils-gdb/gdb/stack.c:755 #3 0x000056313993ad49 in print_frame (fp_opts=..., frame=..., print_level=1, print_what=SRC_AND_LOC, print_args=1, sal=...) at /home/simark/src/binutils-gdb/gdb/stack.c:1401 #4 0x000056313993835d in print_frame_info (fp_opts=..., frame=..., print_level=1, print_what=SRC_AND_LOC, print_args=1, set_current_sal=1) at /home/simark/src/binutils-gdb/gdb/stack.c:1126 #5 0x0000563139932e0b in print_stack_frame (frame=..., print_level=1, print_what=SRC_AND_LOC, set_current_sal=1) at /home/simark/src/binutils-gdb/gdb/stack.c:368 #6 0x0000563139932bbe in print_stack_frame_to_uiout (uiout=0x611000016840, frame=..., print_level=1, print_what=SRC_AND_LOC, set_current_sal=1) at /home/simark/src/binutils-gdb/gdb/stack.c:346 #7 0x0000563139b0641e in print_selected_thread_frame (uiout=0x611000016840, selection=...) at /home/simark/src/binutils-gdb/gdb/thread.c:1993 #8 0x0000563139940b7f in frame_command_core (fi=..., ignored=true) at /home/simark/src/binutils-gdb/gdb/stack.c:1871 #9 0x000056313994db9e in frame_command_helper<frame_command_core>::base_command (arg=0x0, from_tty=1) at /home/simark/src/binutils-gdb/gdb/stack.c:1976 Since the user-created frame has level 0 (identified by the saved level -1), lookup_selected_frame just reselects the target's current frame, and the user-created frame is lost. My goal here is to fix this particular problem. Currently, select_frame does not set selected_frame_id and selected_frame_level for frames with level 0. It leaves them at null_frame_id / -1, indicating to restore_selected_frame to use the target's current frame. User-created frames also have level 0, so add a special case them such that select_frame saves their selected id and level. save_selected_frame does not need any change. Change the assertion in restore_selected_frame that checks `frame_level != 0` to account for the fact that we can restore user-created frames, which have level 0. Finally, change lookup_selected_frame to make it able to re-create user-created frame_info objects from selected_frame_level and selected_frame_id. Add a minimal test case for the case described above, that is the "select-frame view" command followed by the "frame" command twice. In order to have a known stack frame to switch to, the test spawns a second thread, and tells the first thread to use the other thread's top frame. Change-Id: Ifc77848dc465fbd21324b9d44670833e09fe98c7 Reviewed-By: Bruno Larsen <blarsen@redhat.com>
* GDB/testsuite: Expand for character string limiting optionsAndrew Burgess2023-01-192-20/+70
| | | | | | | | | | | | | | | | | | | | | | | | | | | Modify test cases that verify the operation of the array element limit with character strings such that they are executed twice, once with the `set print characters' option set to `elements' and the limit controlled with the `set print elements' option, and then again with the limit controlled with the `set print characters' option instead. Similarly with the `-elements' and `-characters' options for the `print' command. Additionally verify that said `print' command options combined yield the expected result. Verify correct $_gdb_setting and $_gdb_setting_str values for the `print characters' setting, in particular the `void' value for the `elements' default, which has no corresponding integer value exposed. Add Guile and Python coverage for the `print characters' GDB setting. There are new tests for Ada and Pascal, as the string printing code for these languages is different than the generic string printing code used by other languages. Modula2 also has different string printing code, but (a) this is similar to Pascal, and (b) there are no existing modula2 tests written in Modula2, so I'm not sure how I'd even test the Modula2 string printing. Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com> Approved-By: Simon Marchi <simon.marchi@efficios.com>
* GDB: Add a character string limiting optionAndrew Burgess2023-01-192-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit splits the `set/show print elements' option into two. We retain `set/show print elements' for controlling how many elements of an array we print, but a new `set/show print characters' setting is added which is used for controlling how many characters of a string are printed. The motivation behind this change is to allow users a finer level of control over how data is printed, reflecting that, although strings can be thought of as arrays of characters, users often want to treat these two things differently. For compatibility reasons by default the `set/show print characters' option is set to `elements', which makes the limit for character strings follow the setting of the `set/show print elements' option, as it used to. Using `set print characters' with any other value makes the limit independent from the `set/show print elements' setting, however it can be restored to the default with the `set print characters elements' command at any time. A corresponding `-characters' option for the `print' command is added, with the same semantics, i.e. one can use `elements' to make a given `print' invocation follow the limit of elements, be it set with the `-elements' option also given with the same invocation or taken from the `set/show print elements' setting, for characters as well regardless of the current setting of the `set/show print characters' option. The GDB changes are all pretty straightforward, just changing references to the old 'print_max' to use a new `get_print_max_chars' helper which figures out which of the two of `print_max' and `print_max_chars' values to use. Likewise, the documentation is just updated to reference the new setting where appropriate. To make people's life easier the message shown by `show print elements' now indicates if the setting also applies to character strings: (gdb) set print characters elements (gdb) show print elements Limit on string chars or array elements to print is 200. (gdb) set print characters unlimited (gdb) show print elements Limit on array elements to print is 200. (gdb) and the help text shows the dependency as well: (gdb) help set print elements Set limit on array elements to print. "unlimited" causes there to be no limit. This setting also applies to string chars when "print characters" is set to "elements". (gdb) In the testsuite there are two minor updates, one to add `-characters' to the list of completions now shown for the `print' command, and a bare minimum pair of checks for the right handling of `set print characters' and `show print characters', copied from the corresponding checks for `set print elements' and `show print elements' respectively. Co-Authored-By: Maciej W. Rozycki <macro@embecosm.com> Approved-By: Simon Marchi <simon.marchi@efficios.com>
* GDB: Allow arbitrary keywords in integer set commandsMaciej W. Rozycki2023-01-194-23/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rather than just `unlimited' allow the integer set commands (or command options) to define arbitrary keywords for the user to use, removing hardcoded arrangements for the `unlimited' keyword. Remove the confusingly named `var_zinteger', `var_zuinteger' and `var_zuinteger_unlimited' `set'/`show' command variable types redefining them in terms of `var_uinteger', `var_integer' and `var_pinteger', which have the range of [0;UINT_MAX], [INT_MIN;INT_MAX], and [0;INT_MAX] each. Following existing practice `var_pinteger' allows extra negative values to be used, however unlike `var_zuinteger_unlimited' any number of such values can be defined rather than just `-1'. The "p" in `var_pinteger' stands for "positive", for the lack of a more appropriate unambiguous letter, even though 0 obviously is not positive; "n" would be confusing as to whether it stands for "non-negative" or "negative". Add a new structure, `literal_def', the entries of which define extra keywords allowed for a command and numerical values they correspond to. Those values are not verified against the basic range supported by the underlying variable type, allowing extra values to be allowed outside that range, which may or may not be individually made visible to the user. An optional value translation is possible with the structure to follow the existing practice for some commands where user-entered 0 is internally translated to UINT_MAX or INT_MAX. Such translation can now be arbitrary. Literals defined by this structure are automatically used for completion as necessary. So for example: const literal_def integer_unlimited_literals[] = { { "unlimited", INT_MAX, 0 }, { nullptr } }; defines an extra `unlimited' keyword and a user-visible 0 value, both of which get translated to INT_MAX for the setting to be used with. Similarly: const literal_def zuinteger_unlimited_literals[] = { { "unlimited", -1, -1 }, { nullptr } }; defines the same keyword and a corresponding user-visible -1 value that is used for the requested setting. If the last member were omitted (or set to `{}') here, then only the keyword would be allowed for the user to enter and while -1 would still be used internally trying to enter it as a part of a command would result in an "integer -1 out of range" error. Use said error message in all cases (citing the invalid value requested) replacing "only -1 is allowed to set as unlimited" previously used for `var_zuinteger_unlimited' settings only rather than propagating it to `var_pinteger' type. It could only be used for the specific case where a single extra `unlimited' keyword was defined standing for -1 and the use of numeric equivalents is discouraged anyway as it is for historical reasons only that they expose GDB internals, confusingly different across variable types. Similarly update the "must be >= -1" Guile error message. Redefine Guile and Python parameter types in terms of the new variable types and interpret extra keywords as Scheme keywords and Python strings used to communicate corresponding parameter values. Do not add a new PARAM_INTEGER Guile parameter type, however do handle the `var_integer' variable type now, permitting existing parameters defined by GDB proper, such as `listsize', to be accessed from Scheme code. With these changes in place it should be trivial for a Scheme or Python programmer to expand the syntax of the `make-parameter' command and the `gdb.Parameter' class initializer to have arbitrary extra literals along with their internal representation supplied. Update the testsuite accordingly. Approved-By: Simon Marchi <simon.marchi@efficios.com>