1 # export-to-sqlite.py: export perf data to a sqlite3 database
2 # Copyright (c) 2017, Intel Corporation.
4 # This program is free software; you can redistribute it and/or modify it
5 # under the terms and conditions of the GNU General Public License,
6 # version 2, as published by the Free Software Foundation.
8 # This program is distributed in the hope it will be useful, but WITHOUT
9 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 from __future__ import print_function
20 # To use this script you will need to have installed package python-pyside which
21 # provides LGPL-licensed Python bindings for Qt. You will also need the package
22 # libqt4-sql-sqlite for Qt sqlite3 support.
24 # Examples of installing pyside:
28 # $ sudo apt-get install python-pyside.qtsql libqt4-sql-psql
30 # Alternately, to use Python3 and/or pyside 2, one of the following:
32 # $ sudo apt-get install python3-pyside.qtsql libqt4-sql-psql
33 # $ sudo apt-get install python-pyside2.qtsql libqt5sql5-psql
34 # $ sudo apt-get install python3-pyside2.qtsql libqt5sql5-psql
37 # $ sudo yum install python-pyside
39 # Alternately, to use Python3 and/or pyside 2, one of the following:
40 # $ sudo yum install python3-pyside
41 # $ pip install --user PySide2
42 # $ pip3 install --user PySide2
44 # An example of using this script with Intel PT:
46 # $ perf record -e intel_pt//u ls
47 # $ perf script -s ~/libexec/perf-core/scripts/python/export-to-sqlite.py pt_example branches calls
48 # 2017-07-31 14:26:07.326913 Creating database...
49 # 2017-07-31 14:26:07.538097 Writing records...
50 # 2017-07-31 14:26:09.889292 Adding indexes
51 # 2017-07-31 14:26:09.958746 Done
53 # To browse the database, sqlite3 can be used e.g.
55 # $ sqlite3 pt_example
57 # sqlite> select * from samples_view where id < 10;
58 # sqlite> .mode column
59 # sqlite> select * from samples_view where id < 10;
61 # sqlite> .schema samples_view
64 # An example of using the database is provided by the script
65 # exported-sql-viewer.py. Refer to that script for details.
67 # The database structure is practically the same as created by the script
68 # export-to-postgresql.py. Refer to that script for details. A notable
69 # difference is the 'transaction' column of the 'samples' table which is
70 # renamed 'transaction_' in sqlite because 'transaction' is a reserved word.
72 pyside_version_1 = True
73 if not "pyside-version-1" in sys.argv:
75 from PySide2.QtSql import *
76 pyside_version_1 = False
81 from PySide.QtSql import *
83 sys.path.append(os.environ['PERF_EXEC_PATH'] + \
84 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
86 # These perf imports are not used at present
87 #from perf_trace_context import *
90 perf_db_export_mode = True
91 perf_db_export_calls = False
92 perf_db_export_callchains = False
94 def printerr(*args, **keyword_args):
95 print(*args, file=sys.stderr, **keyword_args)
97 def printdate(*args, **kw_args):
98 print(datetime.datetime.today(), *args, sep=' ', **kw_args)
101 printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>] [<pyside-version-1>]");
102 printerr("where: columns 'all' or 'branches'");
103 printerr(" calls 'calls' => create calls and call_paths table");
104 printerr(" callchains 'callchains' => create call_paths table");
105 printerr(" pyside-version-1 'pyside-version-1' => use pyside version 1");
106 raise Exception("Too few or bad arguments")
108 if (len(sys.argv) < 2):
113 if (len(sys.argv) >= 3):
114 columns = sys.argv[2]
118 if columns not in ("all", "branches"):
121 branches = (columns == "branches")
123 for i in range(3,len(sys.argv)):
124 if (sys.argv[i] == "calls"):
125 perf_db_export_calls = True
126 elif (sys.argv[i] == "callchains"):
127 perf_db_export_callchains = True
128 elif (sys.argv[i] == "pyside-version-1"):
136 raise Exception("Query failed: " + q.lastError().text())
141 raise Exception("Query failed: " + q.lastError().text())
143 printdate("Creating database ...")
154 raise Exception(dbname + " already exists")
156 db = QSqlDatabase.addDatabase('QSQLITE')
157 db.setDatabaseName(dbname)
160 query = QSqlQuery(db)
162 do_query(query, 'PRAGMA journal_mode = OFF')
163 do_query(query, 'BEGIN TRANSACTION')
165 do_query(query, 'CREATE TABLE selected_events ('
166 'id integer NOT NULL PRIMARY KEY,'
168 do_query(query, 'CREATE TABLE machines ('
169 'id integer NOT NULL PRIMARY KEY,'
171 'root_dir varchar(4096))')
172 do_query(query, 'CREATE TABLE threads ('
173 'id integer NOT NULL PRIMARY KEY,'
178 do_query(query, 'CREATE TABLE comms ('
179 'id integer NOT NULL PRIMARY KEY,'
181 do_query(query, 'CREATE TABLE comm_threads ('
182 'id integer NOT NULL PRIMARY KEY,'
185 do_query(query, 'CREATE TABLE dsos ('
186 'id integer NOT NULL PRIMARY KEY,'
188 'short_name varchar(256),'
189 'long_name varchar(4096),'
190 'build_id varchar(64))')
191 do_query(query, 'CREATE TABLE symbols ('
192 'id integer NOT NULL PRIMARY KEY,'
197 'name varchar(2048))')
198 do_query(query, 'CREATE TABLE branch_types ('
199 'id integer NOT NULL PRIMARY KEY,'
203 do_query(query, 'CREATE TABLE samples ('
204 'id integer NOT NULL PRIMARY KEY,'
216 'to_symbol_id bigint,'
217 'to_sym_offset bigint,'
219 'branch_type integer,'
221 'call_path_id bigint,'
225 do_query(query, 'CREATE TABLE samples ('
226 'id integer NOT NULL PRIMARY KEY,'
238 'to_symbol_id bigint,'
239 'to_sym_offset bigint,'
243 'transaction_ bigint,'
245 'branch_type integer,'
247 'call_path_id bigint,'
251 if perf_db_export_calls or perf_db_export_callchains:
252 do_query(query, 'CREATE TABLE call_paths ('
253 'id integer NOT NULL PRIMARY KEY,'
257 if perf_db_export_calls:
258 do_query(query, 'CREATE TABLE calls ('
259 'id integer NOT NULL PRIMARY KEY,'
262 'call_path_id bigint,'
264 'return_time bigint,'
265 'branch_count bigint,'
268 'parent_call_path_id bigint,'
274 do_query(query, 'CREATE TABLE ptwrite ('
275 'id integer NOT NULL PRIMARY KEY,'
279 do_query(query, 'CREATE TABLE cbr ('
280 'id integer NOT NULL PRIMARY KEY,'
285 do_query(query, 'CREATE TABLE mwait ('
286 'id integer NOT NULL PRIMARY KEY,'
288 'extensions integer)')
290 do_query(query, 'CREATE TABLE pwre ('
291 'id integer NOT NULL PRIMARY KEY,'
296 do_query(query, 'CREATE TABLE exstop ('
297 'id integer NOT NULL PRIMARY KEY,'
300 do_query(query, 'CREATE TABLE pwrx ('
301 'id integer NOT NULL PRIMARY KEY,'
302 'deepest_cstate integer,'
303 'last_cstate integer,'
304 'wake_reason integer)')
306 # printf was added to sqlite in version 3.8.3
307 sqlite_has_printf = False
309 do_query(query, 'SELECT printf("") FROM machines')
310 sqlite_has_printf = True
315 if sqlite_has_printf:
316 return 'printf("%x", ' + x + ')'
320 do_query(query, 'CREATE VIEW machines_view AS '
325 'CASE WHEN id=0 THEN \'unknown\' WHEN pid=-1 THEN \'host\' ELSE \'guest\' END AS host_or_guest'
328 do_query(query, 'CREATE VIEW dsos_view AS '
332 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
338 do_query(query, 'CREATE VIEW symbols_view AS '
342 '(SELECT short_name FROM dsos WHERE id=dso_id) AS dso,'
346 'CASE WHEN binding=0 THEN \'local\' WHEN binding=1 THEN \'global\' ELSE \'weak\' END AS binding'
349 do_query(query, 'CREATE VIEW threads_view AS '
353 '(SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,'
359 do_query(query, 'CREATE VIEW comm_threads_view AS '
362 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
364 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
365 '(SELECT tid FROM threads WHERE id = thread_id) AS tid'
366 ' FROM comm_threads')
368 if perf_db_export_calls or perf_db_export_callchains:
369 do_query(query, 'CREATE VIEW call_paths_view AS '
372 + emit_to_hex('c.ip') + ' AS ip,'
374 '(SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,'
375 '(SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,'
376 '(SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,'
378 + emit_to_hex('p.ip') + ' AS parent_ip,'
379 'p.symbol_id AS parent_symbol_id,'
380 '(SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,'
381 '(SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,'
382 '(SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name'
383 ' FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id')
384 if perf_db_export_calls:
385 do_query(query, 'CREATE VIEW calls_view AS '
389 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
390 '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
391 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
393 + emit_to_hex('ip') + ' AS ip,'
395 '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
398 'return_time - call_time AS elapsed_time,'
402 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,'
405 '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,'
406 'parent_call_path_id,'
408 ' FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id')
410 do_query(query, 'CREATE VIEW samples_view AS '
415 '(SELECT pid FROM threads WHERE id = thread_id) AS pid,'
416 '(SELECT tid FROM threads WHERE id = thread_id) AS tid,'
417 '(SELECT comm FROM comms WHERE id = comm_id) AS command,'
418 '(SELECT name FROM selected_events WHERE id = evsel_id) AS event,'
419 + emit_to_hex('ip') + ' AS ip_hex,'
420 '(SELECT name FROM symbols WHERE id = symbol_id) AS symbol,'
422 '(SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,'
423 + emit_to_hex('to_ip') + ' AS to_ip_hex,'
424 '(SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,'
426 '(SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,'
427 '(SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,'
431 'CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC'
434 do_query(query, 'CREATE VIEW ptwrite_view AS '
439 + emit_to_hex('payload') + ' AS payload_hex,'
440 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
442 ' INNER JOIN samples ON samples.id = ptwrite.id')
444 do_query(query, 'CREATE VIEW cbr_view AS '
453 ' INNER JOIN samples ON samples.id = cbr.id')
455 do_query(query, 'CREATE VIEW mwait_view AS '
460 + emit_to_hex('hints') + ' AS hints_hex,'
461 + emit_to_hex('extensions') + ' AS extensions_hex'
463 ' INNER JOIN samples ON samples.id = mwait.id')
465 do_query(query, 'CREATE VIEW pwre_view AS '
472 'CASE WHEN hw=0 THEN \'False\' ELSE \'True\' END AS hw'
474 ' INNER JOIN samples ON samples.id = pwre.id')
476 do_query(query, 'CREATE VIEW exstop_view AS '
481 'CASE WHEN exact_ip=0 THEN \'False\' ELSE \'True\' END AS exact_ip'
483 ' INNER JOIN samples ON samples.id = exstop.id')
485 do_query(query, 'CREATE VIEW pwrx_view AS '
492 'CASE WHEN wake_reason=1 THEN \'Interrupt\''
493 ' WHEN wake_reason=2 THEN \'Timer Deadline\''
494 ' WHEN wake_reason=4 THEN \'Monitored Address\''
495 ' WHEN wake_reason=8 THEN \'HW\''
499 ' INNER JOIN samples ON samples.id = pwrx.id')
501 do_query(query, 'CREATE VIEW power_events_view AS '
506 'selected_events.name AS event,'
507 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS cbr,'
508 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS mhz,'
509 'CASE WHEN selected_events.name=\'cbr\' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE "" END AS percent,'
510 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('hints') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS hints_hex,'
511 'CASE WHEN selected_events.name=\'mwait\' THEN (SELECT ' + emit_to_hex('extensions') + ' FROM mwait WHERE mwait.id = samples.id) ELSE "" END AS extensions_hex,'
512 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS cstate,'
513 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS subcstate,'
514 'CASE WHEN selected_events.name=\'pwre\' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE "" END AS hw,'
515 'CASE WHEN selected_events.name=\'exstop\' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE "" END AS exact_ip,'
516 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS deepest_cstate,'
517 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS last_cstate,'
518 'CASE WHEN selected_events.name=\'pwrx\' THEN (SELECT '
519 'CASE WHEN wake_reason=1 THEN \'Interrupt\''
520 ' WHEN wake_reason=2 THEN \'Timer Deadline\''
521 ' WHEN wake_reason=4 THEN \'Monitored Address\''
522 ' WHEN wake_reason=8 THEN \'HW\''
525 ' FROM pwrx WHERE pwrx.id = samples.id) ELSE "" END AS wake_reason'
527 ' INNER JOIN selected_events ON selected_events.id = evsel_id'
528 ' WHERE selected_events.name IN (\'cbr\',\'mwait\',\'exstop\',\'pwre\',\'pwrx\')')
530 do_query(query, 'END TRANSACTION')
532 evsel_query = QSqlQuery(db)
533 evsel_query.prepare("INSERT INTO selected_events VALUES (?, ?)")
534 machine_query = QSqlQuery(db)
535 machine_query.prepare("INSERT INTO machines VALUES (?, ?, ?)")
536 thread_query = QSqlQuery(db)
537 thread_query.prepare("INSERT INTO threads VALUES (?, ?, ?, ?, ?)")
538 comm_query = QSqlQuery(db)
539 comm_query.prepare("INSERT INTO comms VALUES (?, ?)")
540 comm_thread_query = QSqlQuery(db)
541 comm_thread_query.prepare("INSERT INTO comm_threads VALUES (?, ?, ?)")
542 dso_query = QSqlQuery(db)
543 dso_query.prepare("INSERT INTO dsos VALUES (?, ?, ?, ?, ?)")
544 symbol_query = QSqlQuery(db)
545 symbol_query.prepare("INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)")
546 branch_type_query = QSqlQuery(db)
547 branch_type_query.prepare("INSERT INTO branch_types VALUES (?, ?)")
548 sample_query = QSqlQuery(db)
550 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
552 sample_query.prepare("INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
553 if perf_db_export_calls or perf_db_export_callchains:
554 call_path_query = QSqlQuery(db)
555 call_path_query.prepare("INSERT INTO call_paths VALUES (?, ?, ?, ?)")
556 if perf_db_export_calls:
557 call_query = QSqlQuery(db)
558 call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
559 ptwrite_query = QSqlQuery(db)
560 ptwrite_query.prepare("INSERT INTO ptwrite VALUES (?, ?, ?)")
561 cbr_query = QSqlQuery(db)
562 cbr_query.prepare("INSERT INTO cbr VALUES (?, ?, ?, ?)")
563 mwait_query = QSqlQuery(db)
564 mwait_query.prepare("INSERT INTO mwait VALUES (?, ?, ?)")
565 pwre_query = QSqlQuery(db)
566 pwre_query.prepare("INSERT INTO pwre VALUES (?, ?, ?, ?)")
567 exstop_query = QSqlQuery(db)
568 exstop_query.prepare("INSERT INTO exstop VALUES (?, ?)")
569 pwrx_query = QSqlQuery(db)
570 pwrx_query.prepare("INSERT INTO pwrx VALUES (?, ?, ?, ?)")
573 printdate("Writing records...")
574 do_query(query, 'BEGIN TRANSACTION')
575 # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs
576 evsel_table(0, "unknown")
577 machine_table(0, 0, "unknown")
578 thread_table(0, 0, 0, -1, -1)
579 comm_table(0, "unknown")
580 dso_table(0, 0, "unknown", "unknown", "")
581 symbol_table(0, 0, 0, 0, 0, "unknown")
582 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)
583 if perf_db_export_calls or perf_db_export_callchains:
584 call_path_table(0, 0, 0, 0)
585 call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
589 def is_table_empty(table_name):
590 do_query(query, 'SELECT * FROM ' + table_name + ' LIMIT 1');
595 def drop(table_name):
596 do_query(query, 'DROP VIEW ' + table_name + '_view');
597 do_query(query, 'DROP TABLE ' + table_name);
600 do_query(query, 'END TRANSACTION')
602 printdate("Adding indexes")
603 if perf_db_export_calls:
604 do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
605 do_query(query, 'CREATE INDEX pid_idx ON calls (parent_id)')
607 printdate("Dropping unused tables")
608 if is_table_empty("ptwrite"):
610 if is_table_empty("mwait") and is_table_empty("pwre") and is_table_empty("exstop") and is_table_empty("pwrx"):
611 do_query(query, 'DROP VIEW power_events_view');
616 if is_table_empty("cbr"):
619 if (unhandled_count):
620 printdate("Warning: ", unhandled_count, " unhandled events")
623 def trace_unhandled(event_name, context, event_fields_dict):
624 global unhandled_count
627 def sched__sched_switch(*x):
630 def bind_exec(q, n, x):
632 q.addBindValue(str(xx))
636 bind_exec(evsel_query, 2, x)
638 def machine_table(*x):
639 bind_exec(machine_query, 3, x)
641 def thread_table(*x):
642 bind_exec(thread_query, 5, x)
645 bind_exec(comm_query, 2, x)
647 def comm_thread_table(*x):
648 bind_exec(comm_thread_query, 3, x)
651 bind_exec(dso_query, 5, x)
653 def symbol_table(*x):
654 bind_exec(symbol_query, 6, x)
656 def branch_type_table(*x):
657 bind_exec(branch_type_query, 2, x)
659 def sample_table(*x):
662 sample_query.addBindValue(str(xx))
664 sample_query.addBindValue(str(xx))
665 do_query_(sample_query)
667 bind_exec(sample_query, 24, x)
669 def call_path_table(*x):
670 bind_exec(call_path_query, 4, x)
672 def call_return_table(*x):
673 bind_exec(call_query, 14, x)
675 def ptwrite(id, raw_buf):
676 data = struct.unpack_from("<IQ", raw_buf)
680 ptwrite_query.addBindValue(str(id))
681 ptwrite_query.addBindValue(str(payload))
682 ptwrite_query.addBindValue(str(exact_ip))
683 do_query_(ptwrite_query)
685 def cbr(id, raw_buf):
686 data = struct.unpack_from("<BBBBII", raw_buf)
688 MHz = (data[4] + 500) / 1000
689 percent = ((cbr * 1000 / data[2]) + 5) / 10
690 cbr_query.addBindValue(str(id))
691 cbr_query.addBindValue(str(cbr))
692 cbr_query.addBindValue(str(MHz))
693 cbr_query.addBindValue(str(percent))
696 def mwait(id, raw_buf):
697 data = struct.unpack_from("<IQ", raw_buf)
699 hints = payload & 0xff
700 extensions = (payload >> 32) & 0x3
701 mwait_query.addBindValue(str(id))
702 mwait_query.addBindValue(str(hints))
703 mwait_query.addBindValue(str(extensions))
704 do_query_(mwait_query)
706 def pwre(id, raw_buf):
707 data = struct.unpack_from("<IQ", raw_buf)
709 hw = (payload >> 7) & 1
710 cstate = (payload >> 12) & 0xf
711 subcstate = (payload >> 8) & 0xf
712 pwre_query.addBindValue(str(id))
713 pwre_query.addBindValue(str(cstate))
714 pwre_query.addBindValue(str(subcstate))
715 pwre_query.addBindValue(str(hw))
716 do_query_(pwre_query)
718 def exstop(id, raw_buf):
719 data = struct.unpack_from("<I", raw_buf)
722 exstop_query.addBindValue(str(id))
723 exstop_query.addBindValue(str(exact_ip))
724 do_query_(exstop_query)
726 def pwrx(id, raw_buf):
727 data = struct.unpack_from("<IQ", raw_buf)
729 deepest_cstate = payload & 0xf
730 last_cstate = (payload >> 4) & 0xf
731 wake_reason = (payload >> 8) & 0xf
732 pwrx_query.addBindValue(str(id))
733 pwrx_query.addBindValue(str(deepest_cstate))
734 pwrx_query.addBindValue(str(last_cstate))
735 pwrx_query.addBindValue(str(wake_reason))
736 do_query_(pwrx_query)
738 def synth_data(id, config, raw_buf, *x):