OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2011 the V8 project authors. All rights reserved. | 3 # Copyright 2011 the V8 project authors. All rights reserved. |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
516 # }; | 516 # }; |
517 # static P p; | 517 # static P p; |
518 INSTANCE_TYPES = { | 518 INSTANCE_TYPES = { |
519 64: "SYMBOL_TYPE", | 519 64: "SYMBOL_TYPE", |
520 68: "ASCII_SYMBOL_TYPE", | 520 68: "ASCII_SYMBOL_TYPE", |
521 65: "CONS_SYMBOL_TYPE", | 521 65: "CONS_SYMBOL_TYPE", |
522 69: "CONS_ASCII_SYMBOL_TYPE", | 522 69: "CONS_ASCII_SYMBOL_TYPE", |
523 66: "EXTERNAL_SYMBOL_TYPE", | 523 66: "EXTERNAL_SYMBOL_TYPE", |
524 74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", | 524 74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", |
525 70: "EXTERNAL_ASCII_SYMBOL_TYPE", | 525 70: "EXTERNAL_ASCII_SYMBOL_TYPE", |
526 82: "SHORT_EXTERNAL_SYMBOL_TYPE", | |
527 90: "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", | |
528 86: "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE", | |
526 0: "STRING_TYPE", | 529 0: "STRING_TYPE", |
527 4: "ASCII_STRING_TYPE", | 530 4: "ASCII_STRING_TYPE", |
528 1: "CONS_STRING_TYPE", | 531 1: "CONS_STRING_TYPE", |
529 5: "CONS_ASCII_STRING_TYPE", | 532 5: "CONS_ASCII_STRING_TYPE", |
533 3: "SLICED_STRING_TYPE", | |
530 2: "EXTERNAL_STRING_TYPE", | 534 2: "EXTERNAL_STRING_TYPE", |
531 10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", | 535 10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", |
532 6: "EXTERNAL_ASCII_STRING_TYPE", | 536 6: "EXTERNAL_ASCII_STRING_TYPE", |
537 18: "SHORT_EXTERNAL_STRING_TYPE", | |
538 26: "SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", | |
539 22: "SHORT_EXTERNAL_ASCII_STRING_TYPE", | |
533 6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE", | 540 6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE", |
534 128: "MAP_TYPE", | 541 128: "MAP_TYPE", |
535 129: "CODE_TYPE", | 542 129: "CODE_TYPE", |
536 130: "ODDBALL_TYPE", | 543 130: "ODDBALL_TYPE", |
537 131: "JS_GLOBAL_PROPERTY_CELL_TYPE", | 544 131: "JS_GLOBAL_PROPERTY_CELL_TYPE", |
538 132: "HEAP_NUMBER_TYPE", | 545 132: "HEAP_NUMBER_TYPE", |
539 133: "FOREIGN_TYPE", | 546 133: "FOREIGN_TYPE", |
540 134: "BYTE_ARRAY_TYPE", | 547 134: "BYTE_ARRAY_TYPE", |
541 135: "EXTERNAL_BYTE_ARRAY_TYPE", | 548 135: "FREE_SPACE_TYPE", |
542 136: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", | 549 136: "EXTERNAL_BYTE_ARRAY_TYPE", |
543 137: "EXTERNAL_SHORT_ARRAY_TYPE", | 550 137: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", |
544 138: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", | 551 138: "EXTERNAL_SHORT_ARRAY_TYPE", |
545 139: "EXTERNAL_INT_ARRAY_TYPE", | 552 139: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", |
546 140: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", | 553 140: "EXTERNAL_INT_ARRAY_TYPE", |
547 141: "EXTERNAL_FLOAT_ARRAY_TYPE", | 554 141: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", |
548 143: "EXTERNAL_PIXEL_ARRAY_TYPE", | 555 142: "EXTERNAL_FLOAT_ARRAY_TYPE", |
549 145: "FILLER_TYPE", | 556 144: "EXTERNAL_PIXEL_ARRAY_TYPE", |
550 146: "ACCESSOR_INFO_TYPE", | 557 146: "FILLER_TYPE", |
551 147: "ACCESS_CHECK_INFO_TYPE", | 558 147: "ACCESSOR_INFO_TYPE", |
552 148: "INTERCEPTOR_INFO_TYPE", | 559 148: "ACCESS_CHECK_INFO_TYPE", |
553 149: "CALL_HANDLER_INFO_TYPE", | 560 149: "INTERCEPTOR_INFO_TYPE", |
554 150: "FUNCTION_TEMPLATE_INFO_TYPE", | 561 150: "CALL_HANDLER_INFO_TYPE", |
555 151: "OBJECT_TEMPLATE_INFO_TYPE", | 562 151: "FUNCTION_TEMPLATE_INFO_TYPE", |
556 152: "SIGNATURE_INFO_TYPE", | 563 152: "OBJECT_TEMPLATE_INFO_TYPE", |
557 153: "TYPE_SWITCH_INFO_TYPE", | 564 153: "SIGNATURE_INFO_TYPE", |
558 154: "SCRIPT_TYPE", | 565 154: "TYPE_SWITCH_INFO_TYPE", |
559 155: "CODE_CACHE_TYPE", | 566 155: "SCRIPT_TYPE", |
560 156: "POLYMORPHIC_CODE_CACHE_TYPE", | 567 156: "CODE_CACHE_TYPE", |
561 159: "FIXED_ARRAY_TYPE", | 568 157: "POLYMORPHIC_CODE_CACHE_TYPE", |
562 160: "SHARED_FUNCTION_INFO_TYPE", | 569 160: "FIXED_ARRAY_TYPE", |
563 161: "JS_MESSAGE_OBJECT_TYPE", | 570 145: "FIXED_DOUBLE_ARRAY_TYPE", |
564 162: "JS_VALUE_TYPE", | 571 161: "SHARED_FUNCTION_INFO_TYPE", |
565 163: "JS_OBJECT_TYPE", | 572 162: "JS_MESSAGE_OBJECT_TYPE", |
566 164: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", | 573 165: "JS_VALUE_TYPE", |
567 165: "JS_GLOBAL_OBJECT_TYPE", | 574 166: "JS_OBJECT_TYPE", |
568 166: "JS_BUILTINS_OBJECT_TYPE", | 575 167: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", |
569 167: "JS_GLOBAL_PROXY_TYPE", | 576 168: "JS_GLOBAL_OBJECT_TYPE", |
570 168: "JS_ARRAY_TYPE", | 577 169: "JS_BUILTINS_OBJECT_TYPE", |
571 169: "JS_PROXY_TYPE", | 578 170: "JS_GLOBAL_PROXY_TYPE", |
572 170: "JS_WEAK_MAP_TYPE", | 579 171: "JS_ARRAY_TYPE", |
573 171: "JS_REGEXP_TYPE", | 580 164: "JS_PROXY_TYPE", |
574 172: "JS_FUNCTION_TYPE", | 581 174: "JS_WEAK_MAP_TYPE", |
575 173: "JS_FUNCTION_PROXY_TYPE", | 582 175: "JS_REGEXP_TYPE", |
576 157: "DEBUG_INFO_TYPE", | 583 176: "JS_FUNCTION_TYPE", |
577 158: "BREAK_POINT_INFO_TYPE", | 584 163: "JS_FUNCTION_PROXY_TYPE", |
585 158: "DEBUG_INFO_TYPE", | |
586 159: "BREAK_POINT_INFO_TYPE", | |
578 } | 587 } |
579 | 588 |
580 | 589 |
581 class Printer(object): | 590 class Printer(object): |
582 """Printer with indentation support.""" | 591 """Printer with indentation support.""" |
583 | 592 |
584 def __init__(self): | 593 def __init__(self): |
585 self.indent = 0 | 594 self.indent = 0 |
586 | 595 |
587 def Indent(self): | 596 def Indent(self): |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) | 654 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) |
646 return self.heap.FindObjectOrSmi(field_value) | 655 return self.heap.FindObjectOrSmi(field_value) |
647 | 656 |
648 def SmiField(self, offset): | 657 def SmiField(self, offset): |
649 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) | 658 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) |
650 assert (field_value & 1) == 0 | 659 assert (field_value & 1) == 0 |
651 return field_value / 2 | 660 return field_value / 2 |
652 | 661 |
653 | 662 |
654 class Map(HeapObject): | 663 class Map(HeapObject): |
655 def InstanceTypeOffset(): | 664 def InstanceTypeOffset(self): |
656 return self.heap.PointerSize() + self.heap.IntSize() | 665 return self.heap.PointerSize() + self.heap.IntSize() |
657 | 666 |
658 def __init__(self, heap, map, address): | 667 def __init__(self, heap, map, address): |
659 HeapObject.__init__(self, heap, map, address) | 668 HeapObject.__init__(self, heap, map, address) |
660 self.instance_type = \ | 669 self.instance_type = \ |
661 heap.reader.ReadU8(self.address + self.InstanceTypeOffset()) | 670 heap.reader.ReadU8(self.address + self.InstanceTypeOffset()) |
662 | 671 |
663 | 672 |
664 class String(HeapObject): | 673 class String(HeapObject): |
665 def LengthOffset(self): | 674 def LengthOffset(self): |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
879 class Code(HeapObject): | 888 class Code(HeapObject): |
880 CODE_ALIGNMENT_MASK = (1 << 5) - 1 | 889 CODE_ALIGNMENT_MASK = (1 << 5) - 1 |
881 | 890 |
882 def InstructionSizeOffset(self): | 891 def InstructionSizeOffset(self): |
883 return self.heap.PointerSize() | 892 return self.heap.PointerSize() |
884 | 893 |
885 @staticmethod | 894 @staticmethod |
886 def HeaderSize(heap): | 895 def HeaderSize(heap): |
887 return (heap.PointerSize() + heap.IntSize() + \ | 896 return (heap.PointerSize() + heap.IntSize() + \ |
888 4 * heap.PointerSize() + 3 * heap.IntSize() + \ | 897 4 * heap.PointerSize() + 3 * heap.IntSize() + \ |
889 CODE_ALIGNMENT_MASK) & ~CODE_ALIGNMENT_MASK | 898 Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK |
890 | 899 |
891 def __init__(self, heap, map, address): | 900 def __init__(self, heap, map, address): |
892 HeapObject.__init__(self, heap, map, address) | 901 HeapObject.__init__(self, heap, map, address) |
893 self.entry = self.address + Code.HeaderSize(heap) | 902 self.entry = self.address + Code.HeaderSize(heap) |
894 self.instruction_size = \ | 903 self.instruction_size = \ |
895 heap.reader.ReadU32(self.address + self.InstructionSizeOffset()) | 904 heap.reader.ReadU32(self.address + self.InstructionSizeOffset()) |
896 | 905 |
897 def Print(self, p): | 906 def Print(self, p): |
898 lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size) | 907 lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size) |
899 p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address)) | 908 p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address)) |
900 p.Indent() | 909 p.Indent() |
901 p.Print("instruction_size: %d" % self.instruction_size) | 910 p.Print("instruction_size: %d" % self.instruction_size) |
902 p.PrintLines(self._FormatLine(line) for line in lines) | 911 p.PrintLines(self._FormatLine(line) for line in lines) |
903 p.Dedent() | 912 p.Dedent() |
904 p.Print("}") | 913 p.Print("}") |
905 | 914 |
906 def _FormatLine(self, line): | 915 def _FormatLine(self, line): |
907 return FormatDisasmLine(self.entry, self.heap, line) | 916 return FormatDisasmLine(self.entry, self.heap, line) |
908 | 917 |
909 | 918 |
910 class V8Heap(object): | 919 class V8Heap(object): |
911 CLASS_MAP = { | 920 CLASS_MAP = { |
912 "SYMBOL_TYPE": SeqString, | 921 "SYMBOL_TYPE": SeqString, |
913 "ASCII_SYMBOL_TYPE": SeqString, | 922 "ASCII_SYMBOL_TYPE": SeqString, |
914 "CONS_SYMBOL_TYPE": ConsString, | 923 "CONS_SYMBOL_TYPE": ConsString, |
915 "CONS_ASCII_SYMBOL_TYPE": ConsString, | 924 "CONS_ASCII_SYMBOL_TYPE": ConsString, |
916 "EXTERNAL_SYMBOL_TYPE": ExternalString, | 925 "EXTERNAL_SYMBOL_TYPE": ExternalString, |
917 "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, | 926 "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, |
918 "EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, | 927 "EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, |
928 "SHORT_EXTERNAL_SYMBOL_TYPE": ExternalString, | |
929 "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, | |
930 "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, | |
919 "STRING_TYPE": SeqString, | 931 "STRING_TYPE": SeqString, |
920 "ASCII_STRING_TYPE": SeqString, | 932 "ASCII_STRING_TYPE": SeqString, |
921 "CONS_STRING_TYPE": ConsString, | 933 "CONS_STRING_TYPE": ConsString, |
922 "CONS_ASCII_STRING_TYPE": ConsString, | 934 "CONS_ASCII_STRING_TYPE": ConsString, |
923 "EXTERNAL_STRING_TYPE": ExternalString, | 935 "EXTERNAL_STRING_TYPE": ExternalString, |
924 "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE": ExternalString, | 936 "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE": ExternalString, |
925 "EXTERNAL_ASCII_STRING_TYPE": ExternalString, | 937 "EXTERNAL_ASCII_STRING_TYPE": ExternalString, |
926 | 938 |
927 "MAP_TYPE": Map, | 939 "MAP_TYPE": Map, |
928 "ODDBALL_TYPE": Oddball, | 940 "ODDBALL_TYPE": Oddball, |
929 "FIXED_ARRAY_TYPE": FixedArray, | 941 "FIXED_ARRAY_TYPE": FixedArray, |
930 "JS_FUNCTION_TYPE": JSFunction, | 942 "JS_FUNCTION_TYPE": JSFunction, |
931 "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo, | 943 "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo, |
932 "SCRIPT_TYPE": Script, | 944 "SCRIPT_TYPE": Script, |
933 "CODE_TYPE": Code | 945 "CODE_TYPE": Code |
934 } | 946 } |
935 | 947 |
936 def __init__(self, reader, stack_map): | 948 def __init__(self, reader, stack_map): |
937 self.reader = reader | 949 self.reader = reader |
938 self.stack_map = stack_map | 950 self.stack_map = stack_map |
939 self.objects = {} | 951 self.objects = {} |
940 | 952 |
941 def FindObjectOrSmi(self, tagged_address): | 953 def FindObjectOrSmi(self, tagged_address): |
942 if (tagged_address & 1) == 0: return tagged_address / 2 | 954 if (tagged_address & 1) == 0: return tagged_address / 2 |
943 return self.FindObject(tagged_address) | 955 return self.FindObject(tagged_address) |
944 | 956 |
957 def FindMap(self, tagged_address): | |
Vyacheslav Egorov (Chromium)
2012/01/04 08:45:35
One trick that might help to guess whether smth is
Michael Starzinger
2012/01/05 14:26:30
Done. I also added the alignment check for other h
| |
958 if (tagged_address & 1) != 1: return None | |
959 address = tagged_address - 1 | |
960 if not self.reader.IsValidAddress(address): return None | |
961 object = Map(self, None, address) | |
962 return object | |
963 | |
945 def FindObject(self, tagged_address): | 964 def FindObject(self, tagged_address): |
946 if tagged_address in self.objects: | 965 if tagged_address in self.objects: |
947 return self.objects[tagged_address] | 966 return self.objects[tagged_address] |
948 if (tagged_address & 1) != 1: return None | 967 if (tagged_address & 1) != 1: return None |
949 address = tagged_address - 1 | 968 address = tagged_address - 1 |
950 if not self.reader.IsValidAddress(address): return None | 969 if not self.reader.IsValidAddress(address): return None |
951 map_tagged_address = self.reader.ReadUIntPtr(address) | 970 map_tagged_address = self.reader.ReadUIntPtr(address) |
952 if tagged_address == map_tagged_address: | 971 if tagged_address == map_tagged_address: |
953 # Meta map? | 972 # Meta map? |
954 meta_map = Map(self, None, address) | 973 meta_map = Map(self, None, address) |
955 instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type) | 974 instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type) |
956 if instance_type_name != "MAP_TYPE": return None | 975 if instance_type_name != "MAP_TYPE": return None |
957 meta_map.map = meta_map | 976 meta_map.map = meta_map |
958 object = meta_map | 977 object = meta_map |
959 else: | 978 else: |
960 map = self.FindObject(map_tagged_address) | 979 map = self.FindMap(map_tagged_address) |
961 if map is None: return None | 980 if map is None: return None |
962 instance_type_name = INSTANCE_TYPES.get(map.instance_type) | 981 instance_type_name = INSTANCE_TYPES.get(map.instance_type) |
963 if instance_type_name is None: return None | 982 if instance_type_name is None: return None |
964 cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) | 983 cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) |
965 object = cls(self, map, address) | 984 object = cls(self, map, address) |
966 self.objects[tagged_address] = object | 985 self.objects[tagged_address] = object |
967 return object | 986 return object |
968 | 987 |
988 def IntSize(self): | |
989 return 4 | |
990 | |
969 def PointerSize(self): | 991 def PointerSize(self): |
970 return self.reader.PointerSize() | 992 return self.reader.PointerSize() |
971 | 993 |
972 | 994 |
973 | 995 |
974 EIP_PROXIMITY = 64 | 996 EIP_PROXIMITY = 64 |
975 | 997 |
976 CONTEXT_FOR_ARCH = { | 998 CONTEXT_FOR_ARCH = { |
977 MD_CPU_ARCHITECTURE_AMD64: | 999 MD_CPU_ARCHITECTURE_AMD64: |
978 ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip'], | 1000 ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip'], |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 reader.Dispose() | 1049 reader.Dispose() |
1028 | 1050 |
1029 | 1051 |
1030 if __name__ == "__main__": | 1052 if __name__ == "__main__": |
1031 parser = optparse.OptionParser(USAGE) | 1053 parser = optparse.OptionParser(USAGE) |
1032 options, args = parser.parse_args() | 1054 options, args = parser.parse_args() |
1033 if len(args) != 1: | 1055 if len(args) != 1: |
1034 parser.print_help() | 1056 parser.print_help() |
1035 sys.exit(1) | 1057 sys.exit(1) |
1036 AnalyzeMinidump(options, args[0]) | 1058 AnalyzeMinidump(options, args[0]) |
OLD | NEW |