Skip to content
Snippets Groups Projects
  1. Mar 15, 2023
  2. Mar 14, 2023
    • Tom Tromey's avatar
      Implement DAP variables, scopes, and evaluate requests · 8900a92e
      Tom Tromey authored
      The DAP code already claimed to implement "scopes" and "evaluate", but
      this wasn't done completely correctly.  This patch implements these
      and also implements the "variables" request.
      
      After this patch, variables and scopes correctly report their
      sub-structure.  This also interfaces with the gdb pretty-printer API,
      so the output of pretty-printers is available.
      
      8900a92e
    • Tom Tromey's avatar
      Fix DAP frame bug with older versions of Python · 85c72d70
      Tom Tromey authored
      
      Tom de Vries pointed out that one DAP test failed on Python 3.6
      because gdb.Frame is not hashable.
      
      This patch fixes the problem by using a list to hold the frames.  This
      is less efficient but there normally won't be that many frames.
      
      Tested-by: default avatarTom de Vries <tdevries@suse.de>
      85c72d70
  3. Mar 11, 2023
    • Tom Tromey's avatar
      Constify linetables · 977a0c16
      Tom Tromey authored
      
      Linetables no longer change after they are created.  This patch
      applies const to them.
      
      Note there is one hack to cast away const in mdebugread.c.  This code
      allocates a linetable using 'malloc', then later copies it to the
      obstack.  While this could be cleaned up, I chose not to do so because
      I have no way of testing it.
      
      Approved-By: default avatarSimon Marchi <simon.marchi@efficios.com>
      977a0c16
    • Tom Tromey's avatar
      Change linetables to be objfile-independent · 1acc9dca
      Tom Tromey authored
      
      This changes linetables to not add the text offset to the addresses
      they contain.  I did this in a few steps, necessarily combined
      together in one patch: I renamed the 'pc' member to 'm_pc', added the
      appropriate accessors, and then recompiled.  Then I fixed all the
      errors.  Where possible I generally chose to use the raw_pc accessor,
      as it is less expensive.
      
      Note that this patch discounts the possibility that the text section
      offset might cause wraparound in the addresses in the line table.
      However, this was already discounted -- in particular,
      objfile_relocate1 did not re-sort the table in this scenario.  (There
      was a bug open about this, but as far as I can tell this has never
      happened, it's not even clear what inspired that bug.)
      
      Approved-By: default avatarSimon Marchi <simon.marchi@efficios.com>
      1acc9dca
  4. Mar 09, 2023
  5. Mar 06, 2023
    • Kévin Le Gouguec's avatar
      gdb/python: Fix --disable-tui build · 1d6653fd
      Kévin Le Gouguec authored
      As of 2023-02-13 "gdb/python: deallocate tui window factories at Python
      shut down" (9ae4519d), a TUI-less build fails with:
      
      $src/gdb/python/py-tui.c: In function ‘void gdbpy_finalize_tui()’:
      $src/gdb/python/py-tui.c:621:3: error: ‘gdbpy_tui_window_maker’ has not been declared
        621 |   gdbpy_tui_window_maker::invalidate_all ();
            |   ^~~~~~~~~~~~~~~~~~~~~~
      
      Since gdbpy_tui_window_maker is only defined under #ifdef TUI, add an
      #ifdef guard in gdbpy_finalize_tui as well.
      1d6653fd
    • Tom Tromey's avatar
      Fix DAP stackTrace through frames without debuginfo · 68ca7890
      Tom Tromey authored
      The DAP stackTrace implementation did not fully account for frames
      without debuginfo.  Attemping this would yield a result like:
      
      {"request_seq": 5, "type": "response", "command": "stackTrace", "success": false, "message": "'NoneType' object has no attribute 'filename'", "seq": 11}
      
      This patch fixes the problem by adding another check for None.
      68ca7890
  6. Mar 03, 2023
  7. Mar 02, 2023
    • Simon Marchi's avatar
      gdb: update some copyright years (2022 -> 2023) · 14ade916
      Simon Marchi authored
      
      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: default avatarTom Tromey <tom@tromey.com>
      14ade916
  8. Feb 28, 2023
    • Andrew Burgess's avatar
      gdb: fix mi breakpoint-deleted notifications for thread-specific b/p · 2968b79f
      Andrew Burgess authored
      Background
      ----------
      
      When a thread-specific breakpoint is deleted as a result of the
      specific thread exiting the function remove_threaded_breakpoints is
      called which sets the disposition of the breakpoint to
      disp_del_at_next_stop and sets the breakpoint number to 0.  Setting
      the breakpoint number to zero has the effect of hiding the breakpoint
      from the user.  We also print a message indicating that the breakpoint
      has been deleted.
      
      It was brought to my attention during a review of another patch[1]
      that setting a breakpoints number to zero will suppress the MI
      breakpoint-deleted notification for that breakpoint, and indeed, this
      can be seen to be true, in delete_breakpoint, if the breakpoint number
      is zero, then GDB will not notify the breakpoint_deleted observer.
      
      It seems wrong that a user created, thread-specific breakpoint, will
      have a =breakpoint-created notification, but will not have a
      =breakpoint-deleted notification.  I suspect that this is a bug.
      
      [1] https://sourceware.org/pipermail/gdb-patches/2023-February/196560.html
      
      The First Problem
      -----------------
      
      During my initial testing I wanted to see how GDB handled the
      breakpoint after it's number was set to zero.  To do this I created
      the testcase gdb.threads/thread-bp-deleted.exp.  This test creates a
      worker thread, which immediately exits.  After the worker thread has
      exited the main thread spins in a loop.
      
      In GDB I break once the worker thread has been created and place a
      thread-specific breakpoint, then use 'continue&' to resume the
      inferior in non-stop mode.  The worker thread then exits, but the main
      thread never stops - instead it sits in the spin.  I then tried to use
      'maint info breakpoints' to see what GDB thought of the
      thread-specific breakpoint.
      
      Unfortunately, GDB crashed like this:
      
        (gdb) continue&
        Continuing.
        (gdb) [Thread 0x7ffff7c5d700 (LWP 1202458) exited]
        Thread-specific breakpoint 3 deleted - thread 2 no longer in the thread list.
        maint info breakpoints
        ... snip some output ...
      
        Fatal signal: Segmentation fault
        ----- Backtrace -----
        0x5ffb62 gdb_internal_backtrace_1
                ../../src/gdb/bt-utils.c:122
        0x5ffc05 _Z22gdb_internal_backtracev
                ../../src/gdb/bt-utils.c:168
        0x89965e handle_fatal_signal
                ../../src/gdb/event-top.c:964
        0x8997ca handle_sigsegv
                ../../src/gdb/event-top.c:1037
        0x7f96f5971b1f ???
                /usr/src/debug/glibc-2.30-2-gd74461fa34/nptl/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
        0xe602b0 _Z15print_thread_idP11thread_info
                ../../src/gdb/thread.c:1439
        0x5b3d05 print_one_breakpoint_location
                ../../src/gdb/breakpoint.c:6542
        0x5b462e print_one_breakpoint
                ../../src/gdb/breakpoint.c:6702
        0x5b5354 breakpoint_1
                ../../src/gdb/breakpoint.c:6924
        0x5b58b8 maintenance_info_breakpoints
                ../../src/gdb/breakpoint.c:7009
        ... etc ...
      
      As the thread-specific breakpoint is set to disp_del_at_next_stop, and
      GDB hasn't stopped yet, then the breakpoint still exists in the global
      breakpoint list.
      
      The breakpoint will not show in 'info breakpoints' as its number is
      zero, but it will show in 'maint info breakpoints'.
      
      As GDB prints the breakpoint, the thread-id for the breakpoint is
      printed as part of the 'stop only in thread ...' line.  Printing the
      thread-id involves calling find_thread_global_id to convert the global
      thread-id into a thread_info*.  Then calling print_thread_id to
      convert the thread_info* into a string.
      
      The problem is that find_thread_global_id returns nullptr as the
      thread for the thread-specific breakpoint has exited.  The
      print_thread_id assumes it will be passed a non-nullptr.  As a result
      GDB crashes.
      
      In this commit I've added an assert to print_thread_id (gdb/thread.c)
      to check that the pointed passed in is not nullptr.  This assert would
      have triggered in the above case before GDB crashed.
      
      MI Notifications: The Dangers Of Changing A Breakpoint's Number
      ---------------------------------------------------------------
      
      Currently the delete_breakpoint function doesn't trigger the
      breakpoint_deleted observer for any breakpoint with the number zero.
      
      There is a comment explaining why this is the case in the code; it's
      something about watchpoints.  But I did consider just removing the 'is
      the number zero' guard and always triggering the breakpoint_deleted
      observer, figuring that I'd then fix the watchpoint issue some other
      way.
      
      But I realised this wasn't going to be good enough.  When the MI
      notification was delivered the number would be zero, so any frontend
      parsing the notifications would not be able to match
      =breakpoint-deleted notification to the earlier =breakpoint-created
      notification.
      
      What this means is that, at the point the breakpoint_deleted observer
      is called, the breakpoint's number must be correct.
      
      MI Notifications: The Dangers Of Delaying Deletion
      --------------------------------------------------
      
      The test I used to expose the above crash also brought another problem
      to my attention.  In the above test we used 'continue&' to resume,
      after which a thread exited, but the inferior didn't stop.  Recreating
      the same test in the MI looks like this:
      
        -break-insert -p 2 main
        ^done,bkpt={number="2",type="breakpoint",disp="keep",...<snip>...}
        (gdb)
        -exec-continue
        ^running
        *running,thread-id="all"
        (gdb)
        ~"[Thread 0x7ffff7c5d700 (LWP 987038) exited]\n"
        =thread-exited,id="2",group-id="i1"
        ~"Thread-specific breakpoint 2 deleted - thread 2 no longer in the thread list.\n"
      
      At this point the we have a single thread left, which is still
      running:
      
        -thread-info
        ^done,threads=[{id="1",target-id="Thread 0x7ffff7c5eb80 (LWP 987035)",name="thread-bp-delet",state="running",core="4"}],current-thread-id="1"
        (gdb)
      
      Notice that we got the =thread-exited notification from GDB as soon as
      the thread exited.  We also saw the CLI line from GDB, the line
      explaining that breakpoint 2 was deleted.  But, as expected, we didn't
      see the =breakpoint-deleted notification.
      
      I say "as expected" because the number was set to zero.  But, even if
      the number was not set to zero we still wouldn't see the
      notification.  The MI notification is driven by the breakpoint_deleted
      observer, which is only called when we actually delete the breakpoint,
      which is only done the next time GDB stops.
      
      Now, maybe this is fine.  The notification is delivered a little
      late.  But remember, by setting the number to zero the breakpoint will
      be hidden from the user, for example, the breakpoint is removed from
      the MI's -break-info command output.
      
      This means that GDB is in a position where the breakpoint doesn't show
      up in the breakpoint table, but a =breakpoint-deleted notification has
      not yet been sent out.  This doesn't seem right to me.
      
      What this means is that, when the thread exits, we should immediately
      be sending out the =breakpoint-deleted notification.  We should not
      wait for GDB to next stop before sending the notification.
      
      The Solution
      ------------
      
      My proposed solution is this; in remove_threaded_breakpoints, instead
      of setting the disposition to disp_del_at_next_stop and setting the
      number to zero, we now just call delete_breakpoint directly.
      
      The notification will now be sent out immediately; as soon as the
      thread exits.
      
      As the number has not changed when delete_breakpoint is called, the
      notification will have the correct number.
      
      And as the breakpoint is immediately removed from the breakpoint list,
      we no longer need to worry about 'maint info breakpoints' trying to
      print the thread-id for an exited thread.
      
      My only concern is that calling delete_breakpoint directly seems so
      obvious that I wonder why the original patch (that added
      remove_threaded_breakpoints) didn't take this approach.  This code was
      added in commit 49fa26b0, but the commit message offers no clues
      to why this approach was taken, and the original email thread offers
      no insights either[2].  There are no test regressions after making
      this change, so I'm hopeful that this is going to be fine.
      
      [2] https://sourceware.org/pipermail/gdb-patches/2013-September/106493.html
      
      
      
      The Complication
      ----------------
      
      Of course, it couldn't be that simple.
      
      The script gdb.python/py-finish-breakpoint.exp had some regressions
      during testing.
      
      The problem was with the FinishBreakpoint.out_of_scope callback
      implementation.  This callback is supposed to trigger whenever the
      FinishBreakpoint goes out of scope; and this includes when the thread
      for the breakpoint exits.
      
      The problem I ran into is the Python FinishBreakpoint implementation.
      Specifically, after this change I was loosing some of the out_of_scope
      calls.
      
      The problem is that the out_of_scope call (of which I'm interested) is
      triggered from the inferior_exit observer.  Before my change the
      observers were called in this order:
      
        thread_exit
        inferior_exit
        breakpoint_deleted
      
      The inferior_exit would trigger the out_of_scope call.
      
      After my change the breakpoint_deleted notification (for
      thread-specific breakpoints) occurs earlier, as soon as the
      thread-exits, so now the order is:
      
        thread_exit
        breakpoint_deleted
        inferior_exit
      
      Currently, after the breakpoint_deleted call the Python object
      associated with the breakpoint is released, so, when we get to the
      inferior_exit observer, there's no longer a Python object to call the
      out_of_scope method on.
      
      My solution is to follow the model for how bpfinishpy_pre_stop_hook
      and bpfinishpy_post_stop_hook are called, this is done from
      gdbpy_breakpoint_cond_says_stop in py-breakpoint.c.
      
      I've now added a new bpfinishpy_pre_delete_hook
      gdbpy_breakpoint_deleted in py-breakpoint.c, and from this new hook
      function I check and where needed call the out_of_scope method.
      
      With this fix in place I now see the
      gdb.python/py-finish-breakpoint.exp test fully passing again.
      
      Testing
      -------
      
      Tested on x86-64/Linux with unix, native-gdbserver, and
      native-extended-gdbserver boards.
      
      New tests added to covers all the cases I've discussed above.
      
      Approved-By: default avatarPedro Alves <pedro@palves.net>
      2968b79f
    • Kevin Buettner's avatar
      Python QUIT processing updates · b940a061
      Kevin Buettner authored
      See the previous patches in this series for the motivation behind
      these changes.
      
      This commit contains updates to Python's QUIT handling.  Ideally, we'd
      like to throw gdb_exception_forced_quit through the extension
      language; I made an attempt to do this for gdb_exception_quit in an
      earlier version of this patch, but Pedro pointed out that it is
      (almost certainly) not safe to do so.
      
      Still, we definitely don't want to swallow the exception representing
      a SIGTERM for GDB, nor do we want to force modules written in the
      extension language to have to explicitly handle this case.  Since the
      idea is for GDB to cleanup and quit for this exception, we'll simply
      call quit_force() just as if the gdb_exception_forced_quit propagation
      had managed to make it back to the top level.
      
      Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26761
      
      
      Tested-by: default avatarTom de Vries <tdevries@suse.de>
      Approved-By: default avatarPedro Alves <pedro@palves.net>
      b940a061
  9. Feb 27, 2023
    • Tom Tromey's avatar
      Fix value chain use-after-free · f3d3bbbc
      Tom Tromey authored
      Hannes filed a bug showing a crash, where a pretty-printer written in
      Python could cause a use-after-free.  He sent a patch, but I thought a
      different approach was needed.
      
      In a much earlier patch (see bug #12533), we changed the Python code
      to release new values from the value chain when constructing a
      gdb.Value.  The rationale for this is that if you write a command that
      does a lot of computations in a loop, all the values will be kept live
      by the value chain, resulting in gdb using a large amount of memory.
      
      However, suppose a value is passed to Python from some code in gdb
      that needs to use the value after the call into Python.  In this
      scenario, value_to_value_object will still release the value -- and
      because gdb code doesn't generally keep strong references to values (a
      consequence of the ancient decision to use the value chain to avoid
      memory management), this will result in a use-after-free.
      
      This scenario can happen, as it turns out, when a value is passed to
      Python for pretty-printing.  Now, normally this route boxes the value
      via value_to_value_object_no_release, avoiding the problematic release
      from the value chain.  However, if you then call Value.cast, the
      underlying value API might return the same value, when is then
      released from the chain.
      
      This patch fixes the problem by changing how value boxing is done.
      value_to_value_object no longer removes a value from the chain.
      Instead, every spot in gdb that might construct new values uses a
      scoped_value_mark to ensure that the requirements of bug #12533 are
      met.  And, because incoming values aren't ever released from the chain
      (the Value.cast one comes earlier on the chain than the
      scoped_value_mark), the bug can no longer occur.  (Note that many
      spots in the Python layer already take this approach, so not many
      places needed to be touched.)
      
      In the future I think we should replace the use of raw "value *" with
      value_ref_ptr pretty much everywhere.  This will ensure lifetime
      safety throughout gdb.
      
      The test case in this patch comes from Hannes' original patch.  I only
      made a trivial ("require") change to it.  However, while this fails
      for him, I can't make it fail on this machine; nevertheless, he tried
      my patch and reported the bug as being fixed.
      
      Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30044
      f3d3bbbc
    • Simon Marchi's avatar
      gdb: reformat Python files with black 23.1.0 · 09de95fb
      Simon Marchi authored
      
      Change-Id: Ie8ec8870a16d71c5858f5d08958309d23c318302
      Reviewed-By: default avatarTom Tromey <tom@tromey.com>
      Reviewed-By: default avatarAndrew Burgess <aburgess@redhat.com>
      09de95fb
    • Tankut Baris Aktemur's avatar
      gdb, python: do minor modernization in execute_gdb_command · 4e08903f
      Tankut Baris Aktemur authored
      
      Use nullptr instead of NULL and boolify two local variables in
      execute_gdb_command.
      
      Approved-By: default avatarTom Tromey <tom@tromey.com>
      4e08903f
  10. Feb 19, 2023
  11. Feb 13, 2023
  12. Feb 12, 2023
    • Andrew Burgess's avatar
      gdb: use -1 for breakpoint::task default value · 2ecee236
      Andrew Burgess authored
      
      Within the breakpoint struct we have two fields ::thread and ::task
      which are used for thread or task specific breakpoints.  When a
      breakpoint doesn't have a specific thread or task then these fields
      have the values -1 and 0 respectively.
      
      There's no particular reason (as far as I can tell) why these two
      "default" values are different, and I find the difference a little
      confusing.  Long term I'd like to potentially fold these two fields
      into a single field, but that isn't what this commit does.
      
      What this commit does is switch to using -1 as the "default" value for
      both fields, this means that the default for breakpoint::task has
      changed from 0 to -1.   I've updated all the code I can find that
      relied on the value of 0, and I see no test regressions, especially in
      gdb.ada/tasks.exp, which still fully passes.
      
      There should be no user visible changes after this commit.
      
      Approved-By: default avatarPedro Alves <pedro@palves.net>
      2ecee236
    • Andrew Burgess's avatar
      gdb: only allow one of thread or task on breakpoints or watchpoints · 0a9ccb9d
      Andrew Burgess authored
      After this mailing list posting:
      
        https://sourceware.org/pipermail/gdb-patches/2023-February/196607.html
      
      
      
      it seems to me that in practice an Ada task maps 1:1 with a GDB
      thread, and so it doesn't really make sense to allow uses to give both
      a thread and a task within a single breakpoint or watchpoint
      condition.
      
      This commit updates GDB so that the user will get an error if both
      are specified.
      
      I've added new tests to cover the CLI as well as the Python and Guile
      APIs.  For the Python and Guile testing, as far as I can tell, this
      was the first testing for this corner of the APIs, so I ended up
      adding more than just a single test.
      
      For documentation I've added a NEWS entry, but I've not added anything
      to the docs themselves.  Currently we document the commands with a
      thread-id or task-id as distinct command, e.g.:
      
        'break LOCSPEC task TASKNO'
        'break LOCSPEC task TASKNO if ...'
        'break LOCSPEC thread THREAD-ID'
        'break LOCSPEC thread THREAD-ID if ...'
      
      As such, I don't believe there is any indication that combining 'task'
      and 'thread' would be expected to work; it seems clear to me in the
      above that those four options are all distinct commands.
      
      I think the NEWS entry is enough that if someone is combining these
      keywords (it's not clear what the expected behaviour would be in this
      case) then they can figure out that this was a deliberate change in
      GDB, but for a new user, the manual doesn't suggest combining them is
      OK, and any future attempt to combine them will give an error.
      
      Approved-By: default avatarPedro Alves <pedro@palves.net>
      0a9ccb9d
  13. Feb 10, 2023
    • Tom Tromey's avatar
      Ensure all DAP requests are keyword-only · 5036bde9
      Tom Tromey authored
      Python functions implementing DAP requests should not use positional
      parameters -- it only makes sense to call them with keyword arguments.
      This patch changes the few remaining cases to start with the special
      "*" parameter, following this rule.
      
      5036bde9
  14. Feb 08, 2023
    • Pedro Alves's avatar
      Simplify interp::exec / interp_exec - let exceptions propagate · b885aea1
      Pedro Alves authored
      This patch implements a simplication that I suggested here:
      
        https://sourceware.org/pipermail/gdb-patches/2022-March/186320.html
      
      
      
      Currently, the interp::exec virtual method interface is such that
      subclass implementations must catch exceptions and then return them
      via normal function return.
      
      However, higher up the in chain, for the CLI we get to
      interpreter_exec_cmd, which does:
      
        for (i = 1; i < nrules; i++)
          {
            struct gdb_exception e = interp_exec (interp_to_use, prules[i]);
      
            if (e.reason < 0)
      	{
      	  interp_set (old_interp, 0);
      	  error (_("error in command: \"%s\"."), prules[i]);
      	}
          }
      
      and for MI we get to mi_cmd_interpreter_exec, which has:
      
        void
        mi_cmd_interpreter_exec (const char *command, char **argv, int argc)
        {
        ...
          for (i = 1; i < argc; i++)
            {
      	struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
      
      	if (e.reason < 0)
      	  error ("%s", e.what ());
            }
        }
      
      Note that if those errors are reached, we lose the original
      exception's error code.  I can't see why we'd want that.
      
      And, I can't see why we need to have interp_exec catch the exception
      and return it via the normal return path.  That's normally needed when
      we need to handle propagating exceptions across C code, like across
      readline or ncurses, but that's not the case here.
      
      It seems to me that we can simplify things by removing some
      try/catch-ing and just letting exceptions propagate normally.
      
      Note, the "error in command" error shown above, which only exists in
      the CLI interpreter-exec command, is only ever printed AFAICS if you
      run "interpreter-exec console" when the top level interpreter is
      already the console/tui.  Like:
      
       (gdb) interpreter-exec console "foobar"
       Undefined command: "foobar".  Try "help".
       error in command: "foobar".
      
      You won't see it with MI's "-interpreter-exec console" from a top
      level MI interpreter:
      
       (gdb)
       -interpreter-exec console "foobar"
       &"Undefined command: \"foobar\".  Try \"help\".\n"
       ^error,msg="Undefined command: \"foobar\".  Try \"help\"."
       (gdb)
      
      nor with MI's "-interpreter-exec mi" from a top level MI interpreter:
      
       (gdb)
       -interpreter-exec mi "-foobar"
       ^error,msg="Undefined MI command: foobar",code="undefined-command"
       ^done
       (gdb)
      
      in both these cases because MI's -interpreter-exec just does:
      
        error ("%s", e.what ());
      
      You won't see it either when running an MI command with the CLI's
      "interpreter-exec mi":
      
       (gdb) interpreter-exec mi "-foobar"
       ^error,msg="Undefined MI command: foobar",code="undefined-command"
       (gdb)
      
      This last case is because MI's interp::exec implementation never
      returns an error:
      
       gdb_exception
       mi_interp::exec (const char *command)
       {
         mi_execute_command_wrapper (command);
         return gdb_exception ();
       }
      
      Thus I think that "error in command" error is pretty pointless, and
      since it simplifies things to not have it, the patch just removes it.
      
      The patch also ends up addressing an old FIXME.
      
      Change-Id: I5a6432a80496934ac7127594c53bf5221622e393
      Approved-By: default avatarTom Tromey <tromey@adacore.com>
      Approved-By: default avatarKevin Buettner <kevinb@redhat.com>
      b885aea1
  15. Jan 20, 2023
    • Simon Marchi's avatar
      gdb: remove language.h include from frame.h · 83b6e1f1
      Simon Marchi authored
      
      This helps resolve some cyclic include problem later in the series.
      The only language-related thing frame.h needs is enum language, and that
      is in defs.h.
      
      Doing so reveals that a bunch of files were relying on frame.h to
      include language.h, so fix the fallouts here and there.
      
      Change-Id: I178a7efec1953c2d088adb58483bade1f349b705
      Reviewed-By: default avatarBruno Larsen <blarsen@redhat.com>
      83b6e1f1
  16. Jan 19, 2023
    • Andrew Burgess's avatar
      GDB: Add a character string limiting option · 76b58849
      Andrew Burgess authored
      
      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: default avatarMaciej W. Rozycki <macro@embecosm.com>
      Approved-By: default avatarSimon Marchi <simon.marchi@efficios.com>
      76b58849
    • Maciej W. Rozycki's avatar
      GDB: Allow arbitrary keywords in integer set commands · 7aeb03e2
      Maciej W. Rozycki authored
      
      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: default avatarSimon Marchi <simon.marchi@efficios.com>
      7aeb03e2
Loading