Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / findit / component_dictionary.py
1 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import os
6
7
8 class FileDictionary(object):
9   """Maps file in a stacktrace to its crash information.
10
11   It maps file to another dictionary, which maps the file's path to crashed
12   lines, stack frame indices and crashed functions.
13   """
14
15   def __init__(self):
16     """Initializes the file dictionary."""
17     self.file_dict = {}
18
19   def AddFile(self, file_name, file_path, crashed_line_number,
20               stack_frame_index, function):
21     """Adds file and its crash information to the map.
22
23     Args:
24       file_name: The name of the crashed file.
25       file_path: The path of the crashed file.
26       crashed_line_number: The crashed line of the file.
27       stack_frame_index: The file's position in the callstack.
28       function: The name of the crashed function.
29     """
30     # Populate the dictionary if this file/path has not been added before.
31     if file_name not in self.file_dict:
32       self.file_dict[file_name] = {}
33
34     if file_path not in self.file_dict[file_name]:
35       self.file_dict[file_name][file_path] = {}
36       self.file_dict[file_name][file_path]['line_numbers'] = []
37       self.file_dict[file_name][file_path]['stack_frame_indices'] = []
38       self.file_dict[file_name][file_path]['function'] = []
39
40     # Add the crashed line, frame index and function name.
41     self.file_dict[file_name][file_path]['line_numbers'].append(
42         crashed_line_number)
43     self.file_dict[file_name][file_path]['stack_frame_indices'].append(
44         stack_frame_index)
45     self.file_dict[file_name][file_path]['function'].append(function)
46
47   def GetPathDic(self, file_name):
48     """Returns file's path and crash information."""
49     return self.file_dict[file_name]
50
51   def GetCrashedLineNumbers(self, file_path):
52     """Returns crashed line numbers given a file path."""
53     file_name = os.path.basename(file_path)
54     return self.file_dict[file_name][file_path]['line_numbers']
55
56   def GetCrashStackFrameindex(self, file_path):
57     """Returns stack frame indices given a file path."""
58     file_name = os.path.basename(file_path)
59     return self.file_dict[file_name][file_path]['stack_frame_indices']
60
61   def GetCrashFunction(self, file_path):
62     """Returns list of crashed functions given a file path."""
63     file_name = os.path.basename(file_path)
64     return self.file_dict[file_name][file_path]['function']
65
66   def __iter__(self):
67     return iter(self.file_dict)
68
69
70 class ComponentDictionary(object):
71   """Represents a file dictionary.
72
73   It maps each component path to a file dictionary.
74   """
75
76   def __init__(self, callstack, components):
77     """Initializes the dictionary with given components."""
78     self.component_dict = {}
79
80     # Create file dictionary for all the components.
81     for component in components:
82       self.component_dict[component] = FileDictionary()
83
84     # Create file dict from callstack.
85     self.__CreateFileDictFromCallstack(callstack)
86
87   def GetFileDict(self, component):
88     """Returns a file dictionary for a given component."""
89     return self.component_dict.get(component)
90
91   def __GenerateFileDict(self, stack_frame_list):
92     """Generates file dictionary, given an instance of StackFrame list."""
93     # Iterate through the list of stackframe objects.
94     for stack_frame in stack_frame_list:
95       # If the component of this line is not in the list of components to
96       # look for, ignore this line.
97       component_path = stack_frame.component_path
98       if component_path not in self.component_dict:
99         continue
100
101       # Get values of the variables
102       file_name = stack_frame.file_name
103       file_path = stack_frame.file_path
104       crashed_line_number = stack_frame.crashed_line_number
105       stack_frame_index = stack_frame.index
106       function = stack_frame.function
107
108       # Add the file to this component's dictionary of files.
109       file_dict = self.component_dict[component_path]
110       file_dict.AddFile(file_name, file_path, crashed_line_number,
111                         stack_frame_index, function)
112
113   def __CreateFileDictFromCallstack(self, callstack, top_n_frames=15):
114     """Creates a file dict that maps a file to the occurrence in the stack.
115
116     Args:
117       callstack: A list containing parsed result from a single stack
118                   within a stacktrace. For example, a stacktrace from
119                   previously-allocated thread in release build stacktrace.
120       top_n_frames: The number of frames to look for.
121
122     Returns:
123       Component_dict, a dictionary with key as a file name and value as another
124       dictionary, which maps the file's path (because there can be multiple
125       files with same name but in different directory) to the list of this
126       file's place in stack, lines that this file caused a crash, and the name
127       of the function.
128     """
129
130     # Only look at first top_n_frames of the stacktrace, below those are likely
131     # to be noisy. Parse the stacktrace into the component dictionary.
132     stack_list = callstack.GetTopNFrames(top_n_frames)
133     self.__GenerateFileDict(stack_list)
134
135   def __iter__(self):
136     return iter(self.component_dict)