Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: gdb/python/lib/gdb/command/explore.py

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

Powered by Google App Engine
This is Rietveld 408576698