Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / gdb / python / lib / gdb / command / explore.py
1 # GDB 'explore' command.
2 # Copyright (C) 2012-2022 Free Software Foundation, Inc.
3
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.
8 #
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.
13 #
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/>.
16
17 """Implementation of the GDB 'explore' command using the GDB Python API."""
18
19 import gdb
20 import sys
21
22 if sys.version_info[0] > 2:
23 # Python 3 renamed raw_input to input
24 raw_input = input
25
26
27 class Explorer(object):
28 """Internal class which invokes other explorers."""
29
30 # This map is filled by the Explorer.init_env() function
31 type_code_to_explorer_map = {}
32
33 _SCALAR_TYPE_LIST = (
34 gdb.TYPE_CODE_CHAR,
35 gdb.TYPE_CODE_INT,
36 gdb.TYPE_CODE_BOOL,
37 gdb.TYPE_CODE_FLT,
38 gdb.TYPE_CODE_VOID,
39 gdb.TYPE_CODE_ENUM,
40 )
41
42 @staticmethod
43 def guard_expr(expr):
44 length = len(expr)
45 guard = False
46
47 if expr[0] == "(" and expr[length - 1] == ")":
48 pass
49 else:
50 i = 0
51 while i < length:
52 c = expr[i]
53 if (
54 c == "_"
55 or ("a" <= c and c <= "z")
56 or ("A" <= c and c <= "Z")
57 or ("0" <= c and c <= "9")
58 ):
59 pass
60 else:
61 guard = True
62 break
63 i += 1
64
65 if guard:
66 return "(" + expr + ")"
67 else:
68 return expr
69
70 @staticmethod
71 def explore_expr(expr, value, is_child):
72 """Main function to explore an expression value.
73
74 Arguments:
75 expr: The expression string that is being explored.
76 value: The gdb.Value value of the expression.
77 is_child: Boolean value to indicate if the expression is a child.
78 An expression is a child if it is derived from the main
79 expression entered by the user. For example, if the user
80 entered an expression which evaluates to a struct, then
81 when exploring the fields of the struct, is_child is set
82 to True internally.
83
84 Returns:
85 No return value.
86 """
87 type_code = value.type.code
88 if type_code in Explorer.type_code_to_explorer_map:
89 explorer_class = Explorer.type_code_to_explorer_map[type_code]
90 while explorer_class.explore_expr(expr, value, is_child):
91 pass
92 else:
93 print("Explorer for type '%s' not yet available.\n" % str(value.type))
94
95 @staticmethod
96 def explore_type(name, datatype, is_child):
97 """Main function to explore a data type.
98
99 Arguments:
100 name: The string representing the path to the data type being
101 explored.
102 datatype: The gdb.Type value of the data type being explored.
103 is_child: Boolean value to indicate if the name is a child.
104 A name is a child if it is derived from the main name
105 entered by the user. For example, if the user entered
106 the name of struct type, then when exploring the fields
107 of the struct, is_child is set to True internally.
108
109 Returns:
110 No return value.
111 """
112 type_code = datatype.code
113 if type_code in Explorer.type_code_to_explorer_map:
114 explorer_class = Explorer.type_code_to_explorer_map[type_code]
115 while explorer_class.explore_type(name, datatype, is_child):
116 pass
117 else:
118 print("Explorer for type '%s' not yet available.\n" % str(datatype))
119
120 @staticmethod
121 def init_env():
122 """Initializes the Explorer environment.
123 This function should be invoked before starting any exploration. If
124 invoked before an exploration, it need not be invoked for subsequent
125 explorations.
126 """
127 Explorer.type_code_to_explorer_map = {
128 gdb.TYPE_CODE_CHAR: ScalarExplorer,
129 gdb.TYPE_CODE_INT: ScalarExplorer,
130 gdb.TYPE_CODE_BOOL: ScalarExplorer,
131 gdb.TYPE_CODE_FLT: ScalarExplorer,
132 gdb.TYPE_CODE_VOID: ScalarExplorer,
133 gdb.TYPE_CODE_ENUM: ScalarExplorer,
134 gdb.TYPE_CODE_STRUCT: CompoundExplorer,
135 gdb.TYPE_CODE_UNION: CompoundExplorer,
136 gdb.TYPE_CODE_PTR: PointerExplorer,
137 gdb.TYPE_CODE_REF: ReferenceExplorer,
138 gdb.TYPE_CODE_RVALUE_REF: ReferenceExplorer,
139 gdb.TYPE_CODE_TYPEDEF: TypedefExplorer,
140 gdb.TYPE_CODE_ARRAY: ArrayExplorer,
141 }
142
143 @staticmethod
144 def is_scalar_type(type):
145 """Checks whether a type is a scalar type.
146 A type is a scalar type of its type is
147 gdb.TYPE_CODE_CHAR or
148 gdb.TYPE_CODE_INT or
149 gdb.TYPE_CODE_BOOL or
150 gdb.TYPE_CODE_FLT or
151 gdb.TYPE_CODE_VOID or
152 gdb.TYPE_CODE_ENUM.
153
154 Arguments:
155 type: The type to be checked.
156
157 Returns:
158 'True' if 'type' is a scalar type. 'False' otherwise.
159 """
160 return type.code in Explorer._SCALAR_TYPE_LIST
161
162 @staticmethod
163 def return_to_parent_value():
164 """A utility function which prints that the current exploration session
165 is returning to the parent value. Useful when exploring values.
166 """
167 print("\nReturning to parent value...\n")
168
169 @staticmethod
170 def return_to_parent_value_prompt():
171 """A utility function which prompts the user to press the 'enter' key
172 so that the exploration session can shift back to the parent value.
173 Useful when exploring values.
174 """
175 raw_input("\nPress enter to return to parent value: ")
176
177 @staticmethod
178 def return_to_enclosing_type():
179 """A utility function which prints that the current exploration session
180 is returning to the enclosing type. Useful when exploring types.
181 """
182 print("\nReturning to enclosing type...\n")
183
184 @staticmethod
185 def return_to_enclosing_type_prompt():
186 """A utility function which prompts the user to press the 'enter' key
187 so that the exploration session can shift back to the enclosing type.
188 Useful when exploring types.
189 """
190 raw_input("\nPress enter to return to enclosing type: ")
191
192
193 class ScalarExplorer(object):
194 """Internal class used to explore scalar values."""
195
196 @staticmethod
197 def explore_expr(expr, value, is_child):
198 """Function to explore scalar values.
199 See Explorer.explore_expr and Explorer.is_scalar_type for more
200 information.
201 """
202 print("'%s' is a scalar value of type '%s'." % (expr, value.type))
203 print("%s = %s" % (expr, str(value)))
204
205 if is_child:
206 Explorer.return_to_parent_value_prompt()
207 Explorer.return_to_parent_value()
208
209 return False
210
211 @staticmethod
212 def explore_type(name, datatype, is_child):
213 """Function to explore scalar types.
214 See Explorer.explore_type and Explorer.is_scalar_type for more
215 information.
216 """
217 if datatype.code == gdb.TYPE_CODE_ENUM:
218 if is_child:
219 print("%s is of an enumerated type '%s'." % (name, str(datatype)))
220 else:
221 print("'%s' is an enumerated type." % name)
222 else:
223 if is_child:
224 print("%s is of a scalar type '%s'." % (name, str(datatype)))
225 else:
226 print("'%s' is a scalar type." % name)
227
228 if is_child:
229 Explorer.return_to_enclosing_type_prompt()
230 Explorer.return_to_enclosing_type()
231
232 return False
233
234
235 class PointerExplorer(object):
236 """Internal class used to explore pointer values."""
237
238 @staticmethod
239 def explore_expr(expr, value, is_child):
240 """Function to explore pointer values.
241 See Explorer.explore_expr for more information.
242 """
243 print(
244 "'%s' is a pointer to a value of type '%s'"
245 % (expr, str(value.type.target()))
246 )
247 option = raw_input(
248 "Continue exploring it as a pointer to a single " "value [y/n]: "
249 )
250 if option == "y":
251 deref_value = None
252 try:
253 deref_value = value.dereference()
254 str(deref_value)
255 except gdb.MemoryError:
256 print(
257 "'%s' a pointer pointing to an invalid memory " "location." % expr
258 )
259 if is_child:
260 Explorer.return_to_parent_value_prompt()
261 return False
262 Explorer.explore_expr(
263 "*%s" % Explorer.guard_expr(expr), deref_value, is_child
264 )
265 return False
266
267 option = raw_input("Continue exploring it as a pointer to an " "array [y/n]: ")
268 if option == "y":
269 while True:
270 index = 0
271 try:
272 index = int(
273 raw_input(
274 "Enter the index of the element you "
275 "want to explore in '%s': " % expr
276 )
277 )
278 except ValueError:
279 break
280 element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index)
281 element = value[index]
282 try:
283 str(element)
284 except gdb.MemoryError:
285 print("Cannot read value at index %d." % index)
286 continue
287 Explorer.explore_expr(element_expr, element, True)
288 return False
289
290 if is_child:
291 Explorer.return_to_parent_value()
292 return False
293
294 @staticmethod
295 def explore_type(name, datatype, is_child):
296 """Function to explore pointer types.
297 See Explorer.explore_type for more information.
298 """
299 target_type = datatype.target()
300 print("\n%s is a pointer to a value of type '%s'." % (name, str(target_type)))
301
302 Explorer.explore_type("the pointee type of %s" % name, target_type, is_child)
303 return False
304
305
306 class ReferenceExplorer(object):
307 """Internal class used to explore reference (TYPE_CODE_REF) values."""
308
309 @staticmethod
310 def explore_expr(expr, value, is_child):
311 """Function to explore array values.
312 See Explorer.explore_expr for more information.
313 """
314 referenced_value = value.referenced_value()
315 Explorer.explore_expr(expr, referenced_value, is_child)
316 return False
317
318 @staticmethod
319 def explore_type(name, datatype, is_child):
320 """Function to explore pointer types.
321 See Explorer.explore_type for more information.
322 """
323 target_type = datatype.target()
324 Explorer.explore_type(name, target_type, is_child)
325 return False
326
327
328 class ArrayExplorer(object):
329 """Internal class used to explore arrays."""
330
331 @staticmethod
332 def explore_expr(expr, value, is_child):
333 """Function to explore array values.
334 See Explorer.explore_expr for more information.
335 """
336 target_type = value.type.target()
337 print("'%s' is an array of '%s'." % (expr, str(target_type)))
338 index = 0
339 try:
340 index = int(
341 raw_input(
342 "Enter the index of the element you want to "
343 "explore in '%s': " % expr
344 )
345 )
346 except ValueError:
347 if is_child:
348 Explorer.return_to_parent_value()
349 return False
350
351 element = None
352 try:
353 element = value[index]
354 str(element)
355 except gdb.MemoryError:
356 print("Cannot read value at index %d." % index)
357 raw_input("Press enter to continue... ")
358 return True
359
360 Explorer.explore_expr(
361 "%s[%d]" % (Explorer.guard_expr(expr), index), element, True
362 )
363 return True
364
365 @staticmethod
366 def explore_type(name, datatype, is_child):
367 """Function to explore array types.
368 See Explorer.explore_type for more information.
369 """
370 target_type = datatype.target()
371 print("%s is an array of '%s'." % (name, str(target_type)))
372
373 Explorer.explore_type("the array element of %s" % name, target_type, is_child)
374 return False
375
376
377 class CompoundExplorer(object):
378 """Internal class used to explore struct, classes and unions."""
379
380 @staticmethod
381 def _print_fields(print_list):
382 """Internal function which prints the fields of a struct/class/union."""
383 max_field_name_length = 0
384 for pair in print_list:
385 if max_field_name_length < len(pair[0]):
386 max_field_name_length = len(pair[0])
387
388 for pair in print_list:
389 print(" %*s = %s" % (max_field_name_length, pair[0], pair[1]))
390
391 @staticmethod
392 def _get_real_field_count(fields):
393 real_field_count = 0
394 for field in fields:
395 if not field.artificial:
396 real_field_count = real_field_count + 1
397
398 return real_field_count
399
400 @staticmethod
401 def explore_expr(expr, value, is_child):
402 """Function to explore structs/classes and union values.
403 See Explorer.explore_expr for more information.
404 """
405 datatype = value.type
406 type_code = datatype.code
407 fields = datatype.fields()
408
409 if type_code == gdb.TYPE_CODE_STRUCT:
410 type_desc = "struct/class"
411 else:
412 type_desc = "union"
413
414 if CompoundExplorer._get_real_field_count(fields) == 0:
415 print(
416 "The value of '%s' is a %s of type '%s' with no fields."
417 % (expr, type_desc, str(value.type))
418 )
419 if is_child:
420 Explorer.return_to_parent_value_prompt()
421 return False
422
423 print(
424 "The value of '%s' is a %s of type '%s' with the following "
425 "fields:\n" % (expr, type_desc, str(value.type))
426 )
427
428 has_explorable_fields = False
429 choice_to_compound_field_map = {}
430 current_choice = 0
431 print_list = []
432 for field in fields:
433 if field.artificial:
434 continue
435 field_full_name = Explorer.guard_expr(expr) + "." + field.name
436 if field.is_base_class:
437 field_value = value.cast(field.type)
438 else:
439 field_value = value[field.name]
440 literal_value = ""
441 if type_code == gdb.TYPE_CODE_UNION:
442 literal_value = "<Enter %d to explore this field of type " "'%s'>" % (
443 current_choice,
444 str(field.type),
445 )
446 has_explorable_fields = True
447 else:
448 if Explorer.is_scalar_type(field.type):
449 literal_value = "%s .. (Value of type '%s')" % (
450 str(field_value),
451 str(field.type),
452 )
453 else:
454 if field.is_base_class:
455 field_desc = "base class"
456 else:
457 field_desc = "field"
458 literal_value = "<Enter %d to explore this %s of type " "'%s'>" % (
459 current_choice,
460 field_desc,
461 str(field.type),
462 )
463 has_explorable_fields = True
464
465 choice_to_compound_field_map[str(current_choice)] = (
466 field_full_name,
467 field_value,
468 )
469 current_choice = current_choice + 1
470
471 print_list.append((field.name, literal_value))
472
473 CompoundExplorer._print_fields(print_list)
474 print("")
475
476 if has_explorable_fields:
477 choice = raw_input("Enter the field number of choice: ")
478 if choice in choice_to_compound_field_map:
479 Explorer.explore_expr(
480 choice_to_compound_field_map[choice][0],
481 choice_to_compound_field_map[choice][1],
482 True,
483 )
484 return True
485 else:
486 if is_child:
487 Explorer.return_to_parent_value()
488 else:
489 if is_child:
490 Explorer.return_to_parent_value_prompt()
491
492 return False
493
494 @staticmethod
495 def explore_type(name, datatype, is_child):
496 """Function to explore struct/class and union types.
497 See Explorer.explore_type for more information.
498 """
499 type_code = datatype.code
500 type_desc = ""
501 if type_code == gdb.TYPE_CODE_STRUCT:
502 type_desc = "struct/class"
503 else:
504 type_desc = "union"
505
506 fields = datatype.fields()
507 if CompoundExplorer._get_real_field_count(fields) == 0:
508 if is_child:
509 print(
510 "%s is a %s of type '%s' with no fields."
511 % (name, type_desc, str(datatype))
512 )
513 Explorer.return_to_enclosing_type_prompt()
514 else:
515 print("'%s' is a %s with no fields." % (name, type_desc))
516 return False
517
518 if is_child:
519 print(
520 "%s is a %s of type '%s' "
521 "with the following fields:\n" % (name, type_desc, str(datatype))
522 )
523 else:
524 print("'%s' is a %s with the following " "fields:\n" % (name, type_desc))
525
526 has_explorable_fields = False
527 current_choice = 0
528 choice_to_compound_field_map = {}
529 print_list = []
530 for field in fields:
531 if field.artificial:
532 continue
533 if field.is_base_class:
534 field_desc = "base class"
535 else:
536 field_desc = "field"
537 rhs = "<Enter %d to explore this %s of type '%s'>" % (
538 current_choice,
539 field_desc,
540 str(field.type),
541 )
542 print_list.append((field.name, rhs))
543 choice_to_compound_field_map[str(current_choice)] = (
544 field.name,
545 field.type,
546 field_desc,
547 )
548 current_choice = current_choice + 1
549
550 CompoundExplorer._print_fields(print_list)
551 print("")
552
553 if len(choice_to_compound_field_map) > 0:
554 choice = raw_input("Enter the field number of choice: ")
555 if choice in choice_to_compound_field_map:
556 if is_child:
557 new_name = "%s '%s' of %s" % (
558 choice_to_compound_field_map[choice][2],
559 choice_to_compound_field_map[choice][0],
560 name,
561 )
562 else:
563 new_name = "%s '%s' of '%s'" % (
564 choice_to_compound_field_map[choice][2],
565 choice_to_compound_field_map[choice][0],
566 name,
567 )
568 Explorer.explore_type(
569 new_name, choice_to_compound_field_map[choice][1], True
570 )
571 return True
572 else:
573 if is_child:
574 Explorer.return_to_enclosing_type()
575 else:
576 if is_child:
577 Explorer.return_to_enclosing_type_prompt()
578
579 return False
580
581
582 class TypedefExplorer(object):
583 """Internal class used to explore values whose type is a typedef."""
584
585 @staticmethod
586 def explore_expr(expr, value, is_child):
587 """Function to explore typedef values.
588 See Explorer.explore_expr for more information.
589 """
590 actual_type = value.type.strip_typedefs()
591 print(
592 "The value of '%s' is of type '%s' "
593 "which is a typedef of type '%s'"
594 % (expr, str(value.type), str(actual_type))
595 )
596
597 Explorer.explore_expr(expr, value.cast(actual_type), is_child)
598 return False
599
600 @staticmethod
601 def explore_type(name, datatype, is_child):
602 """Function to explore typedef types.
603 See Explorer.explore_type for more information.
604 """
605 actual_type = datatype.strip_typedefs()
606 if is_child:
607 print(
608 "The type of %s is a typedef of type '%s'." % (name, str(actual_type))
609 )
610 else:
611 print("The type '%s' is a typedef of type '%s'." % (name, str(actual_type)))
612
613 Explorer.explore_type(name, actual_type, is_child)
614 return False
615
616
617 class ExploreUtils(object):
618 """Internal class which provides utilities for the main command classes."""
619
620 @staticmethod
621 def check_args(name, arg_str):
622 """Utility to check if adequate number of arguments are passed to an
623 explore command.
624
625 Arguments:
626 name: The name of the explore command.
627 arg_str: The argument string passed to the explore command.
628
629 Returns:
630 True if adequate arguments are passed, false otherwise.
631
632 Raises:
633 gdb.GdbError if adequate arguments are not passed.
634 """
635 if len(arg_str) < 1:
636 raise gdb.GdbError("ERROR: '%s' requires an argument." % name)
637 return False
638 else:
639 return True
640
641 @staticmethod
642 def get_type_from_str(type_str):
643 """A utility function to deduce the gdb.Type value from a string
644 representing the type.
645
646 Arguments:
647 type_str: The type string from which the gdb.Type value should be
648 deduced.
649
650 Returns:
651 The deduced gdb.Type value if possible, None otherwise.
652 """
653 try:
654 # Assume the current language to be C/C++ and make a try.
655 return gdb.parse_and_eval("(%s *)0" % type_str).type.target()
656 except RuntimeError:
657 # If assumption of current language to be C/C++ was wrong, then
658 # lookup the type using the API.
659 try:
660 return gdb.lookup_type(type_str)
661 except RuntimeError:
662 return None
663
664 @staticmethod
665 def get_value_from_str(value_str):
666 """A utility function to deduce the gdb.Value value from a string
667 representing the value.
668
669 Arguments:
670 value_str: The value string from which the gdb.Value value should
671 be deduced.
672
673 Returns:
674 The deduced gdb.Value value if possible, None otherwise.
675 """
676 try:
677 return gdb.parse_and_eval(value_str)
678 except RuntimeError:
679 return None
680
681
682 class ExploreCommand(gdb.Command):
683 """Explore a value or a type valid in the current context.
684
685 Usage: explore ARG
686
687 - ARG is either a valid expression or a type name.
688 - At any stage of exploration, hit the return key (instead of a
689 choice, if any) to return to the enclosing type or value."""
690
691 def __init__(self):
692 super(ExploreCommand, self).__init__(
693 name="explore", command_class=gdb.COMMAND_DATA, prefix=True
694 )
695
696 def invoke(self, arg_str, from_tty):
697 if ExploreUtils.check_args("explore", arg_str) == False:
698 return
699
700 # Check if it is a value
701 value = ExploreUtils.get_value_from_str(arg_str)
702 if value is not None:
703 Explorer.explore_expr(arg_str, value, False)
704 return
705
706 # If it is not a value, check if it is a type
707 datatype = ExploreUtils.get_type_from_str(arg_str)
708 if datatype is not None:
709 Explorer.explore_type(arg_str, datatype, False)
710 return
711
712 # If it is neither a value nor a type, raise an error.
713 raise gdb.GdbError(
714 (
715 "'%s' neither evaluates to a value nor is a type "
716 "in the current context." % arg_str
717 )
718 )
719
720
721 class ExploreValueCommand(gdb.Command):
722 """Explore value of an expression valid in the current context.
723
724 Usage: explore value ARG
725
726 - ARG is a valid expression.
727 - At any stage of exploration, hit the return key (instead of a
728 choice, if any) to return to the enclosing value."""
729
730 def __init__(self):
731 super(ExploreValueCommand, self).__init__(
732 name="explore value", command_class=gdb.COMMAND_DATA
733 )
734
735 def invoke(self, arg_str, from_tty):
736 if ExploreUtils.check_args("explore value", arg_str) == False:
737 return
738
739 value = ExploreUtils.get_value_from_str(arg_str)
740 if value is None:
741 raise gdb.GdbError(
742 (
743 " '%s' does not evaluate to a value in the current "
744 "context." % arg_str
745 )
746 )
747 return
748
749 Explorer.explore_expr(arg_str, value, False)
750
751
752 class ExploreTypeCommand(gdb.Command):
753 """Explore a type or the type of an expression.
754
755 Usage: explore type ARG
756
757 - ARG is a valid expression or a type name.
758 - At any stage of exploration, hit the return key (instead of a
759 choice, if any) to return to the enclosing type."""
760
761 def __init__(self):
762 super(ExploreTypeCommand, self).__init__(
763 name="explore type", command_class=gdb.COMMAND_DATA
764 )
765
766 def invoke(self, arg_str, from_tty):
767 if ExploreUtils.check_args("explore type", arg_str) == False:
768 return
769
770 datatype = ExploreUtils.get_type_from_str(arg_str)
771 if datatype is not None:
772 Explorer.explore_type(arg_str, datatype, False)
773 return
774
775 value = ExploreUtils.get_value_from_str(arg_str)
776 if value is not None:
777 print("'%s' is of type '%s'." % (arg_str, str(value.type)))
778 Explorer.explore_type(str(value.type), value.type, False)
779 return
780
781 raise gdb.GdbError(
782 ("'%s' is not a type or value in the current " "context." % arg_str)
783 )
784
785
786 Explorer.init_env()
787
788 ExploreCommand()
789 ExploreValueCommand()
790 ExploreTypeCommand()
This page took 0.054455 seconds and 4 git commands to generate.