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 1727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1738 | 1738 |
1739 def color_addresses(self): | 1739 def color_addresses(self): |
1740 # Color all stack addresses. | 1740 # Color all stack addresses. |
1741 exception_thread = self.reader.thread_map[self.reader.exception.thread_id] | 1741 exception_thread = self.reader.thread_map[self.reader.exception.thread_id] |
1742 stack_top = self.reader.ExceptionSP() | 1742 stack_top = self.reader.ExceptionSP() |
1743 stack_bottom = exception_thread.stack.start + \ | 1743 stack_bottom = exception_thread.stack.start + \ |
1744 exception_thread.stack.memory.data_size | 1744 exception_thread.stack.memory.data_size |
1745 frame_pointer = self.reader.ExceptionFP() | 1745 frame_pointer = self.reader.ExceptionFP() |
1746 self.styles[frame_pointer] = "frame" | 1746 self.styles[frame_pointer] = "frame" |
1747 for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): | 1747 for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): |
1748 self.styles[slot] = "stackaddress" | 1748 # stack address |
1749 self.styles[slot] = "sa" | |
1749 for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): | 1750 for slot in xrange(stack_top, stack_bottom, self.reader.PointerSize()): |
1750 maybe_address = self.reader.ReadUIntPtr(slot) | 1751 maybe_address = self.reader.ReadUIntPtr(slot) |
1751 self.styles[maybe_address] = "stackval" | 1752 # stack value |
1753 self.styles[maybe_address] = "sv" | |
1752 if slot == frame_pointer: | 1754 if slot == frame_pointer: |
1753 self.styles[slot] = "frame" | 1755 self.styles[slot] = "frame" |
1754 frame_pointer = maybe_address | 1756 frame_pointer = maybe_address |
1755 self.styles[self.reader.ExceptionIP()] = "pc" | 1757 self.styles[self.reader.ExceptionIP()] = "pc" |
1756 | 1758 |
1757 def get_style_class(self, address): | 1759 def get_style_class(self, address): |
1758 return self.styles.get(address, None) | 1760 return self.styles.get(address, None) |
1759 | 1761 |
1760 def get_style_class_string(self, address): | 1762 def get_style_class_string(self, address): |
1761 style = self.get_style_class(address) | 1763 style = self.get_style_class(address) |
1762 if style != None: | 1764 if style != None: |
1763 return " class=\"%s\" " % style | 1765 return " class=%s " % style |
1764 else: | 1766 else: |
1765 return "" | 1767 return "" |
1766 | 1768 |
1767 def set_comment(self, address, comment): | 1769 def set_comment(self, address, comment): |
1768 self.address_comments[address] = comment | 1770 self.address_comments[address] = comment |
1769 with open(self.comment_file, "a") as f: | 1771 with open(self.comment_file, "a") as f: |
1770 f.write("C 0x%x %s\n" % (address, comment)) | 1772 f.write("C 0x%x %s\n" % (address, comment)) |
1771 f.close() | 1773 f.close() |
1772 | 1774 |
1773 def get_comment(self, address): | 1775 def get_comment(self, address): |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1868 <meta content="text/html; charset=utf-8" http-equiv="content-type"> | 1870 <meta content="text/html; charset=utf-8" http-equiv="content-type"> |
1869 <style media="screen" type="text/css"> | 1871 <style media="screen" type="text/css"> |
1870 | 1872 |
1871 .code { | 1873 .code { |
1872 font-family: monospace; | 1874 font-family: monospace; |
1873 } | 1875 } |
1874 | 1876 |
1875 .dmptable { | 1877 .dmptable { |
1876 border-collapse : collapse; | 1878 border-collapse : collapse; |
1877 border-spacing : 0px; | 1879 border-spacing : 0px; |
1880 table-layout: fixed; | |
1878 } | 1881 } |
1879 | 1882 |
1880 .codedump { | 1883 .codedump { |
1881 border-collapse : collapse; | 1884 border-collapse : collapse; |
1882 border-spacing : 0px; | 1885 border-spacing : 0px; |
1886 table-layout: fixed; | |
1883 } | 1887 } |
1884 | 1888 |
1885 .addrcomments { | 1889 .addrcomments { |
1886 border : 0px; | 1890 border : 0px; |
1887 } | 1891 } |
1888 | 1892 |
1889 .register { | 1893 .register { |
1890 padding-right : 1em; | 1894 padding-right : 1em; |
1891 } | 1895 } |
1892 | 1896 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1925 } | 1929 } |
1926 | 1930 |
1927 .regions td { | 1931 .regions td { |
1928 padding:0 15px 0 15px; | 1932 padding:0 15px 0 15px; |
1929 } | 1933 } |
1930 | 1934 |
1931 .stackframe td { | 1935 .stackframe td { |
1932 background-color : cyan; | 1936 background-color : cyan; |
1933 } | 1937 } |
1934 | 1938 |
1935 .stackaddress { | 1939 .stackaddress, .sa { |
1936 background-color : LightGray; | 1940 background-color : LightGray; |
1937 } | 1941 } |
1938 | 1942 |
1939 .stackval { | 1943 .stackval, .sv { |
1940 background-color : LightCyan; | 1944 background-color : LightCyan; |
1941 } | 1945 } |
1942 | 1946 |
1943 .frame { | 1947 .frame { |
1944 background-color : cyan; | 1948 background-color : cyan; |
1945 } | 1949 } |
1946 | 1950 |
1947 .commentinput { | 1951 .commentinput, .ci { |
1948 width : 20em; | 1952 width : 20em; |
1949 } | 1953 } |
1950 | 1954 |
1951 a.nodump:visited { | 1955 /* a.nodump */ |
1956 a.nd:visited { | |
1952 color : black; | 1957 color : black; |
1953 text-decoration : none; | 1958 text-decoration : none; |
1954 } | 1959 } |
1955 | 1960 |
1956 a.nodump:link { | 1961 a.nd:link { |
1957 color : black; | 1962 color : black; |
1958 text-decoration : none; | 1963 text-decoration : none; |
1959 } | 1964 } |
1960 | 1965 |
1961 a:visited { | 1966 a:visited { |
1962 color : blueviolet; | 1967 color : blueviolet; |
1963 } | 1968 } |
1964 | 1969 |
1965 a:link { | 1970 a:link { |
1966 color : blue; | 1971 color : blue; |
(...skipping 10 matching lines...) Expand all Loading... | |
1977 var address_str = "address-"; | 1982 var address_str = "address-"; |
1978 var address_len = address_str.length; | 1983 var address_len = address_str.length; |
1979 | 1984 |
1980 function comment() { | 1985 function comment() { |
1981 var s = event.srcElement.id; | 1986 var s = event.srcElement.id; |
1982 var index = s.indexOf(address_str); | 1987 var index = s.indexOf(address_str); |
1983 if (index >= 0) { | 1988 if (index >= 0) { |
1984 send_comment(s.substring(index + address_len), event.srcElement.value); | 1989 send_comment(s.substring(index + address_len), event.srcElement.value); |
1985 } | 1990 } |
1986 } | 1991 } |
1992 var c = comment; | |
1987 | 1993 |
1988 function send_comment(address, comment) { | 1994 function send_comment(address, comment) { |
1989 xmlhttp = new XMLHttpRequest(); | 1995 xmlhttp = new XMLHttpRequest(); |
1990 address = encodeURIComponent(address) | 1996 address = encodeURIComponent(address) |
1991 comment = encodeURIComponent(comment) | 1997 comment = encodeURIComponent(comment) |
1992 xmlhttp.open("GET", | 1998 xmlhttp.open("GET", |
1993 "setcomment?%(query_dump)s&address=" + address + | 1999 "setcomment?%(query_dump)s&address=" + address + |
1994 "&comment=" + comment, true); | 2000 "&comment=" + comment, true); |
1995 xmlhttp.send(); | 2001 xmlhttp.send(); |
1996 } | 2002 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2031 xmlhttp.send(); | 2037 xmlhttp.send(); |
2032 } | 2038 } |
2033 | 2039 |
2034 </script> | 2040 </script> |
2035 | 2041 |
2036 <title>Dump %(dump_name)s</title> | 2042 <title>Dump %(dump_name)s</title> |
2037 </head> | 2043 </head> |
2038 | 2044 |
2039 <body> | 2045 <body> |
2040 <div class="header"> | 2046 <div class="header"> |
2041 <form class="navigation" action="search.html"> | 2047 <form class="navigation" action=/search.html"> |
Igor Sheludko
2016/09/21 11:29:59
DBC: I guess we are missing a " here.
| |
2042 <a href="summary.html?%(query_dump)s">Context info</a> | 2048 <a href="summary.html?%(query_dump)s">Context info</a> |
2043 <a href="info.html?%(query_dump)s">Dump info</a> | 2049 <a href="info.html?%(query_dump)s">Dump info</a> |
2044 <a href="modules.html?%(query_dump)s">Modules</a> | 2050 <a href="modules.html?%(query_dump)s">Modules</a> |
2045 | 2051 |
2046 <input type="search" name="val"> | 2052 <input type="search" name="val"> |
2047 <input type="submit" name="search" value="Search"> | 2053 <input type="submit" name="search" value="Search"> |
2048 <input type="hidden" name="dump" value="%(dump_name)s"> | 2054 <input type="hidden" name="dump" value="%(dump_name)s"> |
2049 </form> | 2055 </form> |
2050 <form class="navigation" action="disasm.html#highlight"> | 2056 <form class="navigation" action="disasm.html#highlight"> |
2051 | 2057 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2098 self.server.output_dumps(self.wfile) | 2104 self.server.output_dumps(self.wfile) |
2099 elif parsedurl.path == "/summary.html": | 2105 elif parsedurl.path == "/summary.html": |
2100 self.send_success_html_headers() | 2106 self.send_success_html_headers() |
2101 self.formatter(query_components).output_summary(self.wfile) | 2107 self.formatter(query_components).output_summary(self.wfile) |
2102 elif parsedurl.path == "/info.html": | 2108 elif parsedurl.path == "/info.html": |
2103 self.send_success_html_headers() | 2109 self.send_success_html_headers() |
2104 self.formatter(query_components).output_info(self.wfile) | 2110 self.formatter(query_components).output_info(self.wfile) |
2105 elif parsedurl.path == "/modules.html": | 2111 elif parsedurl.path == "/modules.html": |
2106 self.send_success_html_headers() | 2112 self.send_success_html_headers() |
2107 self.formatter(query_components).output_modules(self.wfile) | 2113 self.formatter(query_components).output_modules(self.wfile) |
2108 elif parsedurl.path == "/search.html": | 2114 elif parsedurl.path == "/search.html" or parsedurl.path == "/s": |
2109 address = query_components.get("val", []) | 2115 address = query_components.get("val", []) |
2110 if len(address) != 1: | 2116 if len(address) != 1: |
2111 self.send_error(404, "Invalid params") | 2117 self.send_error(404, "Invalid params") |
2112 return | 2118 return |
2113 self.send_success_html_headers() | 2119 self.send_success_html_headers() |
2114 self.formatter(query_components).output_search_res( | 2120 self.formatter(query_components).output_search_res( |
2115 self.wfile, address[0]) | 2121 self.wfile, address[0]) |
2116 elif parsedurl.path == "/disasm.html": | 2122 elif parsedurl.path == "/disasm.html": |
2117 address = query_components.get("val", []) | 2123 address = query_components.get("val", []) |
2118 exact = query_components.get("exact", ["on"]) | 2124 exact = query_components.get("exact", ["on"]) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2228 f.write("<td %s>" % self.comments.get_style_class_string(address)) | 2234 f.write("<td %s>" % self.comments.get_style_class_string(address)) |
2229 | 2235 |
2230 def format_address(self, maybeaddress, straddress = None): | 2236 def format_address(self, maybeaddress, straddress = None): |
2231 if maybeaddress is None: | 2237 if maybeaddress is None: |
2232 return "not in dump" | 2238 return "not in dump" |
2233 else: | 2239 else: |
2234 if straddress is None: | 2240 if straddress is None: |
2235 straddress = "0x" + self.reader.FormatIntPtr(maybeaddress) | 2241 straddress = "0x" + self.reader.FormatIntPtr(maybeaddress) |
2236 style_class = "" | 2242 style_class = "" |
2237 if not self.reader.IsValidAddress(maybeaddress): | 2243 if not self.reader.IsValidAddress(maybeaddress): |
2238 style_class = " class=\"nodump\"" | 2244 style_class = "class=nd" |
2239 return ("<a %s href=\"search.html?%s&val=%s\">%s</a>" % | 2245 return ("<a %s href=s?%s&val=%s>%s</a>" % |
2240 (style_class, self.encfilename, straddress, straddress)) | 2246 (style_class, self.encfilename, straddress, straddress)) |
2241 | 2247 |
2242 def output_header(self, f): | 2248 def output_header(self, f): |
2243 f.write(WEB_HEADER % | 2249 f.write(WEB_HEADER % |
2244 { "query_dump" : self.encfilename, | 2250 { "query_dump" : self.encfilename, |
2245 "dump_name" : cgi.escape(self.dumpfilename) }) | 2251 "dump_name" : cgi.escape(self.dumpfilename) }) |
2246 | 2252 |
2247 def output_footer(self, f): | 2253 def output_footer(self, f): |
2248 f.write(WEB_FOOTER) | 2254 f.write(WEB_FOOTER) |
2249 | 2255 |
(...skipping 11 matching lines...) Expand all Loading... | |
2261 min(exception_thread.stack.memory.data_size, self.MAX_CONTEXT_STACK) | 2267 min(exception_thread.stack.memory.data_size, self.MAX_CONTEXT_STACK) |
2262 stack_top = self.reader.ExceptionSP() | 2268 stack_top = self.reader.ExceptionSP() |
2263 self.output_words(f, stack_top - 16, stack_bottom, stack_top, "Stack") | 2269 self.output_words(f, stack_top - 16, stack_bottom, stack_top, "Stack") |
2264 | 2270 |
2265 f.write('</div>') | 2271 f.write('</div>') |
2266 self.output_footer(f) | 2272 self.output_footer(f) |
2267 return | 2273 return |
2268 | 2274 |
2269 def output_info(self, f): | 2275 def output_info(self, f): |
2270 self.output_header(f) | 2276 self.output_header(f) |
2271 f.write("<h3>Dump info</h3>\n") | 2277 f.write("<h3>Dump info</h3>") |
2272 f.write("Description: ") | 2278 f.write("Description: ") |
2273 self.server.output_dump_desc_field(f, self.dumpfilename) | 2279 self.server.output_dump_desc_field(f, self.dumpfilename) |
2274 f.write("<br>\n") | 2280 f.write("<br>") |
2275 f.write("Filename: ") | 2281 f.write("Filename: ") |
2276 f.write("<span class=\"code\">%s</span><br>\n" % (self.dumpfilename)) | 2282 f.write("<span class=\"code\">%s</span><br>" % (self.dumpfilename)) |
2277 dt = datetime.datetime.fromtimestamp(self.reader.header.time_date_stampt) | 2283 dt = datetime.datetime.fromtimestamp(self.reader.header.time_date_stampt) |
2278 f.write("Timestamp: %s<br>\n" % dt.strftime('%Y-%m-%d %H:%M:%S')) | 2284 f.write("Timestamp: %s<br>" % dt.strftime('%Y-%m-%d %H:%M:%S')) |
2279 self.output_context(f, InspectionWebFormatter.CONTEXT_FULL) | 2285 self.output_context(f, InspectionWebFormatter.CONTEXT_FULL) |
2280 self.output_address_ranges(f) | 2286 self.output_address_ranges(f) |
2281 self.output_footer(f) | 2287 self.output_footer(f) |
2282 return | 2288 return |
2283 | 2289 |
2284 def output_address_ranges(self, f): | 2290 def output_address_ranges(self, f): |
2285 regions = {} | 2291 regions = {} |
2286 def print_region(_reader, start, size, _location): | 2292 def print_region(_reader, start, size, _location): |
2287 regions[start] = size | 2293 regions[start] = size |
2288 self.reader.ForEachMemoryRegion(print_region) | 2294 self.reader.ForEachMemoryRegion(print_region) |
2289 f.write("<h3>Available memory regions</h3>\n") | 2295 f.write("<h3>Available memory regions</h3>") |
2290 f.write('<div class="code">') | 2296 f.write('<div class="code">') |
2291 f.write("<table class=\"regions\">\n") | 2297 f.write("<table class=\"regions\">") |
2292 f.write("<thead><tr>") | 2298 f.write("<thead><tr>") |
2293 f.write("<th>Start address</th>") | 2299 f.write("<th>Start address</th>") |
2294 f.write("<th>End address</th>") | 2300 f.write("<th>End address</th>") |
2295 f.write("<th>Number of bytes</th>") | 2301 f.write("<th>Number of bytes</th>") |
2296 f.write("</tr></thead>\n") | 2302 f.write("</tr></thead>") |
2297 for start in sorted(regions): | 2303 for start in sorted(regions): |
2298 size = regions[start] | 2304 size = regions[start] |
2299 f.write("<tr>") | 2305 f.write("<tr>") |
2300 f.write("<td>%s</td>" % self.format_address(start)) | 2306 f.write("<td>%s</td>" % self.format_address(start)) |
2301 f.write("<td> %s</td>" % self.format_address(start + size)) | 2307 f.write("<td> %s</td>" % self.format_address(start + size)) |
2302 f.write("<td> %d</td>" % size) | 2308 f.write("<td> %d</td>" % size) |
2303 f.write("</tr>\n") | 2309 f.write("</tr>") |
2304 f.write("</table>\n") | 2310 f.write("</table>") |
2305 f.write('</div>') | 2311 f.write('</div>') |
2306 return | 2312 return |
2307 | 2313 |
2308 def output_module_details(self, f, module): | 2314 def output_module_details(self, f, module): |
2309 f.write("<b>%s</b>" % GetModuleName(self.reader, module)) | 2315 f.write("<b>%s</b>" % GetModuleName(self.reader, module)) |
2310 file_version = GetVersionString(module.version_info.dwFileVersionMS, | 2316 file_version = GetVersionString(module.version_info.dwFileVersionMS, |
2311 module.version_info.dwFileVersionLS) | 2317 module.version_info.dwFileVersionLS) |
2312 product_version = GetVersionString(module.version_info.dwProductVersionMS, | 2318 product_version = GetVersionString(module.version_info.dwProductVersionMS, |
2313 module.version_info.dwProductVersionLS) | 2319 module.version_info.dwProductVersionLS) |
2314 f.write("<br> \n") | 2320 f.write("<br> ") |
2315 f.write("base: %s" % self.reader.FormatIntPtr(module.base_of_image)) | 2321 f.write("base: %s" % self.reader.FormatIntPtr(module.base_of_image)) |
2316 f.write("<br> \n") | 2322 f.write("<br> ") |
2317 f.write(" end: %s" % self.reader.FormatIntPtr(module.base_of_image + | 2323 f.write(" end: %s" % self.reader.FormatIntPtr(module.base_of_image + |
2318 module.size_of_image)) | 2324 module.size_of_image)) |
2319 f.write("<br> \n") | 2325 f.write("<br> ") |
2320 f.write(" file version: %s" % file_version) | 2326 f.write(" file version: %s" % file_version) |
2321 f.write("<br> \n") | 2327 f.write("<br> ") |
2322 f.write(" product version: %s" % product_version) | 2328 f.write(" product version: %s" % product_version) |
2323 f.write("<br> \n") | 2329 f.write("<br> ") |
2324 time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) | 2330 time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) |
2325 f.write(" timestamp: %s" % time_date_stamp) | 2331 f.write(" timestamp: %s" % time_date_stamp) |
2326 f.write("<br>\n"); | 2332 f.write("<br>"); |
2327 | 2333 |
2328 def output_modules(self, f): | 2334 def output_modules(self, f): |
2329 self.output_header(f) | 2335 self.output_header(f) |
2330 f.write('<div class="code">') | 2336 f.write('<div class="code">') |
2331 for module in self.reader.module_list.modules: | 2337 for module in self.reader.module_list.modules: |
2332 self.output_module_details(f, module) | 2338 self.output_module_details(f, module) |
2333 f.write("</div>") | 2339 f.write("</div>") |
2334 self.output_footer(f) | 2340 self.output_footer(f) |
2335 return | 2341 return |
2336 | 2342 |
2337 def output_context(self, f, details): | 2343 def output_context(self, f, details): |
2338 exception_thread = self.reader.thread_map[self.reader.exception.thread_id] | 2344 exception_thread = self.reader.thread_map[self.reader.exception.thread_id] |
2339 f.write("<h3>Exception context</h3>") | 2345 f.write("<h3>Exception context</h3>") |
2340 f.write('<div class="code">\n') | 2346 f.write('<div class="code">') |
2341 f.write("Thread id: %d" % exception_thread.id) | 2347 f.write("Thread id: %d" % exception_thread.id) |
2342 f.write(" Exception code: %08X<br/>\n" % | 2348 f.write(" Exception code: %08X<br/>" % |
2343 self.reader.exception.exception.code) | 2349 self.reader.exception.exception.code) |
2344 if details == InspectionWebFormatter.CONTEXT_FULL: | 2350 if details == InspectionWebFormatter.CONTEXT_FULL: |
2345 if self.reader.exception.exception.parameter_count > 0: | 2351 if self.reader.exception.exception.parameter_count > 0: |
2346 f.write(" Exception parameters: \n") | 2352 f.write(" Exception parameters: ") |
2347 for i in xrange(0, self.reader.exception.exception.parameter_count): | 2353 for i in xrange(0, self.reader.exception.exception.parameter_count): |
2348 f.write("%08x" % self.reader.exception.exception.information[i]) | 2354 f.write("%08x" % self.reader.exception.exception.information[i]) |
2349 f.write("<br><br>\n") | 2355 f.write("<br><br>") |
2350 | 2356 |
2351 for r in CONTEXT_FOR_ARCH[self.reader.arch]: | 2357 for r in CONTEXT_FOR_ARCH[self.reader.arch]: |
2352 f.write(HTML_REG_FORMAT % | 2358 f.write(HTML_REG_FORMAT % |
2353 (r, self.format_address(self.reader.Register(r)))) | 2359 (r, self.format_address(self.reader.Register(r)))) |
2354 # TODO(vitalyr): decode eflags. | 2360 # TODO(vitalyr): decode eflags. |
2355 if self.reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]: | 2361 if self.reader.arch in [MD_CPU_ARCHITECTURE_ARM, MD_CPU_ARCHITECTURE_ARM64]: |
2356 f.write("<b>cpsr</b>: %s" % bin(self.reader.exception_context.cpsr)[2:]) | 2362 f.write("<b>cpsr</b>: %s" % bin(self.reader.exception_context.cpsr)[2:]) |
2357 else: | 2363 else: |
2358 f.write("<b>eflags</b>: %s" % | 2364 f.write("<b>eflags</b>: %s" % |
2359 bin(self.reader.exception_context.eflags)[2:]) | 2365 bin(self.reader.exception_context.eflags)[2:]) |
2360 f.write('</div>\n') | 2366 f.write('</div>') |
2361 return | 2367 return |
2362 | 2368 |
2363 def align_down(self, a, size): | 2369 def align_down(self, a, size): |
2364 alignment_correction = a % size | 2370 alignment_correction = a % size |
2365 return a - alignment_correction | 2371 return a - alignment_correction |
2366 | 2372 |
2367 def align_up(self, a, size): | 2373 def align_up(self, a, size): |
2368 alignment_correction = (size - 1) - ((a + size - 1) % size) | 2374 alignment_correction = (size - 1) - ((a + size - 1) % size) |
2369 return a + alignment_correction | 2375 return a + alignment_correction |
2370 | 2376 |
(...skipping 16 matching lines...) Expand all Loading... | |
2387 self.output_footer(f) | 2393 self.output_footer(f) |
2388 | 2394 |
2389 except ValueError: | 2395 except ValueError: |
2390 f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress) | 2396 f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress) |
2391 return | 2397 return |
2392 | 2398 |
2393 def output_words(self, f, start_address, end_address, | 2399 def output_words(self, f, start_address, end_address, |
2394 highlight_address, desc): | 2400 highlight_address, desc): |
2395 region = self.reader.FindRegion(highlight_address) | 2401 region = self.reader.FindRegion(highlight_address) |
2396 if region is None: | 2402 if region is None: |
2397 f.write("<h3>Address 0x%x not found in the dump.</h3>\n" % | 2403 f.write("<h3>Address 0x%x not found in the dump.</h3>" % |
2398 (highlight_address)) | 2404 (highlight_address)) |
2399 return | 2405 return |
2400 size = self.heap.PointerSize() | 2406 size = self.heap.PointerSize() |
2401 start_address = self.align_down(start_address, size) | 2407 start_address = self.align_down(start_address, size) |
2402 low = self.align_down(region[0], size) | 2408 low = self.align_down(region[0], size) |
2403 high = self.align_up(region[0] + region[1], size) | 2409 high = self.align_up(region[0] + region[1], size) |
2404 if start_address < low: | 2410 if start_address < low: |
2405 start_address = low | 2411 start_address = low |
2406 end_address = self.align_up(end_address, size) | 2412 end_address = self.align_up(end_address, size) |
2407 if end_address > high: | 2413 if end_address > high: |
2408 end_address = high | 2414 end_address = high |
2409 | 2415 |
2410 expand = "" | 2416 expand = "" |
2411 if start_address != low or end_address != high: | 2417 if start_address != low or end_address != high: |
2412 expand = ("(<a href=\"data.html?%s&val=0x%x#highlight\">" | 2418 expand = ("(<a href=\"data.html?%s&val=0x%x#highlight\">" |
2413 " more..." | 2419 " more..." |
2414 " </a>)" % | 2420 " </a>)" % |
2415 (self.encfilename, highlight_address)) | 2421 (self.encfilename, highlight_address)) |
2416 | 2422 |
2417 f.write("<h3>%s 0x%x - 0x%x, " | 2423 f.write("<h3>%s 0x%x - 0x%x, " |
2418 "highlighting <a href=\"#highlight\">0x%x</a> %s</h3>\n" % | 2424 "highlighting <a href=\"#highlight\">0x%x</a> %s</h3>" % |
2419 (desc, start_address, end_address, highlight_address, expand)) | 2425 (desc, start_address, end_address, highlight_address, expand)) |
2420 f.write('<div class="code">') | 2426 f.write('<div class="code">') |
2421 f.write("<table class=\"codedump\">\n") | 2427 f.write("<table class=codedump>") |
2422 | 2428 |
2423 for j in xrange(0, end_address - start_address, size): | 2429 for j in xrange(0, end_address - start_address, size): |
2424 slot = start_address + j | 2430 slot = start_address + j |
2425 heap_object = "" | 2431 heap_object = "" |
2426 maybe_address = None | 2432 maybe_address = None |
2427 end_region = region[0] + region[1] | 2433 end_region = region[0] + region[1] |
2428 if slot < region[0] or slot + size > end_region: | 2434 if slot < region[0] or slot + size > end_region: |
2429 straddress = "0x" | 2435 straddress = "0x" |
2430 for i in xrange(end_region, slot + size): | 2436 for i in xrange(end_region, slot + size): |
2431 straddress += "??" | 2437 straddress += "??" |
2432 for i in reversed( | 2438 for i in reversed( |
2433 xrange(max(slot, region[0]), min(slot + size, end_region))): | 2439 xrange(max(slot, region[0]), min(slot + size, end_region))): |
2434 straddress += "%02x" % self.reader.ReadU8(i) | 2440 straddress += "%02x" % self.reader.ReadU8(i) |
2435 for i in xrange(slot, region[0]): | 2441 for i in xrange(slot, region[0]): |
2436 straddress += "??" | 2442 straddress += "??" |
2437 else: | 2443 else: |
2438 maybe_address = self.reader.ReadUIntPtr(slot) | 2444 maybe_address = self.reader.ReadUIntPtr(slot) |
2439 straddress = self.format_address(maybe_address) | 2445 straddress = self.format_address(maybe_address) |
2440 if maybe_address: | 2446 if maybe_address: |
2441 heap_object = self.format_object(maybe_address) | 2447 heap_object = self.format_object(maybe_address) |
2442 | 2448 |
2443 address_fmt = "%s </td>\n" | 2449 address_fmt = "%s </td>" |
2444 if slot == highlight_address: | 2450 if slot == highlight_address: |
2445 f.write("<tr class=\"highlight-line\">\n") | 2451 f.write("<tr class=highlight-line>") |
2446 address_fmt = "<a id=\"highlight\"></a>%s </td>\n" | 2452 address_fmt = "<a id=highlight></a>%s </td>" |
2447 elif slot < highlight_address and highlight_address < slot + size: | 2453 elif slot < highlight_address and highlight_address < slot + size: |
2448 f.write("<tr class=\"inexact-highlight-line\">\n") | 2454 f.write("<tr class=inexact-highlight-line>") |
2449 address_fmt = "<a id=\"highlight\"></a>%s </td>\n" | 2455 address_fmt = "<a id=highlight></a>%s </td>" |
2450 else: | 2456 else: |
2451 f.write("<tr>\n") | 2457 f.write("<tr>") |
2452 | 2458 |
2453 f.write(" <td>") | 2459 f.write("<td>") |
2454 self.output_comment_box(f, "da-", slot) | 2460 self.output_comment_box(f, "da-", slot) |
2455 f.write("</td>\n") | 2461 f.write("</td>") |
2456 f.write(" ") | |
2457 self.td_from_address(f, slot) | 2462 self.td_from_address(f, slot) |
2458 f.write(address_fmt % self.format_address(slot)) | 2463 f.write(address_fmt % self.format_address(slot)) |
2459 f.write(" ") | |
2460 self.td_from_address(f, maybe_address) | 2464 self.td_from_address(f, maybe_address) |
2461 f.write(": %s </td>\n" % straddress) | 2465 f.write(": %s </td>" % straddress) |
2462 f.write(" <td>") | 2466 f.write("<td>") |
2463 if maybe_address != None: | 2467 if maybe_address != None: |
2464 self.output_comment_box( | 2468 self.output_comment_box( |
2465 f, "sv-" + self.reader.FormatIntPtr(slot), maybe_address) | 2469 f, "sv-" + self.reader.FormatIntPtr(slot), maybe_address) |
2466 f.write(" </td>\n") | 2470 f.write("</td>") |
2467 f.write(" <td>%s</td>\n" % (heap_object or '')) | 2471 f.write("<td>%s</td>" % (heap_object or '')) |
2468 f.write("</tr>\n") | 2472 f.write("</tr>") |
2469 f.write("</table>\n") | 2473 f.write("</table>") |
2470 f.write("</div>") | 2474 f.write("</div>") |
2471 return | 2475 return |
2472 | 2476 |
2473 def output_ascii(self, f, start_address, end_address, highlight_address): | 2477 def output_ascii(self, f, start_address, end_address, highlight_address): |
2474 region = self.reader.FindRegion(highlight_address) | 2478 region = self.reader.FindRegion(highlight_address) |
2475 if region is None: | 2479 if region is None: |
2476 f.write("<h3>Address %x not found in the dump.</h3>" % | 2480 f.write("<h3>Address %x not found in the dump.</h3>" % |
2477 highlight_address) | 2481 highlight_address) |
2478 return | 2482 return |
2479 if start_address < region[0]: | 2483 if start_address < region[0]: |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2558 exactness = "" | 2562 exactness = "" |
2559 if exact and not found and end_address == region[0] + region[1]: | 2563 if exact and not found and end_address == region[0] + region[1]: |
2560 exactness = "&exact=off" | 2564 exactness = "&exact=off" |
2561 expand = ("(<a href=\"disasm.html?%s%s" | 2565 expand = ("(<a href=\"disasm.html?%s%s" |
2562 "&val=0x%x#highlight\">more...</a>)" % | 2566 "&val=0x%x#highlight\">more...</a>)" % |
2563 (self.encfilename, exactness, highlight_address)) | 2567 (self.encfilename, exactness, highlight_address)) |
2564 | 2568 |
2565 f.write("<h3>Disassembling 0x%x - 0x%x, highlighting 0x%x %s</h3>" % | 2569 f.write("<h3>Disassembling 0x%x - 0x%x, highlighting 0x%x %s</h3>" % |
2566 (start_address, end_address, highlight_address, expand)) | 2570 (start_address, end_address, highlight_address, expand)) |
2567 f.write('<div class="code">') | 2571 f.write('<div class="code">') |
2568 f.write("<table class=\"codedump\">\n"); | 2572 f.write("<table class=\"codedump\">"); |
2569 for i in xrange(len(lines)): | 2573 for i in xrange(len(lines)): |
2570 line = lines[i] | 2574 line = lines[i] |
2571 next_address = count | 2575 next_address = count |
2572 if i + 1 < len(lines): | 2576 if i + 1 < len(lines): |
2573 next_line = lines[i + 1] | 2577 next_line = lines[i + 1] |
2574 next_address = next_line[0] | 2578 next_address = next_line[0] |
2575 self.format_disasm_line( | 2579 self.format_disasm_line( |
2576 f, start_address, line, next_address, highlight_address) | 2580 f, start_address, line, next_address, highlight_address) |
2577 f.write("</table>\n") | 2581 f.write("</table>") |
2578 f.write("</div>") | 2582 f.write("</div>") |
2579 return | 2583 return |
2580 | 2584 |
2581 def annotate_disasm_addresses(self, line): | 2585 def annotate_disasm_addresses(self, line): |
2582 extra = [] | 2586 extra = [] |
2583 for m in ADDRESS_RE.finditer(line): | 2587 for m in ADDRESS_RE.finditer(line): |
2584 maybe_address = int(m.group(0), 16) | 2588 maybe_address = int(m.group(0), 16) |
2585 formatted_address = self.format_address(maybe_address, m.group(0)) | 2589 formatted_address = self.format_address(maybe_address, m.group(0)) |
2586 line = line.replace(m.group(0), formatted_address) | 2590 line = line.replace(m.group(0), formatted_address) |
2587 object_info = self.padawan.SenseObject(maybe_address) | 2591 object_info = self.padawan.SenseObject(maybe_address) |
2588 if not object_info: | 2592 if not object_info: |
2589 continue | 2593 continue |
2590 extra.append(cgi.escape(str(object_info))) | 2594 extra.append(cgi.escape(str(object_info))) |
2591 if len(extra) == 0: | 2595 if len(extra) == 0: |
2592 return line | 2596 return line |
2593 return ("%s <span class=\"disasmcomment\">;; %s</span>" % | 2597 return ("%s <span class=disasmcomment>;; %s</span>" % |
2594 (line, ", ".join(extra))) | 2598 (line, ", ".join(extra))) |
2595 | 2599 |
2596 def format_disasm_line( | 2600 def format_disasm_line( |
2597 self, f, start, line, next_address, highlight_address): | 2601 self, f, start, line, next_address, highlight_address): |
2598 line_address = start + line[0] | 2602 line_address = start + line[0] |
2599 address_fmt = " <td>%s</td>\n" | 2603 address_fmt = " <td>%s</td>" |
2600 if line_address == highlight_address: | 2604 if line_address == highlight_address: |
2601 f.write("<tr class=\"highlight-line\">\n") | 2605 f.write("<tr class=highlight-line>") |
2602 address_fmt = " <td><a id=\"highlight\">%s</a></td>\n" | 2606 address_fmt = " <td><a id=highlight>%s</a></td>" |
2603 elif (line_address < highlight_address and | 2607 elif (line_address < highlight_address and |
2604 highlight_address < next_address + start): | 2608 highlight_address < next_address + start): |
2605 f.write("<tr class=\"inexact-highlight-line\">\n") | 2609 f.write("<tr class=inexact-highlight-line>") |
2606 address_fmt = " <td><a id=\"highlight\">%s</a></td>\n" | 2610 address_fmt = " <td><a id=highlight>%s</a></td>" |
2607 else: | 2611 else: |
2608 f.write("<tr>\n") | 2612 f.write("<tr>") |
2609 num_bytes = next_address - line[0] | 2613 num_bytes = next_address - line[0] |
2610 stack_slot = self.heap.stack_map.get(line_address) | 2614 stack_slot = self.heap.stack_map.get(line_address) |
2611 marker = "" | 2615 marker = "" |
2612 if stack_slot: | 2616 if stack_slot: |
2613 marker = "=>" | 2617 marker = "=>" |
2614 op_offset = 3 * num_bytes - 1 | 2618 op_offset = 3 * num_bytes - 1 |
2615 | 2619 |
2616 code = line[1] | 2620 code = line[1] |
2617 # Compute the actual call target which the disassembler is too stupid | 2621 # Compute the actual call target which the disassembler is too stupid |
2618 # to figure out (it adds the call offset to the disassembly offset rather | 2622 # to figure out (it adds the call offset to the disassembly offset rather |
2619 # than the absolute instruction address). | 2623 # than the absolute instruction address). |
2620 if self.heap.reader.arch == MD_CPU_ARCHITECTURE_X86: | 2624 if self.heap.reader.arch == MD_CPU_ARCHITECTURE_X86: |
2621 if code.startswith("e8"): | 2625 if code.startswith("e8"): |
2622 words = code.split() | 2626 words = code.split() |
2623 if len(words) > 6 and words[5] == "call": | 2627 if len(words) > 6 and words[5] == "call": |
2624 offset = int(words[4] + words[3] + words[2] + words[1], 16) | 2628 offset = int(words[4] + words[3] + words[2] + words[1], 16) |
2625 target = (line_address + offset + 5) & 0xFFFFFFFF | 2629 target = (line_address + offset + 5) & 0xFFFFFFFF |
2626 code = code.replace(words[6], "0x%08x" % target) | 2630 code = code.replace(words[6], "0x%08x" % target) |
2627 # TODO(jkummerow): port this hack to ARM and x64. | 2631 # TODO(jkummerow): port this hack to ARM and x64. |
2628 | 2632 |
2629 opcodes = code[:op_offset] | 2633 opcodes = code[:op_offset] |
2630 code = self.annotate_disasm_addresses(code[op_offset:]) | 2634 code = self.annotate_disasm_addresses(code[op_offset:]) |
2631 f.write(" <td>") | 2635 f.write(" <td>") |
2632 self.output_comment_box(f, "codel-", line_address) | 2636 self.output_comment_box(f, "codel-", line_address) |
2633 f.write("</td>\n") | 2637 f.write("</td>") |
2634 f.write(address_fmt % marker) | 2638 f.write(address_fmt % marker) |
2635 f.write(" ") | 2639 f.write(" ") |
2636 self.td_from_address(f, line_address) | 2640 self.td_from_address(f, line_address) |
2637 f.write("%s (+0x%x)</td>\n" % | 2641 f.write(self.format_address(line_address)) |
2638 (self.format_address(line_address), line[0])) | 2642 f.write(" (+0x%x)</td>" % line[0]) |
2639 f.write(" <td>: %s </td>\n" % opcodes) | 2643 f.write("<td>: %s </td>" % opcodes) |
2640 f.write(" <td>%s</td>\n" % code) | 2644 f.write("<td>%s</td>" % code) |
2641 f.write("</tr>\n") | 2645 f.write("</tr>") |
2642 | 2646 |
2643 def output_comment_box(self, f, prefix, address): | 2647 def output_comment_box(self, f, prefix, address): |
2644 f.write("<input type=\"text\" class=\"commentinput\" " | 2648 comment = self.comments.get_comment(address) |
2645 "id=\"%s-address-0x%s\" onchange=\"comment()\" value=\"%s\">" % | 2649 value = "" |
2650 if comment: | |
2651 value = " value=\"%s\"" % cgi.escape(comment) | |
2652 f.write("<input type=text class=ci " | |
2653 "id=%s-address-0x%s onchange=c()%s>" % | |
2646 (prefix, | 2654 (prefix, |
2647 self.reader.FormatIntPtr(address), | 2655 self.reader.FormatIntPtr(address), |
2648 cgi.escape(self.comments.get_comment(address)) or "")) | 2656 value)) |
2649 | 2657 |
2650 MAX_FOUND_RESULTS = 100 | 2658 MAX_FOUND_RESULTS = 100 |
2651 | 2659 |
2652 def output_find_results(self, f, results): | 2660 def output_find_results(self, f, results): |
2653 f.write("Addresses") | 2661 f.write("Addresses") |
2654 toomany = len(results) > self.MAX_FOUND_RESULTS | 2662 toomany = len(results) > self.MAX_FOUND_RESULTS |
2655 if toomany: | 2663 if toomany: |
2656 f.write("(found %i results, displaying only first %i)" % | 2664 f.write("(found %i results, displaying only first %i)" % |
2657 (len(results), self.MAX_FOUND_RESULTS)) | 2665 (len(results), self.MAX_FOUND_RESULTS)) |
2658 f.write(": \n") | 2666 f.write(": ") |
2659 results = sorted(results) | 2667 results = sorted(results) |
2660 results = results[:min(len(results), self.MAX_FOUND_RESULTS)] | 2668 results = results[:min(len(results), self.MAX_FOUND_RESULTS)] |
2661 for address in results: | 2669 for address in results: |
2662 f.write("<span %s>%s</span>\n" % | 2670 f.write("<span %s>%s</span>" % |
2663 (self.comments.get_style_class_string(address), | 2671 (self.comments.get_style_class_string(address), |
2664 self.format_address(address))) | 2672 self.format_address(address))) |
2665 if toomany: | 2673 if toomany: |
2666 f.write("...\n") | 2674 f.write("...") |
2667 | 2675 |
2668 | 2676 |
2669 def output_page_info(self, f, page_kind, page_address, my_page_address): | 2677 def output_page_info(self, f, page_kind, page_address, my_page_address): |
2670 if my_page_address == page_address and page_address != 0: | 2678 if my_page_address == page_address and page_address != 0: |
2671 f.write("Marked first %s page.\n" % page_kind) | 2679 f.write("Marked first %s page." % page_kind) |
2672 else: | 2680 else: |
2673 f.write("<span id=\"%spage\" style=\"display:none\">" % page_kind) | 2681 f.write("<span id=\"%spage\" style=\"display:none\">" % page_kind) |
2674 f.write("Marked first %s page." % page_kind) | 2682 f.write("Marked first %s page." % page_kind) |
2675 f.write("</span>\n") | 2683 f.write("</span>\n") |
2676 f.write("<button onclick=\"onpage('%spage', '0x%x')\">" % | 2684 f.write("<button onclick=\"onpage('%spage', '0x%x')\">" % |
2677 (page_kind, my_page_address)) | 2685 (page_kind, my_page_address)) |
2678 f.write("Mark as first %s page</button>\n" % page_kind) | 2686 f.write("Mark as first %s page</button>" % page_kind) |
2679 return | 2687 return |
2680 | 2688 |
2681 def output_search_res(self, f, straddress): | 2689 def output_search_res(self, f, straddress): |
2682 try: | 2690 try: |
2683 self.output_header(f) | 2691 self.output_header(f) |
2684 f.write("<h3>Search results for %s</h3>" % straddress) | 2692 f.write("<h3>Search results for %s</h3>" % straddress) |
2685 | 2693 |
2686 address = int(straddress, 0) | 2694 address = int(straddress, 0) |
2687 | 2695 |
2688 f.write("Comment: ") | 2696 f.write("Comment: ") |
2689 self.output_comment_box(f, "search-", address) | 2697 self.output_comment_box(f, "search-", address) |
2690 f.write("<br>\n") | 2698 f.write("<br>") |
2691 | 2699 |
2692 page_address = address & ~self.heap.PageAlignmentMask() | 2700 page_address = address & ~self.heap.PageAlignmentMask() |
2693 | 2701 |
2694 f.write("Page info: \n") | 2702 f.write("Page info: ") |
2695 self.output_page_info(f, "old", self.padawan.known_first_old_page, \ | 2703 self.output_page_info(f, "old", self.padawan.known_first_old_page, \ |
2696 page_address) | 2704 page_address) |
2697 self.output_page_info(f, "map", self.padawan.known_first_map_page, \ | 2705 self.output_page_info(f, "map", self.padawan.known_first_map_page, \ |
2698 page_address) | 2706 page_address) |
2699 | 2707 |
2700 if not self.reader.IsValidAddress(address): | 2708 if not self.reader.IsValidAddress(address): |
2701 f.write("<h3>The contents at address %s not found in the dump.</h3>" % \ | 2709 f.write("<h3>The contents at address %s not found in the dump.</h3>" % \ |
2702 straddress) | 2710 straddress) |
2703 else: | 2711 else: |
2704 # Print as words | 2712 # Print as words |
2705 self.output_words(f, address - 8, address + 32, address, "Dump") | 2713 self.output_words(f, address - 8, address + 32, address, "Dump") |
2706 | 2714 |
2707 # Print as ASCII | 2715 # Print as ASCII |
2708 f.write("<hr>\n") | 2716 f.write("<hr>") |
2709 self.output_ascii(f, address, address + 256, address) | 2717 self.output_ascii(f, address, address + 256, address) |
2710 | 2718 |
2711 # Print as code | 2719 # Print as code |
2712 f.write("<hr>\n") | 2720 f.write("<hr>") |
2713 self.output_disasm_range(f, address - 16, address + 16, address, True) | 2721 self.output_disasm_range(f, address - 16, address + 16, address, True) |
2714 | 2722 |
2715 aligned_res, unaligned_res = self.reader.FindWordList(address) | 2723 aligned_res, unaligned_res = self.reader.FindWordList(address) |
2716 | 2724 |
2717 if len(aligned_res) > 0: | 2725 if len(aligned_res) > 0: |
2718 f.write("<h3>Occurrences of 0x%x at aligned addresses</h3>\n" % | 2726 f.write("<h3>Occurrences of 0x%x at aligned addresses</h3>" % |
2719 address) | 2727 address) |
2720 self.output_find_results(f, aligned_res) | 2728 self.output_find_results(f, aligned_res) |
2721 | 2729 |
2722 if len(unaligned_res) > 0: | 2730 if len(unaligned_res) > 0: |
2723 f.write("<h3>Occurrences of 0x%x at unaligned addresses</h3>\n" % \ | 2731 f.write("<h3>Occurrences of 0x%x at unaligned addresses</h3>" % \ |
2724 address) | 2732 address) |
2725 self.output_find_results(f, unaligned_res) | 2733 self.output_find_results(f, unaligned_res) |
2726 | 2734 |
2727 if len(aligned_res) + len(unaligned_res) == 0: | 2735 if len(aligned_res) + len(unaligned_res) == 0: |
2728 f.write("<h3>No occurences of 0x%x found in the dump</h3>\n" % address) | 2736 f.write("<h3>No occurences of 0x%x found in the dump</h3>" % address) |
2729 | 2737 |
2730 self.output_footer(f) | 2738 self.output_footer(f) |
2731 | 2739 |
2732 except ValueError: | 2740 except ValueError: |
2733 f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress) | 2741 f.write("<h3>Unrecognized address format \"%s\".</h3>" % straddress) |
2734 return | 2742 return |
2735 | 2743 |
2736 def output_disasm_pc(self, f): | 2744 def output_disasm_pc(self, f): |
2737 address = self.reader.ExceptionIP() | 2745 address = self.reader.ExceptionIP() |
2738 if not self.reader.IsValidAddress(address): | 2746 if not self.reader.IsValidAddress(address): |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3276 try: | 3284 try: |
3277 server = InspectionWebServer(PORT_NUMBER, options, args[0]) | 3285 server = InspectionWebServer(PORT_NUMBER, options, args[0]) |
3278 print 'Started httpserver on port ' , PORT_NUMBER | 3286 print 'Started httpserver on port ' , PORT_NUMBER |
3279 webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER) | 3287 webbrowser.open('http://localhost:%i/summary.html' % PORT_NUMBER) |
3280 server.serve_forever() | 3288 server.serve_forever() |
3281 except KeyboardInterrupt: | 3289 except KeyboardInterrupt: |
3282 print '^C received, shutting down the web server' | 3290 print '^C received, shutting down the web server' |
3283 server.socket.close() | 3291 server.socket.close() |
3284 else: | 3292 else: |
3285 AnalyzeMinidump(options, args[0]) | 3293 AnalyzeMinidump(options, args[0]) |
OLD | NEW |