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

Unified Diff: tools/findit/stacktrace.py

Issue 430943003: [Findit] Plain objects to represent and parse stack trace. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: changed wrong reference to stack frame Created 6 years, 5 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 side-by-side diff with in-line comments
Download patch
« tools/findit/component_dictionary.py ('K') | « tools/findit/crash_utils.py ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/findit/stacktrace.py
diff --git a/tools/findit/stacktrace.py b/tools/findit/stacktrace.py
new file mode 100644
index 0000000000000000000000000000000000000000..490750037166144e1e910c0502c0e852244bac73
--- /dev/null
+++ b/tools/findit/stacktrace.py
@@ -0,0 +1,169 @@
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+import os
+import re
+import crash_utils
+
+
+class Stacktrace(object):
+ """Represents Stacktrace object.
+
+ Contains release build stacktrace and debug build stacktrace.
+ """
+
+ def __init__(self, stacktrace, chrome_build):
+ self.stack_list = []
+ self.ParseStacktrace(stacktrace, chrome_build)
+
+ def ParseStacktrace(self, stacktrace, chrome_build):
+ """Parses stacktrace and normalizes it.
+
+ If there are multiple callstacks within the stacktrace,
+ it will parse each of them separately, and store them in the stack_list
+ variable.
+
+ Args:
+ stacktrace: a string containing stacktrace
+ chrome_build: a string containing the job type of the crash
+ """
+ # If the passed in string is empty, the object does not represent anything.
+ if not stacktrace:
+ self.stack_list = None
+ return
+
+ stack_frame_index_pattern = re.compile(r'#(\d+)')
+
+ # Reset the stack list, and assume we start from main thread.
+ self.stack_list = []
+ stack_priority = 0
+ seen_main_thread = False
stgao 2014/07/31 19:48:58 reach_new_callstack?
+ current_stack = CallStack(stack_priority)
+
+ for line in stacktrace:
+ # match the line to see if it is a valid stack frame
stgao 2014/07/31 19:48:58 nit: comment style
+ stack_frame_index_match = stack_frame_index_pattern.match(line)
+
+ # If this line does not represent the crashing information, continue.
+ if not stack_frame_index_match:
+ continue
+
+ # Get the stack frame index from the match
+ stack_frame_index = int(stack_frame_index_match.group(1))
+
+ # If it is 0, we need to check if this is from freed or prev-alloc, or
+ # is from main thead.
+ if stack_frame_index == 0:
+
+ # If this callstack is from main thread, update the boolean.
+ if not seen_main_thread:
+ seen_main_thread = True
+
+ # If this is from freed or prev-alloc, add the callstack we have
+ # to the list of callstacks, and increment the stack priority.
+ else:
+ self.stack_list.append(current_stack)
+ stack_priority += 1
+ current_stack = CallStack(stack_priority)
+
+ # Parse function name, file path and line number from the line.
+ parsed_stack_frame_line = self.ExtractFromStackFrame(
+ line, chrome_build)
+
+ # If the line is malformed, ignore this line. Else, get the info.
+ if not parsed_stack_frame_line:
+ continue
+ (function, file_path, crashed_line_number) = parsed_stack_frame_line
+
+ # Normalize the file path so that it can be compared to repository path.
+ file_name = os.path.basename(file_path)
+ (component, file_path) = crash_utils.NormalizePathLinux(file_path)
+
+ # Currently supports only blink and chromium.
+ if component == 'blink' or component == 'chromium':
+ current_stack.Add(
+ StackFrame(stack_frame_index, component, file_name,
+ function, file_path, crashed_line_number))
+
+ self.stack_list.append(current_stack)
+
+ def ExtractFromStackFrame(self, line, chrome_build):
stgao 2014/07/31 19:48:58 Used within class only. Add underscore before func
+ """Extracts information from a line in stacktrace.
+
+ Args:
+ line: a stacktrace string to extract data from
+ chrome_build: a string containing the job type
+ of this crash (e.g. linux_asan_chrome_mp)
+
+ Returns:
+ A triple containing the name of the function, the path of the file and
+ the line of crash
+ """
+ line_parts = line.split()
+ try:
+ # tsan has different stack frame style from other builds.
+ if chrome_build.startswith('linux_tsan'):
+ file_path_and_line = line_parts[-2]
+ function = ' '.join(line_parts[1:-2])
+
+ else:
+ file_path_and_line = line_parts[-1]
+ function = ' '.join(line_parts[3:-1])
+
+ # Get file path and line info from the line.
+ file_path_and_line = file_path_and_line.split(':')
+ file_path = file_path_and_line[0]
+ crashed_line_number = int(file_path_and_line[1])
+ return (function, file_path, crashed_line_number)
+
+ # Return None if the line is malformed.
+ except IndexError:
+ return None
+ except ValueError:
+ return None
+
+ def __getitem__(self, index):
+ return self.stack_list[index]
+
+ def GetStackFromMainThread(self):
+ return self.stack_list[0]
+
+
+class CallStack(object):
+ """Represents a call stack within a stacktrace.
+
+ It is a list of StackFrame object, and the stack represented by
+ this object is from main thread, freed thread or previously-allocated thread.
+ """
+
+ def __init__(self, stack_priority):
+ self.frame_list = []
+ self.priority = stack_priority
+
+ def Add(self, stacktrace_line):
+ self.frame_list.append(stacktrace_line)
+
+ def GetFirstN(self, n):
+ return self.frame_list[:n]
+
+
+class StackFrame(object):
+ """Represents a line in stacktrace.
+
+ Attributes:
+ index: index in the stacktrace
+ component: a component this line represents, such as blink, chrome, etc.
+ file_name: name of the file that crashed
+ function: function that caused the crash
+ file_path: path of the crashed file
+ crashed_line_number: line of the file that caused the crash
+ """
+
+ def __init__(self, stack_frame_index, component, file_name,
+ function, file_path, crashed_line_number):
+ self.index = stack_frame_index
+ self.component = component
+ self.file_name = file_name
+ self.function = function
+ self.file_path = file_path
+ self.crashed_line_number = crashed_line_number
« tools/findit/component_dictionary.py ('K') | « tools/findit/crash_utils.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698