| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2012 the V8 project authors. All rights reserved. | 3 # Copyright 2012 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 22 matching lines...) Expand all Loading... |
| 33 import ctypes | 33 import ctypes |
| 34 import datetime | 34 import datetime |
| 35 import disasm | 35 import disasm |
| 36 import mmap | 36 import mmap |
| 37 import optparse | 37 import optparse |
| 38 import os | 38 import os |
| 39 import re | 39 import re |
| 40 import struct | 40 import struct |
| 41 import sys | 41 import sys |
| 42 import types | 42 import types |
| 43 import v8heapconst |
| 43 | 44 |
| 44 USAGE="""usage: %prog [OPTIONS] [DUMP-FILE] | 45 USAGE="""usage: %prog [OPTIONS] [DUMP-FILE] |
| 45 | 46 |
| 46 Minidump analyzer. | 47 Minidump analyzer. |
| 47 | 48 |
| 48 Shows the processor state at the point of exception including the | 49 Shows the processor state at the point of exception including the |
| 49 stack of the active thread and the referenced objects in the V8 | 50 stack of the active thread and the referenced objects in the V8 |
| 50 heap. Code objects are disassembled and the addresses linked from the | 51 heap. Code objects are disassembled and the addresses linked from the |
| 51 stack (e.g. pushed return addresses) are marked with "=>". | 52 stack (e.g. pushed return addresses) are marked with "=>". |
| 52 | 53 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 maybe_address = reader.ReadUIntPtr(slot) | 157 maybe_address = reader.ReadUIntPtr(slot) |
| 157 heap_object = heap.FindObject(maybe_address) | 158 heap_object = heap.FindObject(maybe_address) |
| 158 print "%s: %s" % (reader.FormatIntPtr(slot), | 159 print "%s: %s" % (reader.FormatIntPtr(slot), |
| 159 reader.FormatIntPtr(maybe_address)) | 160 reader.FormatIntPtr(maybe_address)) |
| 160 if heap_object: | 161 if heap_object: |
| 161 heap_object.Print(Printer()) | 162 heap_object.Print(Printer()) |
| 162 print | 163 print |
| 163 | 164 |
| 164 reader.ForEachMemoryRegion(dump_region) | 165 reader.ForEachMemoryRegion(dump_region) |
| 165 | 166 |
| 167 # Heap constants generated by 'make grokdump' in v8heapconst module. |
| 168 INSTANCE_TYPES = v8heapconst.INSTANCE_TYPES |
| 169 KNOWN_MAPS = v8heapconst.KNOWN_MAPS |
| 170 KNOWN_OBJECTS = v8heapconst.KNOWN_OBJECTS |
| 171 |
| 166 # Set of structures and constants that describe the layout of minidump | 172 # Set of structures and constants that describe the layout of minidump |
| 167 # files. Based on MSDN and Google Breakpad. | 173 # files. Based on MSDN and Google Breakpad. |
| 168 | 174 |
| 169 MINIDUMP_HEADER = Descriptor([ | 175 MINIDUMP_HEADER = Descriptor([ |
| 170 ("signature", ctypes.c_uint32), | 176 ("signature", ctypes.c_uint32), |
| 171 ("version", ctypes.c_uint32), | 177 ("version", ctypes.c_uint32), |
| 172 ("stream_count", ctypes.c_uint32), | 178 ("stream_count", ctypes.c_uint32), |
| 173 ("stream_directories_rva", ctypes.c_uint32), | 179 ("stream_directories_rva", ctypes.c_uint32), |
| 174 ("checksum", ctypes.c_uint32), | 180 ("checksum", ctypes.c_uint32), |
| 175 ("time_date_stampt", ctypes.c_uint32), | 181 ("time_date_stampt", ctypes.c_uint32), |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 if (0 < i) and self.symbols[i - 1].Covers(addr): | 833 if (0 < i) and self.symbols[i - 1].Covers(addr): |
| 828 symbol = self.symbols[i - 1] | 834 symbol = self.symbols[i - 1] |
| 829 elif (i < len(self.symbols)) and self.symbols[i].Covers(addr): | 835 elif (i < len(self.symbols)) and self.symbols[i].Covers(addr): |
| 830 symbol = self.symbols[i] | 836 symbol = self.symbols[i] |
| 831 else: | 837 else: |
| 832 return None | 838 return None |
| 833 diff = addr - symbol.start | 839 diff = addr - symbol.start |
| 834 return "%s+0x%x" % (symbol.name, diff) | 840 return "%s+0x%x" % (symbol.name, diff) |
| 835 | 841 |
| 836 | 842 |
| 837 | |
| 838 # List of V8 instance types. Obtained by adding the code below to any .cc file. | |
| 839 # | |
| 840 # #define DUMP_TYPE(T) printf(" %d: \"%s\",\n", T, #T); | |
| 841 # struct P { | |
| 842 # P() { | |
| 843 # printf("INSTANCE_TYPES = {\n"); | |
| 844 # INSTANCE_TYPE_LIST(DUMP_TYPE) | |
| 845 # printf("}\n"); | |
| 846 # } | |
| 847 # }; | |
| 848 # static P p; | |
| 849 INSTANCE_TYPES = { | |
| 850 0: "STRING_TYPE", | |
| 851 4: "ASCII_STRING_TYPE", | |
| 852 1: "CONS_STRING_TYPE", | |
| 853 5: "CONS_ASCII_STRING_TYPE", | |
| 854 3: "SLICED_STRING_TYPE", | |
| 855 2: "EXTERNAL_STRING_TYPE", | |
| 856 6: "EXTERNAL_ASCII_STRING_TYPE", | |
| 857 10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", | |
| 858 18: "SHORT_EXTERNAL_STRING_TYPE", | |
| 859 22: "SHORT_EXTERNAL_ASCII_STRING_TYPE", | |
| 860 26: "SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", | |
| 861 64: "INTERNALIZED_STRING_TYPE", | |
| 862 68: "ASCII_INTERNALIZED_STRING_TYPE", | |
| 863 65: "CONS_INTERNALIZED_STRING_TYPE", | |
| 864 69: "CONS_ASCII_INTERNALIZED_STRING_TYPE", | |
| 865 66: "EXTERNAL_INTERNALIZED_STRING_TYPE", | |
| 866 70: "EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE", | |
| 867 74: "EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE", | |
| 868 82: "SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE", | |
| 869 86: "SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE", | |
| 870 90: "SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ASCII_DATA_TYPE", | |
| 871 128: "SYMBOL_TYPE", | |
| 872 129: "MAP_TYPE", | |
| 873 130: "CODE_TYPE", | |
| 874 131: "ODDBALL_TYPE", | |
| 875 132: "JS_GLOBAL_PROPERTY_CELL_TYPE", | |
| 876 133: "HEAP_NUMBER_TYPE", | |
| 877 134: "FOREIGN_TYPE", | |
| 878 135: "BYTE_ARRAY_TYPE", | |
| 879 136: "FREE_SPACE_TYPE", | |
| 880 137: "EXTERNAL_BYTE_ARRAY_TYPE", | |
| 881 138: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", | |
| 882 139: "EXTERNAL_SHORT_ARRAY_TYPE", | |
| 883 140: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", | |
| 884 141: "EXTERNAL_INT_ARRAY_TYPE", | |
| 885 142: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", | |
| 886 143: "EXTERNAL_FLOAT_ARRAY_TYPE", | |
| 887 145: "EXTERNAL_PIXEL_ARRAY_TYPE", | |
| 888 147: "FILLER_TYPE", | |
| 889 148: "DECLARED_ACCESSOR_DESCRIPTOR_TYPE", | |
| 890 149: "DECLARED_ACCESSOR_INFO_TYPE", | |
| 891 150: "EXECUTABLE_ACCESSOR_INFO_TYPE", | |
| 892 151: "ACCESSOR_PAIR_TYPE", | |
| 893 152: "ACCESS_CHECK_INFO_TYPE", | |
| 894 153: "INTERCEPTOR_INFO_TYPE", | |
| 895 154: "CALL_HANDLER_INFO_TYPE", | |
| 896 155: "FUNCTION_TEMPLATE_INFO_TYPE", | |
| 897 156: "OBJECT_TEMPLATE_INFO_TYPE", | |
| 898 157: "SIGNATURE_INFO_TYPE", | |
| 899 158: "TYPE_SWITCH_INFO_TYPE", | |
| 900 159: "ALLOCATION_SITE_INFO_TYPE", | |
| 901 160: "SCRIPT_TYPE", | |
| 902 161: "CODE_CACHE_TYPE", | |
| 903 162: "POLYMORPHIC_CODE_CACHE_TYPE", | |
| 904 163: "TYPE_FEEDBACK_INFO_TYPE", | |
| 905 164: "ALIASED_ARGUMENTS_ENTRY_TYPE", | |
| 906 167: "FIXED_ARRAY_TYPE", | |
| 907 146: "FIXED_DOUBLE_ARRAY_TYPE", | |
| 908 168: "SHARED_FUNCTION_INFO_TYPE", | |
| 909 169: "JS_MESSAGE_OBJECT_TYPE", | |
| 910 172: "JS_VALUE_TYPE", | |
| 911 173: "JS_DATE_TYPE", | |
| 912 174: "JS_OBJECT_TYPE", | |
| 913 175: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", | |
| 914 176: "JS_MODULE_TYPE", | |
| 915 177: "JS_GLOBAL_OBJECT_TYPE", | |
| 916 178: "JS_BUILTINS_OBJECT_TYPE", | |
| 917 179: "JS_GLOBAL_PROXY_TYPE", | |
| 918 180: "JS_ARRAY_TYPE", | |
| 919 171: "JS_PROXY_TYPE", | |
| 920 183: "JS_WEAK_MAP_TYPE", | |
| 921 184: "JS_WEAK_SET_TYPE", | |
| 922 185: "JS_REGEXP_TYPE", | |
| 923 186: "JS_FUNCTION_TYPE", | |
| 924 170: "JS_FUNCTION_PROXY_TYPE", | |
| 925 165: "DEBUG_INFO_TYPE", | |
| 926 166: "BREAK_POINT_INFO_TYPE", | |
| 927 } | |
| 928 | |
| 929 | |
| 930 # List of known V8 maps. Used to determine the instance type and name | |
| 931 # for maps that are part of the root-set and hence on the first page of | |
| 932 # the map-space. Obtained by adding the code below to an IA32 release | |
| 933 # build with enabled snapshots to the end of the Isolate::Init method. | |
| 934 # | |
| 935 # #define ROOT_LIST_CASE(type, name, camel_name) \ | |
| 936 # if (o == heap_.name()) n = #camel_name; | |
| 937 # #define STRUCT_LIST_CASE(upper_name, camel_name, name) \ | |
| 938 # if (o == heap_.name##_map()) n = #camel_name "Map"; | |
| 939 # HeapObjectIterator it(heap_.map_space()); | |
| 940 # printf("KNOWN_MAPS = {\n"); | |
| 941 # for (Object* o = it.Next(); o != NULL; o = it.Next()) { | |
| 942 # Map* m = Map::cast(o); | |
| 943 # const char* n = ""; | |
| 944 # intptr_t p = reinterpret_cast<intptr_t>(m) & 0xfffff; | |
| 945 # int t = m->instance_type(); | |
| 946 # ROOT_LIST(ROOT_LIST_CASE) | |
| 947 # STRUCT_LIST(STRUCT_LIST_CASE) | |
| 948 # printf(" 0x%05x: (%d, \"%s\"),\n", p, t, n); | |
| 949 # } | |
| 950 # printf("}\n"); | |
| 951 KNOWN_MAPS = { | |
| 952 0x08081: (135, "ByteArrayMap"), | |
| 953 0x080a9: (129, "MetaMap"), | |
| 954 0x080d1: (131, "OddballMap"), | |
| 955 0x080f9: (68, "AsciiInternalizedStringMap"), | |
| 956 0x08121: (167, "FixedArrayMap"), | |
| 957 0x08149: (133, "HeapNumberMap"), | |
| 958 0x08171: (136, "FreeSpaceMap"), | |
| 959 0x08199: (147, "OnePointerFillerMap"), | |
| 960 0x081c1: (147, "TwoPointerFillerMap"), | |
| 961 0x081e9: (132, "GlobalPropertyCellMap"), | |
| 962 0x08211: (168, "SharedFunctionInfoMap"), | |
| 963 0x08239: (167, "NativeContextMap"), | |
| 964 0x08261: (130, "CodeMap"), | |
| 965 0x08289: (167, "ScopeInfoMap"), | |
| 966 0x082b1: (167, "FixedCOWArrayMap"), | |
| 967 0x082d9: (146, "FixedDoubleArrayMap"), | |
| 968 0x08301: (167, "HashTableMap"), | |
| 969 0x08329: (128, "SymbolMap"), | |
| 970 0x08351: (0, "StringMap"), | |
| 971 0x08379: (4, "AsciiStringMap"), | |
| 972 0x083a1: (1, "ConsStringMap"), | |
| 973 0x083c9: (5, "ConsAsciiStringMap"), | |
| 974 0x083f1: (3, "SlicedStringMap"), | |
| 975 0x08419: (7, "SlicedAsciiStringMap"), | |
| 976 0x08441: (2, "ExternalStringMap"), | |
| 977 0x08469: (10, "ExternalStringWithAsciiDataMap"), | |
| 978 0x08491: (6, "ExternalAsciiStringMap"), | |
| 979 0x084b9: (18, "ShortExternalStringMap"), | |
| 980 0x084e1: (26, "ShortExternalStringWithAsciiDataMap"), | |
| 981 0x08509: (64, "InternalizedStringMap"), | |
| 982 0x08531: (65, "ConsInternalizedStringMap"), | |
| 983 0x08559: (69, "ConsAsciiInternalizedStringMap"), | |
| 984 0x08581: (66, "ExternalInternalizedStringMap"), | |
| 985 0x085a9: (74, "ExternalInternalizedStringWithAsciiDataMap"), | |
| 986 0x085d1: (70, "ExternalAsciiInternalizedStringMap"), | |
| 987 0x085f9: (82, "ShortExternalInternalizedStringMap"), | |
| 988 0x08621: (90, "ShortExternalInternalizedStringWithAsciiDataMap"), | |
| 989 0x08649: (86, "ShortExternalAsciiInternalizedStringMap"), | |
| 990 0x08671: (22, "ShortExternalAsciiStringMap"), | |
| 991 0x08699: (0, "UndetectableStringMap"), | |
| 992 0x086c1: (4, "UndetectableAsciiStringMap"), | |
| 993 0x086e9: (145, "ExternalPixelArrayMap"), | |
| 994 0x08711: (137, "ExternalByteArrayMap"), | |
| 995 0x08739: (138, "ExternalUnsignedByteArrayMap"), | |
| 996 0x08761: (139, "ExternalShortArrayMap"), | |
| 997 0x08789: (140, "ExternalUnsignedShortArrayMap"), | |
| 998 0x087b1: (141, "ExternalIntArrayMap"), | |
| 999 0x087d9: (142, "ExternalUnsignedIntArrayMap"), | |
| 1000 0x08801: (143, "ExternalFloatArrayMap"), | |
| 1001 0x08829: (144, "ExternalDoubleArrayMap"), | |
| 1002 0x08851: (167, "NonStrictArgumentsElementsMap"), | |
| 1003 0x08879: (167, "FunctionContextMap"), | |
| 1004 0x088a1: (167, "CatchContextMap"), | |
| 1005 0x088c9: (167, "WithContextMap"), | |
| 1006 0x088f1: (167, "BlockContextMap"), | |
| 1007 0x08919: (167, "ModuleContextMap"), | |
| 1008 0x08941: (167, "GlobalContextMap"), | |
| 1009 0x08969: (169, "JSMessageObjectMap"), | |
| 1010 0x08991: (134, "ForeignMap"), | |
| 1011 0x089b9: (174, "NeanderMap"), | |
| 1012 0x089e1: (159, "AllocationSiteInfoMap"), | |
| 1013 0x08a09: (162, "PolymorphicCodeCacheMap"), | |
| 1014 0x08a31: (160, "ScriptMap"), | |
| 1015 0x08a59: (174, ""), | |
| 1016 0x08a81: (174, "ExternalMap"), | |
| 1017 0x08aa9: (148, "DeclaredAccessorDescriptorMap"), | |
| 1018 0x08ad1: (149, "DeclaredAccessorInfoMap"), | |
| 1019 0x08af9: (150, "ExecutableAccessorInfoMap"), | |
| 1020 0x08b21: (151, "AccessorPairMap"), | |
| 1021 0x08b49: (152, "AccessCheckInfoMap"), | |
| 1022 0x08b71: (153, "InterceptorInfoMap"), | |
| 1023 0x08b99: (154, "CallHandlerInfoMap"), | |
| 1024 0x08bc1: (155, "FunctionTemplateInfoMap"), | |
| 1025 0x08be9: (156, "ObjectTemplateInfoMap"), | |
| 1026 0x08c11: (157, "SignatureInfoMap"), | |
| 1027 0x08c39: (158, "TypeSwitchInfoMap"), | |
| 1028 0x08c61: (161, "CodeCacheMap"), | |
| 1029 0x08c89: (163, "TypeFeedbackInfoMap"), | |
| 1030 0x08cb1: (164, "AliasedArgumentsEntryMap"), | |
| 1031 0x08cd9: (165, "DebugInfoMap"), | |
| 1032 0x08d01: (166, "BreakPointInfoMap"), | |
| 1033 } | |
| 1034 | |
| 1035 | |
| 1036 # List of known V8 objects. Used to determine name for objects that are | |
| 1037 # part of the root-set and hence on the first page of various old-space | |
| 1038 # paged. Obtained by adding the code below to an IA32 release build with | |
| 1039 # enabled snapshots to the end of the Isolate::Init method. | |
| 1040 # | |
| 1041 # #define ROOT_LIST_CASE(type, name, camel_name) \ | |
| 1042 # if (o == heap_.name()) n = #camel_name; | |
| 1043 # OldSpaces spit(heap()); | |
| 1044 # printf("KNOWN_OBJECTS = {\n"); | |
| 1045 # for (PagedSpace* s = spit.next(); s != NULL; s = spit.next()) { | |
| 1046 # HeapObjectIterator it(s); | |
| 1047 # const char* sname = AllocationSpaceName(s->identity()); | |
| 1048 # for (Object* o = it.Next(); o != NULL; o = it.Next()) { | |
| 1049 # const char* n = NULL; | |
| 1050 # intptr_t p = reinterpret_cast<intptr_t>(o) & 0xfffff; | |
| 1051 # ROOT_LIST(ROOT_LIST_CASE) | |
| 1052 # if (n != NULL) { | |
| 1053 # printf(" (\"%s\", 0x%05x): \"%s\",\n", sname, p, n); | |
| 1054 # } | |
| 1055 # } | |
| 1056 # } | |
| 1057 # printf("}\n"); | |
| 1058 KNOWN_OBJECTS = { | |
| 1059 ("OLD_POINTER_SPACE", 0x08081): "NullValue", | |
| 1060 ("OLD_POINTER_SPACE", 0x08091): "UndefinedValue", | |
| 1061 ("OLD_POINTER_SPACE", 0x080a1): "InstanceofCacheMap", | |
| 1062 ("OLD_POINTER_SPACE", 0x080b1): "TrueValue", | |
| 1063 ("OLD_POINTER_SPACE", 0x080c1): "FalseValue", | |
| 1064 ("OLD_POINTER_SPACE", 0x080d1): "NoInterceptorResultSentinel", | |
| 1065 ("OLD_POINTER_SPACE", 0x080e1): "ArgumentsMarker", | |
| 1066 ("OLD_POINTER_SPACE", 0x080f1): "NumberStringCache", | |
| 1067 ("OLD_POINTER_SPACE", 0x088f9): "SingleCharacterStringCache", | |
| 1068 ("OLD_POINTER_SPACE", 0x08b01): "StringSplitCache", | |
| 1069 ("OLD_POINTER_SPACE", 0x08f09): "RegExpMultipleCache", | |
| 1070 ("OLD_POINTER_SPACE", 0x09311): "TerminationException", | |
| 1071 ("OLD_POINTER_SPACE", 0x09321): "MessageListeners", | |
| 1072 ("OLD_POINTER_SPACE", 0x0933d): "CodeStubs", | |
| 1073 ("OLD_POINTER_SPACE", 0x09fa5): "NonMonomorphicCache", | |
| 1074 ("OLD_POINTER_SPACE", 0x0a5b9): "PolymorphicCodeCache", | |
| 1075 ("OLD_POINTER_SPACE", 0x0a5c1): "NativesSourceCache", | |
| 1076 ("OLD_POINTER_SPACE", 0x0a601): "EmptyScript", | |
| 1077 ("OLD_POINTER_SPACE", 0x0a63d): "IntrinsicFunctionNames", | |
| 1078 ("OLD_POINTER_SPACE", 0x0d659): "ObservationState", | |
| 1079 ("OLD_POINTER_SPACE", 0x27415): "SymbolTable", | |
| 1080 ("OLD_DATA_SPACE", 0x08099): "EmptyDescriptorArray", | |
| 1081 ("OLD_DATA_SPACE", 0x080a1): "EmptyFixedArray", | |
| 1082 ("OLD_DATA_SPACE", 0x080a9): "NanValue", | |
| 1083 ("OLD_DATA_SPACE", 0x08125): "EmptyByteArray", | |
| 1084 ("OLD_DATA_SPACE", 0x0812d): "EmptyString", | |
| 1085 ("OLD_DATA_SPACE", 0x08259): "InfinityValue", | |
| 1086 ("OLD_DATA_SPACE", 0x08265): "MinusZeroValue", | |
| 1087 ("OLD_DATA_SPACE", 0x08271): "PrototypeAccessors", | |
| 1088 ("CODE_SPACE", 0x0aea1): "JsEntryCode", | |
| 1089 ("CODE_SPACE", 0x0b5c1): "JsConstructEntryCode", | |
| 1090 } | |
| 1091 | |
| 1092 | |
| 1093 class Printer(object): | 843 class Printer(object): |
| 1094 """Printer with indentation support.""" | 844 """Printer with indentation support.""" |
| 1095 | 845 |
| 1096 def __init__(self): | 846 def __init__(self): |
| 1097 self.indent = 0 | 847 self.indent = 0 |
| 1098 | 848 |
| 1099 def Indent(self): | 849 def Indent(self): |
| 1100 self.indent += 2 | 850 self.indent += 2 |
| 1101 | 851 |
| 1102 def Dedent(self): | 852 def Dedent(self): |
| (...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 options, args = parser.parse_args() | 1982 options, args = parser.parse_args() |
| 2233 if os.path.exists(options.objdump): | 1983 if os.path.exists(options.objdump): |
| 2234 disasm.OBJDUMP_BIN = options.objdump | 1984 disasm.OBJDUMP_BIN = options.objdump |
| 2235 OBJDUMP_BIN = options.objdump | 1985 OBJDUMP_BIN = options.objdump |
| 2236 else: | 1986 else: |
| 2237 print "Cannot find %s, falling back to default objdump" % options.objdump | 1987 print "Cannot find %s, falling back to default objdump" % options.objdump |
| 2238 if len(args) != 1: | 1988 if len(args) != 1: |
| 2239 parser.print_help() | 1989 parser.print_help() |
| 2240 sys.exit(1) | 1990 sys.exit(1) |
| 2241 AnalyzeMinidump(options, args[0]) | 1991 AnalyzeMinidump(options, args[0]) |
| OLD | NEW |