diff options
Diffstat (limited to 'tools/perf/scripts/python/exported-sql-viewer.py')
| -rwxr-xr-x | tools/perf/scripts/python/exported-sql-viewer.py | 155 |
1 files changed, 154 insertions, 1 deletions
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py index a9d2b3170141..c2fcf6c5237a 100755 --- a/tools/perf/scripts/python/exported-sql-viewer.py +++ b/tools/perf/scripts/python/exported-sql-viewer.py | |||
| @@ -2084,6 +2084,147 @@ class WindowMenu(): | |||
| 2084 | def setActiveSubWindow(self, nr): | 2084 | def setActiveSubWindow(self, nr): |
| 2085 | self.mdi_area.setActiveSubWindow(self.mdi_area.subWindowList()[nr - 1]) | 2085 | self.mdi_area.setActiveSubWindow(self.mdi_area.subWindowList()[nr - 1]) |
| 2086 | 2086 | ||
| 2087 | # Help text | ||
| 2088 | |||
| 2089 | glb_help_text = """ | ||
| 2090 | <h1>Contents</h1> | ||
| 2091 | <style> | ||
| 2092 | p.c1 { | ||
| 2093 | text-indent: 40px; | ||
| 2094 | } | ||
| 2095 | p.c2 { | ||
| 2096 | text-indent: 80px; | ||
| 2097 | } | ||
| 2098 | } | ||
| 2099 | </style> | ||
| 2100 | <p class=c1><a href=#reports>1. Reports</a></p> | ||
| 2101 | <p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p> | ||
| 2102 | <p class=c2><a href=#allbranches>1.2 All branches</a></p> | ||
| 2103 | <p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p> | ||
| 2104 | <p class=c1><a href=#tables>2. Tables</a></p> | ||
| 2105 | <h1 id=reports>1. Reports</h1> | ||
| 2106 | <h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2> | ||
| 2107 | The result is a GUI window with a tree representing a context-sensitive | ||
| 2108 | call-graph. Expanding a couple of levels of the tree and adjusting column | ||
| 2109 | widths to suit will display something like: | ||
| 2110 | <pre> | ||
| 2111 | Call Graph: pt_example | ||
| 2112 | Call Path Object Count Time(ns) Time(%) Branch Count Branch Count(%) | ||
| 2113 | v- ls | ||
| 2114 | v- 2638:2638 | ||
| 2115 | v- _start ld-2.19.so 1 10074071 100.0 211135 100.0 | ||
| 2116 | |- unknown unknown 1 13198 0.1 1 0.0 | ||
| 2117 | >- _dl_start ld-2.19.so 1 1400980 13.9 19637 9.3 | ||
| 2118 | >- _d_linit_internal ld-2.19.so 1 448152 4.4 11094 5.3 | ||
| 2119 | v-__libc_start_main@plt ls 1 8211741 81.5 180397 85.4 | ||
| 2120 | >- _dl_fixup ld-2.19.so 1 7607 0.1 108 0.1 | ||
| 2121 | >- __cxa_atexit libc-2.19.so 1 11737 0.1 10 0.0 | ||
| 2122 | >- __libc_csu_init ls 1 10354 0.1 10 0.0 | ||
| 2123 | |- _setjmp libc-2.19.so 1 0 0.0 4 0.0 | ||
| 2124 | v- main ls 1 8182043 99.6 180254 99.9 | ||
| 2125 | </pre> | ||
| 2126 | <h3>Points to note:</h3> | ||
| 2127 | <ul> | ||
| 2128 | <li>The top level is a command name (comm)</li> | ||
| 2129 | <li>The next level is a thread (pid:tid)</li> | ||
| 2130 | <li>Subsequent levels are functions</li> | ||
| 2131 | <li>'Count' is the number of calls</li> | ||
| 2132 | <li>'Time' is the elapsed time until the function returns</li> | ||
| 2133 | <li>Percentages are relative to the level above</li> | ||
| 2134 | <li>'Branch Count' is the total number of branches for that function and all functions that it calls | ||
| 2135 | </ul> | ||
| 2136 | <h3>Find</h3> | ||
| 2137 | Ctrl-F displays a Find bar which finds function names by either an exact match or a pattern match. | ||
| 2138 | The pattern matching symbols are ? for any character and * for zero or more characters. | ||
| 2139 | <h2 id=allbranches>1.2 All branches</h2> | ||
| 2140 | The All branches report displays all branches in chronological order. | ||
| 2141 | Not all data is fetched immediately. More records can be fetched using the Fetch bar provided. | ||
| 2142 | <h3>Disassembly</h3> | ||
| 2143 | Open a branch to display disassembly. This only works if: | ||
| 2144 | <ol> | ||
| 2145 | <li>The disassembler is available. Currently, only Intel XED is supported - see <a href=#xed>Intel XED Setup</a></li> | ||
| 2146 | <li>The object code is available. Currently, only the perf build ID cache is searched for object code. | ||
| 2147 | The default directory ~/.debug can be overridden by setting environment variable PERF_BUILDID_DIR. | ||
| 2148 | One exception is kcore where the DSO long name is used (refer dsos_view on the Tables menu), | ||
| 2149 | or alternatively, set environment variable PERF_KCORE to the kcore file name.</li> | ||
| 2150 | </ol> | ||
| 2151 | <h4 id=xed>Intel XED Setup</h4> | ||
| 2152 | To use Intel XED, libxed.so must be present. To build and install libxed.so: | ||
| 2153 | <pre> | ||
| 2154 | git clone https://github.com/intelxed/mbuild.git mbuild | ||
| 2155 | git clone https://github.com/intelxed/xed | ||
| 2156 | cd xed | ||
| 2157 | ./mfile.py --share | ||
| 2158 | sudo ./mfile.py --prefix=/usr/local install | ||
| 2159 | sudo ldconfig | ||
| 2160 | </pre> | ||
| 2161 | <h3>Find</h3> | ||
| 2162 | Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match. | ||
| 2163 | Refer to Python documentation for the regular expression syntax. | ||
| 2164 | All columns are searched, but only currently fetched rows are searched. | ||
| 2165 | <h2 id=selectedbranches>1.3 Selected branches</h2> | ||
| 2166 | This is the same as the <a href=#allbranches>All branches</a> report but with the data reduced | ||
| 2167 | by various selection criteria. A dialog box displays available criteria which are AND'ed together. | ||
| 2168 | <h3>1.3.1 Time ranges</h3> | ||
| 2169 | The time ranges hint text shows the total time range. Relative time ranges can also be entered in | ||
| 2170 | ms, us or ns. Also, negative values are relative to the end of trace. Examples: | ||
| 2171 | <pre> | ||
| 2172 | 81073085947329-81073085958238 From 81073085947329 to 81073085958238 | ||
| 2173 | 100us-200us From 100us to 200us | ||
| 2174 | 10ms- From 10ms to the end | ||
| 2175 | -100ns The first 100ns | ||
| 2176 | -10ms- The last 10ms | ||
| 2177 | </pre> | ||
| 2178 | N.B. Due to the granularity of timestamps, there could be no branches in any given time range. | ||
| 2179 | <h1 id=tables>2. Tables</h1> | ||
| 2180 | The Tables menu shows all tables and views in the database. Most tables have an associated view | ||
| 2181 | which displays the information in a more friendly way. Not all data for large tables is fetched | ||
| 2182 | immediately. More records can be fetched using the Fetch bar provided. Columns can be sorted, | ||
| 2183 | but that can be slow for large tables. | ||
| 2184 | <p>There are also tables of database meta-information. | ||
| 2185 | For SQLite3 databases, the sqlite_master table is included. | ||
| 2186 | For PostgreSQL databases, information_schema.tables/views/columns are included. | ||
| 2187 | <h3>Find</h3> | ||
| 2188 | Ctrl-F displays a Find bar which finds substrings by either an exact match or a regular expression match. | ||
| 2189 | Refer to Python documentation for the regular expression syntax. | ||
| 2190 | All columns are searched, but only currently fetched rows are searched. | ||
| 2191 | """ | ||
| 2192 | |||
| 2193 | # Help window | ||
| 2194 | |||
| 2195 | class HelpWindow(QMdiSubWindow): | ||
| 2196 | |||
| 2197 | def __init__(self, glb, parent=None): | ||
| 2198 | super(HelpWindow, self).__init__(parent) | ||
| 2199 | |||
| 2200 | self.text = QTextBrowser() | ||
| 2201 | self.text.setHtml(glb_help_text) | ||
| 2202 | self.text.setReadOnly(True) | ||
| 2203 | self.text.setOpenExternalLinks(True) | ||
| 2204 | |||
| 2205 | self.setWidget(self.text) | ||
| 2206 | |||
| 2207 | AddSubWindow(glb.mainwindow.mdi_area, self, "Exported SQL Viewer Help") | ||
| 2208 | |||
| 2209 | # Main window that only displays the help text | ||
| 2210 | |||
| 2211 | class HelpOnlyWindow(QMainWindow): | ||
| 2212 | |||
| 2213 | def __init__(self, parent=None): | ||
| 2214 | super(HelpOnlyWindow, self).__init__(parent) | ||
| 2215 | |||
| 2216 | self.setMinimumSize(200, 100) | ||
| 2217 | self.resize(800, 600) | ||
| 2218 | self.setWindowTitle("Exported SQL Viewer Help") | ||
| 2219 | self.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation)) | ||
| 2220 | |||
| 2221 | self.text = QTextBrowser() | ||
| 2222 | self.text.setHtml(glb_help_text) | ||
| 2223 | self.text.setReadOnly(True) | ||
| 2224 | self.text.setOpenExternalLinks(True) | ||
| 2225 | |||
| 2226 | self.setCentralWidget(self.text) | ||
| 2227 | |||
| 2087 | # Font resize | 2228 | # Font resize |
| 2088 | 2229 | ||
| 2089 | def ResizeFont(widget, diff): | 2230 | def ResizeFont(widget, diff): |
| @@ -2170,6 +2311,9 @@ class MainWindow(QMainWindow): | |||
| 2170 | 2311 | ||
| 2171 | self.window_menu = WindowMenu(self.mdi_area, menu) | 2312 | self.window_menu = WindowMenu(self.mdi_area, menu) |
| 2172 | 2313 | ||
| 2314 | help_menu = menu.addMenu("&Help") | ||
| 2315 | help_menu.addAction(CreateAction("&Exported SQL Viewer Help", "Helpful information", self.Help, self, QKeySequence.HelpContents)) | ||
| 2316 | |||
| 2173 | def Find(self): | 2317 | def Find(self): |
| 2174 | win = self.mdi_area.activeSubWindow() | 2318 | win = self.mdi_area.activeSubWindow() |
| 2175 | if win: | 2319 | if win: |
| @@ -2230,6 +2374,9 @@ class MainWindow(QMainWindow): | |||
| 2230 | def NewTableView(self, table_name): | 2374 | def NewTableView(self, table_name): |
| 2231 | TableWindow(self.glb, table_name, self) | 2375 | TableWindow(self.glb, table_name, self) |
| 2232 | 2376 | ||
| 2377 | def Help(self): | ||
| 2378 | HelpWindow(self.glb, self) | ||
| 2379 | |||
| 2233 | # XED Disassembler | 2380 | # XED Disassembler |
| 2234 | 2381 | ||
| 2235 | class xed_state_t(Structure): | 2382 | class xed_state_t(Structure): |
| @@ -2429,10 +2576,16 @@ class DBRef(): | |||
| 2429 | 2576 | ||
| 2430 | def Main(): | 2577 | def Main(): |
| 2431 | if (len(sys.argv) < 2): | 2578 | if (len(sys.argv) < 2): |
| 2432 | print >> sys.stderr, "Usage is: exported-sql-viewer.py <database name>" | 2579 | print >> sys.stderr, "Usage is: exported-sql-viewer.py {<database name> | --help-only}" |
| 2433 | raise Exception("Too few arguments") | 2580 | raise Exception("Too few arguments") |
| 2434 | 2581 | ||
| 2435 | dbname = sys.argv[1] | 2582 | dbname = sys.argv[1] |
| 2583 | if dbname == "--help-only": | ||
| 2584 | app = QApplication(sys.argv) | ||
| 2585 | mainwindow = HelpOnlyWindow() | ||
| 2586 | mainwindow.show() | ||
| 2587 | err = app.exec_() | ||
| 2588 | sys.exit(err) | ||
| 2436 | 2589 | ||
| 2437 | is_sqlite3 = False | 2590 | is_sqlite3 = False |
| 2438 | try: | 2591 | try: |
