1564b9527SAdrian Hunter# export-to-sqlite.py: export perf data to a sqlite3 database 2564b9527SAdrian Hunter# Copyright (c) 2017, Intel Corporation. 3564b9527SAdrian Hunter# 4564b9527SAdrian Hunter# This program is free software; you can redistribute it and/or modify it 5564b9527SAdrian Hunter# under the terms and conditions of the GNU General Public License, 6564b9527SAdrian Hunter# version 2, as published by the Free Software Foundation. 7564b9527SAdrian Hunter# 8564b9527SAdrian Hunter# This program is distributed in the hope it will be useful, but WITHOUT 9564b9527SAdrian Hunter# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10564b9527SAdrian Hunter# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11564b9527SAdrian Hunter# more details. 12564b9527SAdrian Hunter 13ebf6c5c1STony Jonesfrom __future__ import print_function 14ebf6c5c1STony Jones 15564b9527SAdrian Hunterimport os 16564b9527SAdrian Hunterimport sys 17564b9527SAdrian Hunterimport struct 18564b9527SAdrian Hunterimport datetime 19564b9527SAdrian Hunter 20564b9527SAdrian Hunter# To use this script you will need to have installed package python-pyside which 21564b9527SAdrian Hunter# provides LGPL-licensed Python bindings for Qt. You will also need the package 22564b9527SAdrian Hunter# libqt4-sql-sqlite for Qt sqlite3 support. 23564b9527SAdrian Hunter# 24bfb3170eSAdrian Hunter# Examples of installing pyside: 25bfb3170eSAdrian Hunter# 26bfb3170eSAdrian Hunter# ubuntu: 27bfb3170eSAdrian Hunter# 28bfb3170eSAdrian Hunter# $ sudo apt-get install python-pyside.qtsql libqt4-sql-psql 29bfb3170eSAdrian Hunter# 30bfb3170eSAdrian Hunter# Alternately, to use Python3 and/or pyside 2, one of the following: 31bfb3170eSAdrian Hunter# 32bfb3170eSAdrian Hunter# $ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql 33bfb3170eSAdrian Hunter# $ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql 34bfb3170eSAdrian Hunter# $ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql 35bfb3170eSAdrian Hunter# fedora: 36bfb3170eSAdrian Hunter# 37bfb3170eSAdrian Hunter# $ sudo yum install python-pyside 38bfb3170eSAdrian Hunter# 39bfb3170eSAdrian Hunter# Alternately, to use Python3 and/or pyside 2, one of the following: 40bfb3170eSAdrian Hunter# $ sudo yum install python3-pyside 41bfb3170eSAdrian Hunter# $ pip install --user PySide2 42bfb3170eSAdrian Hunter# $ pip3 install --user PySide2 43bfb3170eSAdrian Hunter# 44564b9527SAdrian Hunter# An example of using this script with Intel PT: 45564b9527SAdrian Hunter# 46564b9527SAdrian Hunter# $ perf record -e intel_pt//u ls 47564b9527SAdrian Hunter# $ perf script -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py pt_example branches calls 48564b9527SAdrian Hunter# 2017-07-31 14:26:07.326913 Creating database... 49564b9527SAdrian Hunter# 2017-07-31 14:26:07.538097 Writing records... 50564b9527SAdrian Hunter# 2017-07-31 14:26:09.889292 Adding indexes 51564b9527SAdrian Hunter# 2017-07-31 14:26:09.958746 Done 52564b9527SAdrian Hunter# 53564b9527SAdrian Hunter# To browse the database, sqlite3 can be used e.g. 54564b9527SAdrian Hunter# 55564b9527SAdrian Hunter# $ sqlite3 pt_example 56564b9527SAdrian Hunter# sqlite> .header on 57564b9527SAdrian Hunter# sqlite> select * from samples_view where id < 10; 58564b9527SAdrian Hunter# sqlite> .mode column 59564b9527SAdrian Hunter# sqlite> select * from samples_view where id < 10; 60564b9527SAdrian Hunter# sqlite> .tables 61564b9527SAdrian Hunter# sqlite> .schema samples_view 62564b9527SAdrian Hunter# sqlite> .quit 63564b9527SAdrian Hunter# 64564b9527SAdrian Hunter# An example of using the database is provided by the script 65031c2a00SAdrian Hunter# exported-sql-viewer.py. Refer to that script for details. 66564b9527SAdrian Hunter# 67564b9527SAdrian Hunter# The database structure is practically the same as created by the script 68564b9527SAdrian Hunter# export-to-postgresql.py. Refer to that script for details. A notable 69564b9527SAdrian Hunter# difference is the 'transaction' column of the 'samples' table which is 70564b9527SAdrian Hunter# renamed 'transaction_' in sqlite because 'transaction' is a reserved word. 71564b9527SAdrian Hunter 72bfb3170eSAdrian Hunterpyside_version_1 = True 73bfb3170eSAdrian Hunterif not "pyside-version-1" in sys.argv: 74bfb3170eSAdrian Hunter try: 75bfb3170eSAdrian Hunter from PySide2.QtSql import * 76bfb3170eSAdrian Hunter pyside_version_1 = False 77bfb3170eSAdrian Hunter except: 78bfb3170eSAdrian Hunter pass 79bfb3170eSAdrian Hunter 80bfb3170eSAdrian Hunterif pyside_version_1: 81564b9527SAdrian Hunter from PySide.QtSql import * 82564b9527SAdrian Hunter 83564b9527SAdrian Huntersys.path.append(os.environ['PERF_EXEC_PATH'] + \ 84564b9527SAdrian Hunter '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 85564b9527SAdrian Hunter 86564b9527SAdrian Hunter# These perf imports are not used at present 87564b9527SAdrian Hunter#from perf_trace_context import * 88564b9527SAdrian Hunter#from Core import * 89564b9527SAdrian Hunter 90564b9527SAdrian Hunterperf_db_export_mode = True 91564b9527SAdrian Hunterperf_db_export_calls = False 92564b9527SAdrian Hunterperf_db_export_callchains = False 93564b9527SAdrian Hunter 94ebf6c5c1STony Jonesdef printerr(*args, **keyword_args): 95ebf6c5c1STony Jones print(*args, file=sys.stderr, **keyword_args) 96ebf6c5c1STony Jones 9749f93bbfSTony Jonesdef printdate(*args, **kw_args): 9849f93bbfSTony Jones print(datetime.datetime.today(), *args, sep=' ', **kw_args) 9949f93bbfSTony Jones 100564b9527SAdrian Hunterdef usage(): 101bfb3170eSAdrian Hunter printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]"); 102ebf6c5c1STony Jones printerr("where: columns 'all' or 'branches'"); 103ebf6c5c1STony Jones printerr(" calls 'calls' => create calls and call_paths table"); 104ebf6c5c1STony Jones printerr(" callchains 'callchains' => create call_paths table"); 105bfb3170eSAdrian Hunter printerr(" pyside-version-1 'pyside-version-1' => use pyside version 1"); 106bfb3170eSAdrian Hunter raise Exception("Too few or bad arguments") 107564b9527SAdrian Hunter 108564b9527SAdrian Hunterif (len(sys.argv) < 2): 109564b9527SAdrian Hunter usage() 110564b9527SAdrian Hunter 111564b9527SAdrian Hunterdbname = sys.argv[1] 112564b9527SAdrian Hunter 113564b9527SAdrian Hunterif (len(sys.argv) >= 3): 114564b9527SAdrian Hunter columns = sys.argv[2] 115564b9527SAdrian Hunterelse: 116564b9527SAdrian Hunter columns = "all" 117564b9527SAdrian Hunter 118564b9527SAdrian Hunterif columns not in ("all", "branches"): 119564b9527SAdrian Hunter usage() 120564b9527SAdrian Hunter 121564b9527SAdrian Hunterbranches = (columns == "branches") 122564b9527SAdrian Hunter 123564b9527SAdrian Hunterfor i in range(3,len(sys.argv)): 124564b9527SAdrian Hunter if (sys.argv[i] == "calls"): 125564b9527SAdrian Hunter perf_db_export_calls = True 126564b9527SAdrian Hunter elif (sys.argv[i] == "callchains"): 127564b9527SAdrian Hunter perf_db_export_callchains = True 128bfb3170eSAdrian Hunter elif (sys.argv[i] == "pyside-version-1"): 129bfb3170eSAdrian Hunter pass 130564b9527SAdrian Hunter else: 131564b9527SAdrian Hunter usage() 132564b9527SAdrian Hunter 133564b9527SAdrian Hunterdef do_query(q, s): 134564b9527SAdrian Hunter if (q.exec_(s)): 135564b9527SAdrian Hunter return 136564b9527SAdrian Hunter raise Exception("Query failed: " + q.lastError().text()) 137564b9527SAdrian Hunter 138564b9527SAdrian Hunterdef do_query_(q): 139564b9527SAdrian Hunter if (q.exec_()): 140564b9527SAdrian Hunter return 141564b9527SAdrian Hunter raise Exception("Query failed: " + q.lastError().text()) 142564b9527SAdrian Hunter 14349f93bbfSTony Jonesprintdate("Creating database ...") 144564b9527SAdrian Hunter 145564b9527SAdrian Hunterdb_exists = False 146564b9527SAdrian Huntertry: 147564b9527SAdrian Hunter f = open(dbname) 148564b9527SAdrian Hunter f.close() 149564b9527SAdrian Hunter db_exists = True 150564b9527SAdrian Hunterexcept: 151564b9527SAdrian Hunter pass 152564b9527SAdrian Hunter 153564b9527SAdrian Hunterif db_exists: 154564b9527SAdrian Hunter raise Exception(dbname + " already exists") 155564b9527SAdrian Hunter 156564b9527SAdrian Hunterdb = QSqlDatabase.addDatabase('QSQLITE') 157564b9527SAdrian Hunterdb.setDatabaseName(dbname) 158564b9527SAdrian Hunterdb.open() 159564b9527SAdrian Hunter 160564b9527SAdrian Hunterquery = QSqlQuery(db) 161564b9527SAdrian Hunter 162564b9527SAdrian Hunterdo_query(query, 'PRAGMA journal_mode = OFF') 163564b9527SAdrian Hunterdo_query(query, 'BEGIN TRANSACTION') 164564b9527SAdrian Hunter 165564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE selected_events (' 166564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 167564b9527SAdrian Hunter 'name varchar(80))') 168564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE machines (' 169564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 170564b9527SAdrian Hunter 'pid integer,' 171564b9527SAdrian Hunter 'root_dir varchar(4096))') 172564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE threads (' 173564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 174564b9527SAdrian Hunter 'machine_id bigint,' 175564b9527SAdrian Hunter 'process_id bigint,' 176564b9527SAdrian Hunter 'pid integer,' 177564b9527SAdrian Hunter 'tid integer)') 178564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE comms (' 179564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 180564b9527SAdrian Hunter 'comm varchar(16))') 181564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE comm_threads (' 182564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 183564b9527SAdrian Hunter 'comm_id bigint,' 184564b9527SAdrian Hunter 'thread_id bigint)') 185564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE dsos (' 186564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 187564b9527SAdrian Hunter 'machine_id bigint,' 188564b9527SAdrian Hunter 'short_name varchar(256),' 189564b9527SAdrian Hunter 'long_name varchar(4096),' 190564b9527SAdrian Hunter 'build_id varchar(64))') 191564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE symbols (' 192564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 193564b9527SAdrian Hunter 'dso_id bigint,' 194564b9527SAdrian Hunter 'sym_start bigint,' 195564b9527SAdrian Hunter 'sym_end bigint,' 196564b9527SAdrian Hunter 'binding integer,' 197564b9527SAdrian Hunter 'name varchar(2048))') 198564b9527SAdrian Hunterdo_query(query, 'CREATE TABLE branch_types (' 199564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 200564b9527SAdrian Hunter 'name varchar(80))') 201564b9527SAdrian Hunter 202564b9527SAdrian Hunterif branches: 203564b9527SAdrian Hunter do_query(query, 'CREATE TABLE samples (' 204564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 205564b9527SAdrian Hunter 'evsel_id bigint,' 206564b9527SAdrian Hunter 'machine_id bigint,' 207564b9527SAdrian Hunter 'thread_id bigint,' 208564b9527SAdrian Hunter 'comm_id bigint,' 209564b9527SAdrian Hunter 'dso_id bigint,' 210564b9527SAdrian Hunter 'symbol_id bigint,' 211564b9527SAdrian Hunter 'sym_offset bigint,' 212564b9527SAdrian Hunter 'ip bigint,' 213564b9527SAdrian Hunter 'time bigint,' 214564b9527SAdrian Hunter 'cpu integer,' 215564b9527SAdrian Hunter 'to_dso_id bigint,' 216564b9527SAdrian Hunter 'to_symbol_id bigint,' 217564b9527SAdrian Hunter 'to_sym_offset bigint,' 218564b9527SAdrian Hunter 'to_ip bigint,' 219564b9527SAdrian Hunter 'branch_type integer,' 220564b9527SAdrian Hunter 'in_tx boolean,' 221*64adadb3SAdrian Hunter 'call_path_id bigint,' 222*64adadb3SAdrian Hunter 'insn_count bigint,' 223*64adadb3SAdrian Hunter 'cyc_count bigint)') 224564b9527SAdrian Hunterelse: 225564b9527SAdrian Hunter do_query(query, 'CREATE TABLE samples (' 226564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 227564b9527SAdrian Hunter 'evsel_id bigint,' 228564b9527SAdrian Hunter 'machine_id bigint,' 229564b9527SAdrian Hunter 'thread_id bigint,' 230564b9527SAdrian Hunter 'comm_id bigint,' 231564b9527SAdrian Hunter 'dso_id bigint,' 232564b9527SAdrian Hunter 'symbol_id bigint,' 233564b9527SAdrian Hunter 'sym_offset bigint,' 234564b9527SAdrian Hunter 'ip bigint,' 235564b9527SAdrian Hunter 'time bigint,' 236564b9527SAdrian Hunter 'cpu integer,' 237564b9527SAdrian Hunter 'to_dso_id bigint,' 238564b9527SAdrian Hunter 'to_symbol_id bigint,' 239564b9527SAdrian Hunter 'to_sym_offset bigint,' 240564b9527SAdrian Hunter 'to_ip bigint,' 241564b9527SAdrian Hunter 'period bigint,' 242564b9527SAdrian Hunter 'weight bigint,' 243564b9527SAdrian Hunter 'transaction_ bigint,' 244564b9527SAdrian Hunter 'data_src bigint,' 245564b9527SAdrian Hunter 'branch_type integer,' 246564b9527SAdrian Hunter 'in_tx boolean,' 247*64adadb3SAdrian Hunter 'call_path_id bigint,' 248*64adadb3SAdrian Hunter 'insn_count bigint,' 249*64adadb3SAdrian Hunter 'cyc_count bigint)') 250564b9527SAdrian Hunter 251564b9527SAdrian Hunterif perf_db_export_calls or perf_db_export_callchains: 252564b9527SAdrian Hunter do_query(query, 'CREATE TABLE call_paths (' 253564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 254564b9527SAdrian Hunter 'parent_id bigint,' 255564b9527SAdrian Hunter 'symbol_id bigint,' 256564b9527SAdrian Hunter 'ip bigint)') 257564b9527SAdrian Hunterif perf_db_export_calls: 258564b9527SAdrian Hunter do_query(query, 'CREATE TABLE calls (' 259564b9527SAdrian Hunter 'id integer NOT NULL PRIMARY KEY,' 260564b9527SAdrian Hunter 'thread_id bigint,' 261564b9527SAdrian Hunter 'comm_id bigint,' 262564b9527SAdrian Hunter 'call_path_id bigint,' 263564b9527SAdrian Hunter 'call_time bigint,' 264564b9527SAdrian Hunter 'return_time bigint,' 265564b9527SAdrian Hunter 'branch_count bigint,' 266564b9527SAdrian Hunter 'call_id bigint,' 267564b9527SAdrian Hunter 'return_id bigint,' 268564b9527SAdrian Hunter 'parent_call_path_id bigint,' 2698ce9a725SAdrian Hunter 'flags integer,' 270*64adadb3SAdrian Hunter 'parent_id bigint,' 271*64adadb3SAdrian Hunter 'insn_count bigint,' 272*64adadb3SAdrian Hunter 'cyc_count bigint)') 273564b9527SAdrian Hunter 274564b9527SAdrian Hunter# printf was added to sqlite in version 3.8.3 275564b9527SAdrian Huntersqlite_has_printf = False 276564b9527SAdrian Huntertry: 277564b9527SAdrian Hunter do_query(query, 'SELECT printf("") FROM machines') 278564b9527SAdrian Hunter sqlite_has_printf = True 279564b9527SAdrian Hunterexcept: 280564b9527SAdrian Hunter pass 281564b9527SAdrian Hunter 282564b9527SAdrian Hunterdef emit_to_hex(x): 283564b9527SAdrian Hunter if sqlite_has_printf: 284564b9527SAdrian Hunter return 'printf("%x", ' + x + ')' 285564b9527SAdrian Hunter else: 286564b9527SAdrian Hunter return x 287564b9527SAdrian Hunter 288564b9527SAdrian Hunterdo_query(query, 'CREATE VIEW machines_view AS ' 289564b9527SAdrian Hunter 'SELECT ' 290564b9527SAdrian Hunter 'id,' 291564b9527SAdrian Hunter 'pid,' 292564b9527SAdrian Hunter 'root_dir,' 293564b9527SAdrian Hunter 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest' 294564b9527SAdrian Hunter ' FROM machines') 295564b9527SAdrian Hunter 296564b9527SAdrian Hunterdo_query(query, 'CREATE VIEW dsos_view AS ' 297564b9527SAdrian Hunter 'SELECT ' 298564b9527SAdrian Hunter 'id,' 299564b9527SAdrian Hunter 'machine_id,' 300564b9527SAdrian Hunter '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,' 301564b9527SAdrian Hunter 'short_name,' 302564b9527SAdrian Hunter 'long_name,' 303564b9527SAdrian Hunter 'build_id' 304564b9527SAdrian Hunter ' FROM dsos') 305564b9527SAdrian Hunter 306564b9527SAdrian Hunterdo_query(query, 'CREATE VIEW symbols_view AS ' 307564b9527SAdrian Hunter 'SELECT ' 308564b9527SAdrian Hunter 'id,' 309564b9527SAdrian Hunter 'name,' 310564b9527SAdrian Hunter '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,' 311564b9527SAdrian Hunter 'dso_id,' 312564b9527SAdrian Hunter 'sym_start,' 313564b9527SAdrian Hunter 'sym_end,' 314564b9527SAdrian Hunter 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding' 315564b9527SAdrian Hunter ' FROM symbols') 316564b9527SAdrian Hunter 317564b9527SAdrian Hunterdo_query(query, 'CREATE VIEW threads_view AS ' 318564b9527SAdrian Hunter 'SELECT ' 319564b9527SAdrian Hunter 'id,' 320564b9527SAdrian Hunter 'machine_id,' 321564b9527SAdrian Hunter '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,' 322564b9527SAdrian Hunter 'process_id,' 323564b9527SAdrian Hunter 'pid,' 324564b9527SAdrian Hunter 'tid' 325564b9527SAdrian Hunter ' FROM threads') 326564b9527SAdrian Hunter 327564b9527SAdrian Hunterdo_query(query, 'CREATE VIEW comm_threads_view AS ' 328564b9527SAdrian Hunter 'SELECT ' 329564b9527SAdrian Hunter 'comm_id,' 330564b9527SAdrian Hunter '(SELECT comm FROM comms WHERE id = comm_id) AS command,' 331564b9527SAdrian Hunter 'thread_id,' 332564b9527SAdrian Hunter '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' 333564b9527SAdrian Hunter '(SELECT tid FROM threads WHERE id = thread_id) AS tid' 334564b9527SAdrian Hunter ' FROM comm_threads') 335564b9527SAdrian Hunter 336564b9527SAdrian Hunterif perf_db_export_calls or perf_db_export_callchains: 337564b9527SAdrian Hunter do_query(query, 'CREATE VIEW call_paths_view AS ' 338564b9527SAdrian Hunter 'SELECT ' 339564b9527SAdrian Hunter 'c.id,' 340564b9527SAdrian Hunter + emit_to_hex('c.ip') + ' AS ip,' 341564b9527SAdrian Hunter 'c.symbol_id,' 342564b9527SAdrian Hunter '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,' 343564b9527SAdrian Hunter '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,' 344564b9527SAdrian Hunter '(SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,' 345564b9527SAdrian Hunter 'c.parent_id,' 346564b9527SAdrian Hunter + emit_to_hex('p.ip') + ' AS parent_ip,' 347564b9527SAdrian Hunter 'p.symbol_id AS parent_symbol_id,' 348564b9527SAdrian Hunter '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,' 349564b9527SAdrian Hunter '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,' 350564b9527SAdrian Hunter '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name' 351564b9527SAdrian Hunter ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id') 352564b9527SAdrian Hunterif perf_db_export_calls: 353564b9527SAdrian Hunter do_query(query, 'CREATE VIEW calls_view AS ' 354564b9527SAdrian Hunter 'SELECT ' 355564b9527SAdrian Hunter 'calls.id,' 356564b9527SAdrian Hunter 'thread_id,' 357564b9527SAdrian Hunter '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' 358564b9527SAdrian Hunter '(SELECT tid FROM threads WHERE id = thread_id) AS tid,' 359564b9527SAdrian Hunter '(SELECT comm FROM comms WHERE id = comm_id) AS command,' 360564b9527SAdrian Hunter 'call_path_id,' 361564b9527SAdrian Hunter + emit_to_hex('ip') + ' AS ip,' 362564b9527SAdrian Hunter 'symbol_id,' 363564b9527SAdrian Hunter '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,' 364564b9527SAdrian Hunter 'call_time,' 365564b9527SAdrian Hunter 'return_time,' 366564b9527SAdrian Hunter 'return_time - call_time AS elapsed_time,' 367564b9527SAdrian Hunter 'branch_count,' 368*64adadb3SAdrian Hunter 'insn_count,' 369*64adadb3SAdrian Hunter 'cyc_count,' 370*64adadb3SAdrian Hunter 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,' 371564b9527SAdrian Hunter 'call_id,' 372564b9527SAdrian Hunter 'return_id,' 373f08046cbSAdrian Hunter 'CASE WHEN flags=0 THEN \'\' WHEN flags=1 THEN \'no call\' WHEN flags=2 THEN \'no return\' WHEN flags=3 THEN \'no call/return\' WHEN flags=6 THEN \'jump\' ELSE flags END AS flags,' 3748ce9a725SAdrian Hunter 'parent_call_path_id,' 3756e4b1cacSAdrian Hunter 'calls.parent_id' 376564b9527SAdrian Hunter ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id') 377564b9527SAdrian Hunter 378564b9527SAdrian Hunterdo_query(query, 'CREATE VIEW samples_view AS ' 379564b9527SAdrian Hunter 'SELECT ' 380564b9527SAdrian Hunter 'id,' 381564b9527SAdrian Hunter 'time,' 382564b9527SAdrian Hunter 'cpu,' 383564b9527SAdrian Hunter '(SELECT pid FROM threads WHERE id = thread_id) AS pid,' 384564b9527SAdrian Hunter '(SELECT tid FROM threads WHERE id = thread_id) AS tid,' 385564b9527SAdrian Hunter '(SELECT comm FROM comms WHERE id = comm_id) AS command,' 386564b9527SAdrian Hunter '(SELECT name FROM selected_events WHERE id = evsel_id) AS event,' 387564b9527SAdrian Hunter + emit_to_hex('ip') + ' AS ip_hex,' 388564b9527SAdrian Hunter '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,' 389564b9527SAdrian Hunter 'sym_offset,' 390564b9527SAdrian Hunter '(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,' 391564b9527SAdrian Hunter + emit_to_hex('to_ip') + ' AS to_ip_hex,' 392564b9527SAdrian Hunter '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,' 393564b9527SAdrian Hunter 'to_sym_offset,' 394564b9527SAdrian Hunter '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,' 395564b9527SAdrian Hunter '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,' 396*64adadb3SAdrian Hunter 'in_tx,' 397*64adadb3SAdrian Hunter 'insn_count,' 398*64adadb3SAdrian Hunter 'cyc_count,' 399*64adadb3SAdrian Hunter 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC' 400564b9527SAdrian Hunter ' FROM samples') 401564b9527SAdrian Hunter 402564b9527SAdrian Hunterdo_query(query, 'END TRANSACTION') 403564b9527SAdrian Hunter 404564b9527SAdrian Hunterevsel_query = QSqlQuery(db) 405564b9527SAdrian Hunterevsel_query.prepare("INSERT INTO selected_events VALUES (?, ?)") 406564b9527SAdrian Huntermachine_query = QSqlQuery(db) 407564b9527SAdrian Huntermachine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)") 408564b9527SAdrian Hunterthread_query = QSqlQuery(db) 409564b9527SAdrian Hunterthread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)") 410564b9527SAdrian Huntercomm_query = QSqlQuery(db) 411564b9527SAdrian Huntercomm_query.prepare("INSERT INTO comms VALUES (?, ?)") 412564b9527SAdrian Huntercomm_thread_query = QSqlQuery(db) 413564b9527SAdrian Huntercomm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)") 414564b9527SAdrian Hunterdso_query = QSqlQuery(db) 415564b9527SAdrian Hunterdso_query.prepare("INSERT INTO dsos VALUES (?, ?, ?, ?, ?)") 416564b9527SAdrian Huntersymbol_query = QSqlQuery(db) 417564b9527SAdrian Huntersymbol_query.prepare("INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)") 418564b9527SAdrian Hunterbranch_type_query = QSqlQuery(db) 419564b9527SAdrian Hunterbranch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)") 420564b9527SAdrian Huntersample_query = QSqlQuery(db) 421564b9527SAdrian Hunterif branches: 422*64adadb3SAdrian Hunter sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 423564b9527SAdrian Hunterelse: 424*64adadb3SAdrian Hunter sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 425564b9527SAdrian Hunterif perf_db_export_calls or perf_db_export_callchains: 426564b9527SAdrian Hunter call_path_query = QSqlQuery(db) 427564b9527SAdrian Hunter call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)") 428564b9527SAdrian Hunterif perf_db_export_calls: 429564b9527SAdrian Hunter call_query = QSqlQuery(db) 430*64adadb3SAdrian Hunter call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") 431564b9527SAdrian Hunter 432564b9527SAdrian Hunterdef trace_begin(): 43349f93bbfSTony Jones printdate("Writing records...") 434564b9527SAdrian Hunter do_query(query, 'BEGIN TRANSACTION') 435564b9527SAdrian Hunter # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs 436564b9527SAdrian Hunter evsel_table(0, "unknown") 437564b9527SAdrian Hunter machine_table(0, 0, "unknown") 438564b9527SAdrian Hunter thread_table(0, 0, 0, -1, -1) 439564b9527SAdrian Hunter comm_table(0, "unknown") 440564b9527SAdrian Hunter dso_table(0, 0, "unknown", "unknown", "") 441564b9527SAdrian Hunter symbol_table(0, 0, 0, 0, 0, "unknown") 442*64adadb3SAdrian Hunter sample_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 443564b9527SAdrian Hunter if perf_db_export_calls or perf_db_export_callchains: 444564b9527SAdrian Hunter call_path_table(0, 0, 0, 0) 445*64adadb3SAdrian Hunter call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 446564b9527SAdrian Hunter 447564b9527SAdrian Hunterunhandled_count = 0 448564b9527SAdrian Hunter 449564b9527SAdrian Hunterdef trace_end(): 450564b9527SAdrian Hunter do_query(query, 'END TRANSACTION') 451564b9527SAdrian Hunter 45249f93bbfSTony Jones printdate("Adding indexes") 453564b9527SAdrian Hunter if perf_db_export_calls: 454564b9527SAdrian Hunter do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') 4558ce9a725SAdrian Hunter do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)') 456564b9527SAdrian Hunter 457564b9527SAdrian Hunter if (unhandled_count): 45849f93bbfSTony Jones printdate("Warning: ", unhandled_count, " unhandled events") 45949f93bbfSTony Jones printdate("Done") 460564b9527SAdrian Hunter 461564b9527SAdrian Hunterdef trace_unhandled(event_name, context, event_fields_dict): 462564b9527SAdrian Hunter global unhandled_count 463564b9527SAdrian Hunter unhandled_count += 1 464564b9527SAdrian Hunter 465564b9527SAdrian Hunterdef sched__sched_switch(*x): 466564b9527SAdrian Hunter pass 467564b9527SAdrian Hunter 468564b9527SAdrian Hunterdef bind_exec(q, n, x): 469564b9527SAdrian Hunter for xx in x[0:n]: 470564b9527SAdrian Hunter q.addBindValue(str(xx)) 471564b9527SAdrian Hunter do_query_(q) 472564b9527SAdrian Hunter 473564b9527SAdrian Hunterdef evsel_table(*x): 474564b9527SAdrian Hunter bind_exec(evsel_query, 2, x) 475564b9527SAdrian Hunter 476564b9527SAdrian Hunterdef machine_table(*x): 477564b9527SAdrian Hunter bind_exec(machine_query, 3, x) 478564b9527SAdrian Hunter 479564b9527SAdrian Hunterdef thread_table(*x): 480564b9527SAdrian Hunter bind_exec(thread_query, 5, x) 481564b9527SAdrian Hunter 482564b9527SAdrian Hunterdef comm_table(*x): 483564b9527SAdrian Hunter bind_exec(comm_query, 2, x) 484564b9527SAdrian Hunter 485564b9527SAdrian Hunterdef comm_thread_table(*x): 486564b9527SAdrian Hunter bind_exec(comm_thread_query, 3, x) 487564b9527SAdrian Hunter 488564b9527SAdrian Hunterdef dso_table(*x): 489564b9527SAdrian Hunter bind_exec(dso_query, 5, x) 490564b9527SAdrian Hunter 491564b9527SAdrian Hunterdef symbol_table(*x): 492564b9527SAdrian Hunter bind_exec(symbol_query, 6, x) 493564b9527SAdrian Hunter 494564b9527SAdrian Hunterdef branch_type_table(*x): 495564b9527SAdrian Hunter bind_exec(branch_type_query, 2, x) 496564b9527SAdrian Hunter 497564b9527SAdrian Hunterdef sample_table(*x): 498564b9527SAdrian Hunter if branches: 499d005efe1SAdrian Hunter for xx in x[0:15]: 500d005efe1SAdrian Hunter sample_query.addBindValue(str(xx)) 501*64adadb3SAdrian Hunter for xx in x[19:24]: 502d005efe1SAdrian Hunter sample_query.addBindValue(str(xx)) 503d005efe1SAdrian Hunter do_query_(sample_query) 504564b9527SAdrian Hunter else: 505*64adadb3SAdrian Hunter bind_exec(sample_query, 24, x) 506564b9527SAdrian Hunter 507564b9527SAdrian Hunterdef call_path_table(*x): 508564b9527SAdrian Hunter bind_exec(call_path_query, 4, x) 509564b9527SAdrian Hunter 510564b9527SAdrian Hunterdef call_return_table(*x): 511*64adadb3SAdrian Hunter bind_exec(call_query, 14, x) 512