1 # GDB 'explore' command.
2 # Copyright (C) 2012-2018 Free Software Foundation, Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 """Implementation of the GDB 'explore' command using the GDB Python API."""
22 if sys
.version_info
[0] > 2:
23 # Python 3 renamed raw_input to input
26 class Explorer(object):
27 """Internal class which invokes other explorers."""
29 # This map is filled by the Explorer.init_env() function
30 type_code_to_explorer_map
= { }
46 if expr
[0] == '(' and expr
[length
-1] == ')':
52 if (c
== '_' or ('a' <= c
and c
<= 'z') or
53 ('A' <= c
and c
<= 'Z') or ('0' <= c
and c
<= '9')):
61 return "(" + expr
+ ")"
66 def explore_expr(expr
, value
, is_child
):
67 """Main function to explore an expression value.
70 expr: The expression string that is being explored.
71 value: The gdb.Value value of the expression.
72 is_child: Boolean value to indicate if the expression is a child.
73 An expression is a child if it is derived from the main
74 expression entered by the user. For example, if the user
75 entered an expression which evaluates to a struct, then
76 when exploring the fields of the struct, is_child is set
82 type_code
= value
.type.code
83 if type_code
in Explorer
.type_code_to_explorer_map
:
84 explorer_class
= Explorer
.type_code_to_explorer_map
[type_code
]
85 while explorer_class
.explore_expr(expr
, value
, is_child
):
88 print ("Explorer for type '%s' not yet available.\n" %
92 def explore_type(name
, datatype
, is_child
):
93 """Main function to explore a data type.
96 name: The string representing the path to the data type being
98 datatype: The gdb.Type value of the data type being explored.
99 is_child: Boolean value to indicate if the name is a child.
100 A name is a child if it is derived from the main name
101 entered by the user. For example, if the user entered
102 the name of struct type, then when exploring the fields
103 of the struct, is_child is set to True internally.
108 type_code
= datatype
.code
109 if type_code
in Explorer
.type_code_to_explorer_map
:
110 explorer_class
= Explorer
.type_code_to_explorer_map
[type_code
]
111 while explorer_class
.explore_type(name
, datatype
, is_child
):
114 print ("Explorer for type '%s' not yet available.\n" %
119 """Initializes the Explorer environment.
120 This function should be invoked before starting any exploration. If
121 invoked before an exploration, it need not be invoked for subsequent
124 Explorer
.type_code_to_explorer_map
= {
125 gdb
.TYPE_CODE_CHAR
: ScalarExplorer
,
126 gdb
.TYPE_CODE_INT
: ScalarExplorer
,
127 gdb
.TYPE_CODE_BOOL
: ScalarExplorer
,
128 gdb
.TYPE_CODE_FLT
: ScalarExplorer
,
129 gdb
.TYPE_CODE_VOID
: ScalarExplorer
,
130 gdb
.TYPE_CODE_ENUM
: ScalarExplorer
,
131 gdb
.TYPE_CODE_STRUCT
: CompoundExplorer
,
132 gdb
.TYPE_CODE_UNION
: CompoundExplorer
,
133 gdb
.TYPE_CODE_PTR
: PointerExplorer
,
134 gdb
.TYPE_CODE_REF
: ReferenceExplorer
,
135 gdb
.TYPE_CODE_RVALUE_REF
: ReferenceExplorer
,
136 gdb
.TYPE_CODE_TYPEDEF
: TypedefExplorer
,
137 gdb
.TYPE_CODE_ARRAY
: ArrayExplorer
141 def is_scalar_type(type):
142 """Checks whether a type is a scalar type.
143 A type is a scalar type of its type is
144 gdb.TYPE_CODE_CHAR or
146 gdb.TYPE_CODE_BOOL or
148 gdb.TYPE_CODE_VOID or
152 type: The type to be checked.
155 'True' if 'type' is a scalar type. 'False' otherwise.
157 return type.code
in Explorer
._SCALAR
_TYPE
_LIST
160 def return_to_parent_value():
161 """A utility function which prints that the current exploration session
162 is returning to the parent value. Useful when exploring values.
164 print ("\nReturning to parent value...\n")
167 def return_to_parent_value_prompt():
168 """A utility function which prompts the user to press the 'enter' key
169 so that the exploration session can shift back to the parent value.
170 Useful when exploring values.
172 raw_input("\nPress enter to return to parent value: ")
175 def return_to_enclosing_type():
176 """A utility function which prints that the current exploration session
177 is returning to the enclosing type. Useful when exploring types.
179 print ("\nReturning to enclosing type...\n")
182 def return_to_enclosing_type_prompt():
183 """A utility function which prompts the user to press the 'enter' key
184 so that the exploration session can shift back to the enclosing type.
185 Useful when exploring types.
187 raw_input("\nPress enter to return to enclosing type: ")
190 class ScalarExplorer(object):
191 """Internal class used to explore scalar values."""
194 def explore_expr(expr
, value
, is_child
):
195 """Function to explore scalar values.
196 See Explorer.explore_expr and Explorer.is_scalar_type for more
199 print ("'%s' is a scalar value of type '%s'." %
201 print ("%s = %s" % (expr
, str(value
)))
204 Explorer
.return_to_parent_value_prompt()
205 Explorer
.return_to_parent_value()
210 def explore_type(name
, datatype
, is_child
):
211 """Function to explore scalar types.
212 See Explorer.explore_type and Explorer.is_scalar_type for more
215 if datatype
.code
== gdb
.TYPE_CODE_ENUM
:
217 print ("%s is of an enumerated type '%s'." %
218 (name
, str(datatype
)))
220 print ("'%s' is an enumerated type." % name
)
223 print ("%s is of a scalar type '%s'." %
224 (name
, str(datatype
)))
226 print ("'%s' is a scalar type." % name
)
229 Explorer
.return_to_enclosing_type_prompt()
230 Explorer
.return_to_enclosing_type()
235 class PointerExplorer(object):
236 """Internal class used to explore pointer values."""
239 def explore_expr(expr
, value
, is_child
):
240 """Function to explore pointer values.
241 See Explorer.explore_expr for more information.
243 print ("'%s' is a pointer to a value of type '%s'" %
244 (expr
, str(value
.type.target())))
245 option
= raw_input("Continue exploring it as a pointer to a single "
250 deref_value
= value
.dereference()
252 except gdb
.MemoryError:
253 print ("'%s' a pointer pointing to an invalid memory "
256 Explorer
.return_to_parent_value_prompt()
258 Explorer
.explore_expr("*%s" % Explorer
.guard_expr(expr
),
259 deref_value
, is_child
)
262 option
= raw_input("Continue exploring it as a pointer to an "
268 index
= int(raw_input("Enter the index of the element you "
269 "want to explore in '%s': " % expr
))
272 element_expr
= "%s[%d]" % (Explorer
.guard_expr(expr
), index
)
273 element
= value
[index
]
276 except gdb
.MemoryError:
277 print ("Cannot read value at index %d." % index
)
279 Explorer
.explore_expr(element_expr
, element
, True)
283 Explorer
.return_to_parent_value()
287 def explore_type(name
, datatype
, is_child
):
288 """Function to explore pointer types.
289 See Explorer.explore_type for more information.
291 target_type
= datatype
.target()
292 print ("\n%s is a pointer to a value of type '%s'." %
293 (name
, str(target_type
)))
295 Explorer
.explore_type("the pointee type of %s" % name
,
301 class ReferenceExplorer(object):
302 """Internal class used to explore reference (TYPE_CODE_REF) values."""
305 def explore_expr(expr
, value
, is_child
):
306 """Function to explore array values.
307 See Explorer.explore_expr for more information.
309 referenced_value
= value
.referenced_value()
310 Explorer
.explore_expr(expr
, referenced_value
, is_child
)
314 def explore_type(name
, datatype
, is_child
):
315 """Function to explore pointer types.
316 See Explorer.explore_type for more information.
318 target_type
= datatype
.target()
319 Explorer
.explore_type(name
, target_type
, is_child
)
322 class ArrayExplorer(object):
323 """Internal class used to explore arrays."""
326 def explore_expr(expr
, value
, is_child
):
327 """Function to explore array values.
328 See Explorer.explore_expr for more information.
330 target_type
= value
.type.target()
331 print ("'%s' is an array of '%s'." % (expr
, str(target_type
)))
334 index
= int(raw_input("Enter the index of the element you want to "
335 "explore in '%s': " % expr
))
338 Explorer
.return_to_parent_value()
343 element
= value
[index
]
345 except gdb
.MemoryError:
346 print ("Cannot read value at index %d." % index
)
347 raw_input("Press enter to continue... ")
350 Explorer
.explore_expr("%s[%d]" % (Explorer
.guard_expr(expr
), index
),
355 def explore_type(name
, datatype
, is_child
):
356 """Function to explore array types.
357 See Explorer.explore_type for more information.
359 target_type
= datatype
.target()
360 print ("%s is an array of '%s'." % (name
, str(target_type
)))
362 Explorer
.explore_type("the array element of %s" % name
, target_type
,
367 class CompoundExplorer(object):
368 """Internal class used to explore struct, classes and unions."""
371 def _print_fields(print_list
):
372 """Internal function which prints the fields of a struct/class/union.
374 max_field_name_length
= 0
375 for pair
in print_list
:
376 if max_field_name_length
< len(pair
[0]):
377 max_field_name_length
= len(pair
[0])
379 for pair
in print_list
:
380 print (" %*s = %s" % (max_field_name_length
, pair
[0], pair
[1]))
383 def _get_real_field_count(fields
):
384 real_field_count
= 0;
386 if not field
.artificial
:
387 real_field_count
= real_field_count
+ 1
389 return real_field_count
392 def explore_expr(expr
, value
, is_child
):
393 """Function to explore structs/classes and union values.
394 See Explorer.explore_expr for more information.
396 datatype
= value
.type
397 type_code
= datatype
.code
398 fields
= datatype
.fields()
400 if type_code
== gdb
.TYPE_CODE_STRUCT
:
401 type_desc
= "struct/class"
405 if CompoundExplorer
._get
_real
_field
_count
(fields
) == 0:
406 print ("The value of '%s' is a %s of type '%s' with no fields." %
407 (expr
, type_desc
, str(value
.type)))
409 Explorer
.return_to_parent_value_prompt()
412 print ("The value of '%s' is a %s of type '%s' with the following "
413 "fields:\n" % (expr
, type_desc
, str(value
.type)))
415 has_explorable_fields
= False
416 choice_to_compound_field_map
= { }
422 field_full_name
= Explorer
.guard_expr(expr
) + "." + field
.name
423 if field
.is_base_class
:
424 field_value
= value
.cast(field
.type)
426 field_value
= value
[field
.name
]
428 if type_code
== gdb
.TYPE_CODE_UNION
:
429 literal_value
= ("<Enter %d to explore this field of type "
430 "'%s'>" % (current_choice
, str(field
.type)))
431 has_explorable_fields
= True
433 if Explorer
.is_scalar_type(field
.type):
434 literal_value
= ("%s .. (Value of type '%s')" %
435 (str(field_value
), str(field
.type)))
437 if field
.is_base_class
:
438 field_desc
= "base class"
441 literal_value
= ("<Enter %d to explore this %s of type "
443 (current_choice
, field_desc
,
445 has_explorable_fields
= True
447 choice_to_compound_field_map
[str(current_choice
)] = (
448 field_full_name
, field_value
)
449 current_choice
= current_choice
+ 1
451 print_list
.append((field
.name
, literal_value
))
453 CompoundExplorer
._print
_fields
(print_list
)
456 if has_explorable_fields
:
457 choice
= raw_input("Enter the field number of choice: ")
458 if choice
in choice_to_compound_field_map
:
459 Explorer
.explore_expr(choice_to_compound_field_map
[choice
][0],
460 choice_to_compound_field_map
[choice
][1],
465 Explorer
.return_to_parent_value()
468 Explorer
.return_to_parent_value_prompt()
473 def explore_type(name
, datatype
, is_child
):
474 """Function to explore struct/class and union types.
475 See Explorer.explore_type for more information.
477 type_code
= datatype
.code
479 if type_code
== gdb
.TYPE_CODE_STRUCT
:
480 type_desc
= "struct/class"
484 fields
= datatype
.fields()
485 if CompoundExplorer
._get
_real
_field
_count
(fields
) == 0:
487 print ("%s is a %s of type '%s' with no fields." %
488 (name
, type_desc
, str(datatype
)))
489 Explorer
.return_to_enclosing_type_prompt()
491 print ("'%s' is a %s with no fields." % (name
, type_desc
))
495 print ("%s is a %s of type '%s' "
496 "with the following fields:\n" %
497 (name
, type_desc
, str(datatype
)))
499 print ("'%s' is a %s with the following "
503 has_explorable_fields
= False
505 choice_to_compound_field_map
= { }
510 if field
.is_base_class
:
511 field_desc
= "base class"
514 rhs
= ("<Enter %d to explore this %s of type '%s'>" %
515 (current_choice
, field_desc
, str(field
.type)))
516 print_list
.append((field
.name
, rhs
))
517 choice_to_compound_field_map
[str(current_choice
)] = (
518 field
.name
, field
.type, field_desc
)
519 current_choice
= current_choice
+ 1
521 CompoundExplorer
._print
_fields
(print_list
)
524 if len(choice_to_compound_field_map
) > 0:
525 choice
= raw_input("Enter the field number of choice: ")
526 if choice
in choice_to_compound_field_map
:
528 new_name
= ("%s '%s' of %s" %
529 (choice_to_compound_field_map
[choice
][2],
530 choice_to_compound_field_map
[choice
][0],
533 new_name
= ("%s '%s' of '%s'" %
534 (choice_to_compound_field_map
[choice
][2],
535 choice_to_compound_field_map
[choice
][0],
537 Explorer
.explore_type(new_name
,
538 choice_to_compound_field_map
[choice
][1], True)
542 Explorer
.return_to_enclosing_type()
545 Explorer
.return_to_enclosing_type_prompt()
550 class TypedefExplorer(object):
551 """Internal class used to explore values whose type is a typedef."""
554 def explore_expr(expr
, value
, is_child
):
555 """Function to explore typedef values.
556 See Explorer.explore_expr for more information.
558 actual_type
= value
.type.strip_typedefs()
559 print ("The value of '%s' is of type '%s' "
560 "which is a typedef of type '%s'" %
561 (expr
, str(value
.type), str(actual_type
)))
563 Explorer
.explore_expr(expr
, value
.cast(actual_type
), is_child
)
567 def explore_type(name
, datatype
, is_child
):
568 """Function to explore typedef types.
569 See Explorer.explore_type for more information.
571 actual_type
= datatype
.strip_typedefs()
573 print ("The type of %s is a typedef of type '%s'." %
574 (name
, str(actual_type
)))
576 print ("The type '%s' is a typedef of type '%s'." %
577 (name
, str(actual_type
)))
579 Explorer
.explore_type(name
, actual_type
, is_child
)
583 class ExploreUtils(object):
584 """Internal class which provides utilities for the main command classes."""
587 def check_args(name
, arg_str
):
588 """Utility to check if adequate number of arguments are passed to an
592 name: The name of the explore command.
593 arg_str: The argument string passed to the explore command.
596 True if adequate arguments are passed, false otherwise.
599 gdb.GdbError if adequate arguments are not passed.
602 raise gdb
.GdbError("ERROR: '%s' requires an argument."
609 def get_type_from_str(type_str
):
610 """A utility function to deduce the gdb.Type value from a string
611 representing the type.
614 type_str: The type string from which the gdb.Type value should be
618 The deduced gdb.Type value if possible, None otherwise.
621 # Assume the current language to be C/C++ and make a try.
622 return gdb
.parse_and_eval("(%s *)0" % type_str
).type.target()
624 # If assumption of current language to be C/C++ was wrong, then
625 # lookup the type using the API.
627 return gdb
.lookup_type(type_str
)
632 def get_value_from_str(value_str
):
633 """A utility function to deduce the gdb.Value value from a string
634 representing the value.
637 value_str: The value string from which the gdb.Value value should
641 The deduced gdb.Value value if possible, None otherwise.
644 return gdb
.parse_and_eval(value_str
)
649 class ExploreCommand(gdb
.Command
):
650 """Explore a value or a type valid in the current context.
656 - ARG is either a valid expression or a type name.
657 - At any stage of exploration, hit the return key (instead of a
658 choice, if any) to return to the enclosing type or value.
662 super(ExploreCommand
, self
).__init
__(name
= "explore",
663 command_class
= gdb
.COMMAND_DATA
,
666 def invoke(self
, arg_str
, from_tty
):
667 if ExploreUtils
.check_args("explore", arg_str
) == False:
670 # Check if it is a value
671 value
= ExploreUtils
.get_value_from_str(arg_str
)
672 if value
is not None:
673 Explorer
.explore_expr(arg_str
, value
, False)
676 # If it is not a value, check if it is a type
677 datatype
= ExploreUtils
.get_type_from_str(arg_str
)
678 if datatype
is not None:
679 Explorer
.explore_type(arg_str
, datatype
, False)
682 # If it is neither a value nor a type, raise an error.
684 ("'%s' neither evaluates to a value nor is a type "
685 "in the current context." %
689 class ExploreValueCommand(gdb
.Command
):
690 """Explore value of an expression valid in the current context.
696 - ARG is a valid expression.
697 - At any stage of exploration, hit the return key (instead of a
698 choice, if any) to return to the enclosing value.
702 super(ExploreValueCommand
, self
).__init
__(
703 name
= "explore value", command_class
= gdb
.COMMAND_DATA
)
705 def invoke(self
, arg_str
, from_tty
):
706 if ExploreUtils
.check_args("explore value", arg_str
) == False:
709 value
= ExploreUtils
.get_value_from_str(arg_str
)
712 (" '%s' does not evaluate to a value in the current "
717 Explorer
.explore_expr(arg_str
, value
, False)
720 class ExploreTypeCommand(gdb
.Command
):
721 """Explore a type or the type of an expression valid in the current
728 - ARG is a valid expression or a type name.
729 - At any stage of exploration, hit the return key (instead of a
730 choice, if any) to return to the enclosing type.
734 super(ExploreTypeCommand
, self
).__init
__(
735 name
= "explore type", command_class
= gdb
.COMMAND_DATA
)
737 def invoke(self
, arg_str
, from_tty
):
738 if ExploreUtils
.check_args("explore type", arg_str
) == False:
741 datatype
= ExploreUtils
.get_type_from_str(arg_str
)
742 if datatype
is not None:
743 Explorer
.explore_type(arg_str
, datatype
, False)
746 value
= ExploreUtils
.get_value_from_str(arg_str
)
747 if value
is not None:
748 print ("'%s' is of type '%s'." % (arg_str
, str(value
.type)))
749 Explorer
.explore_type(str(value
.type), value
.type, False)
752 raise gdb
.GdbError(("'%s' is not a type or value in the current "
753 "context." % arg_str
))
759 ExploreValueCommand()