bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#34589: 26.1.91; GDB-MI Display Complex Data Types


From: Lars Ingebrigtsen
Subject: bug#34589: 26.1.91; GDB-MI Display Complex Data Types
Date: Wed, 30 Sep 2020 20:08:24 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

Gustaf Waldemarson <gustaf.waldemarson@gmail.com> writes:

> After quite some time here, I have finally been able to get the proper
> legal confirmation from Arm to submit patches. As far as I understand
> things, any patch that I submit for Emacs will now have the copyright
> correctly reassigned and should now be usable without any issues.

Great!  Your patch didn't apply cleanly to Emacs 28, so I've respun it
(included below).

There was unfortunately no followup on this at the time, and I'm not
exactly a gdb expert (cough cough).

Could somebody give this a look-over?  It looks good to me, but I
haven't tested it.

> That said, during these months I've been rethinking the variable GDB
> window somewhat, and would like to see what people thinks of a rework of
> the following kind:
>
> - Instead of displaying variables as | 'type' | 'name' | 'value' |,
>   display them as | 'name' | 'short-type' | 'value' |, where
>   'short-type' is the first `X' characters of the type name.
>
>   I personally find this to be more useful, especially for C++ template
>   types which can easily occupy the whole window otherwise.
>
> - Possibly add a new tab 'behind' the variable window which contains the
>   /full/ type name. (This part may also have to interface with the new
>   tabbing interface, something I'll have to look into when I've got some
>   time.)
>
> (Also, if interesting, should this kind of rework be submitted as a
> separate ticket?)

Sure, a separate ticket would be nice.


diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 086f0b6a08..49ec99fc32 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -4228,7 +4228,7 @@ gdb-select-frame
 ;; uses "-stack-list-locals --simple-values". Needs GDB 6.1 onwards.
 (def-gdb-trigger-and-handler
   gdb-invalidate-locals
-  (concat (gdb-current-context-command "-stack-list-locals")
+  (concat (gdb-current-context-command "-stack-list-variables")
           " --simple-values")
   gdb-locals-handler gdb-locals-handler-custom
   '(start update))
@@ -4239,6 +4239,48 @@ gdb-select-frame
  'gdb-locals-mode
  'gdb-invalidate-locals)
 
+
+;; Retrieve the values of all variables before invalidating locals.
+(def-gdb-trigger-and-handler
+  gdb-locals-values
+  (concat (gdb-current-context-command "-stack-list-variables")
+          " --all-values")
+  gdb-locals-values-handler gdb-locals-values-handler-custom
+  '(start update))
+
+(gdb-set-buffer-rules
+ 'gdb-locals-values-buffer
+ 'gdb-locals-values-buffer-name
+ 'gdb-locals-mode
+ 'gdb-locals-values)
+
+(defun gdb-locals-values-buffer-name ()
+  (gdb-current-context-buffer-name
+   (concat "local values of " (gdb-get-target-string))))
+
+(defcustom gdb-locals-simple-values-only nil
+  "Only display simple values in the Locals buffer."
+  :type 'boolean
+  :group 'gud
+  :version "28.1")
+
+(defcustom gdb-locals-value-limit 100
+  "Maximum length the value of a local variable is allowed to be."
+  :type 'integer
+  :group 'gud
+  :version "28.1")
+
+(defvar gdb-locals-values-table (make-hash-table :test #'equal)
+  "Mapping of local variable names to a string with their value.")
+
+(defun gdb-locals-values-handler-custom ()
+  "Store the values of local variables in `gdb-locals-value-map'."
+  (let ((locals-list (bindat-get-field (gdb-json-partial-output) 'variables)))
+    (dolist (local locals-list)
+      (let ((name (bindat-get-field local 'name))
+            (value (bindat-get-field local 'value)))
+        (puthash name value gdb-locals-values-table)))))
+
 (defvar gdb-locals-watch-map
   (let ((map (make-sparse-keymap)))
     (suppress-keymap map)
@@ -4255,6 +4297,15 @@ gdb-edit-locals-map-1
     map)
   "Keymap to edit value of a simple data type local variable.")
 
+(defun gdb-locals-value-filter (value)
+  "Filter function for the local variable VALUE."
+  (let* ((no-nl (replace-regexp-in-string "\n" " " value))
+         (str (replace-regexp-in-string "[[:space:]]+" " " no-nl))
+         (limit gdb-locals-value-limit))
+    (if (>= (length str) limit)
+        (concat (substring str 0 limit) "...")
+      str)))
+
 (defun gdb-edit-locals-value (&optional event)
   "Assign a value to a variable displayed in the locals buffer."
   (interactive (list last-input-event))
@@ -4267,17 +4318,21 @@ gdb-edit-locals-value
       (gud-basic-call
        (concat  "-gdb-set variable " var " = " value)))))
 
-;; Don't display values of arrays or structures.
-;; These can be expanded using gud-watch.
+;; Complex data types are looked up in `gdb-locals-values-table'.
 (defun gdb-locals-handler-custom ()
-  (let ((locals-list (bindat-get-field (gdb-json-partial-output) 'locals))
+  "Handler to rebuild the local variables table buffer."
+  (let ((locals-list (bindat-get-field (gdb-json-partial-output) 'variables))
         (table (make-gdb-table)))
     (dolist (local locals-list)
       (let ((name (bindat-get-field local 'name))
             (value (bindat-get-field local 'value))
             (type (bindat-get-field local 'type)))
         (when (not value)
-          (setq value "<complex data type>"))
+          (setq value
+                (if gdb-locals-simple-values-only
+                    "<complex data type>"
+                  (gethash name gdb-locals-values-table "<unavailable>"))))
+        (setq value (gdb-locals-value-filter value))
         (if (or (not value)
                 (string-match "0x" value))
             (add-text-properties 0 (length name)
@@ -4743,6 +4798,8 @@ gdb-setup-windows
          (expand-file-name gdb-default-window-configuration-file
                            gdb-window-configuration-directory)))
     ;; Create default layout as before.
+    ;; Make sure that local values are updated before locals.
+    (gdb-get-buffer-create 'gdb-locals-values-buffer)
     (gdb-get-buffer-create 'gdb-locals-buffer)
     (gdb-get-buffer-create 'gdb-stack-buffer)
     (gdb-get-buffer-create 'gdb-breakpoints-buffer)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





reply via email to

[Prev in Thread] Current Thread [Next in Thread]