• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ZJU-SPAIL / pipa / 20429502677

22 Dec 2025 10:41AM UTC coverage: 19.033%. Remained the same
20429502677

push

github

bernard035
style: correct formatting

0 of 1 new or added line in 1 file covered. (0.0%)

748 of 3930 relevant lines covered (19.03%)

0.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/pipa/scripts/perf_sqlite.py
1
from __future__ import print_function
×
2

3
import csv
×
4
import datetime
×
5
import os
×
6
import sqlite3
×
7
import struct
×
8
import sys
×
9

10
perf_db_export_mode = True
×
11
perf_db_export_calls = False
×
12
perf_db_export_callchains = False
×
13
export_csv_dir = None
×
14

15
call_path_events = 0
×
16
call_return_events = 0
×
17

18
conn = None
×
19
cur = None
×
20
branches = False
×
21
call_path_insert_sql = None
×
22
call_insert_sql = None
×
23
sample_insert_sql = None
×
24
unhandled_count = 0
×
25
sqlite_has_printf = False
×
26
dbname = ""
×
27

28

29
def printerr(*args, **keyword_args):
×
30
    print(*args, file=sys.stderr, **keyword_args)
×
31

32

33
def printdate(*args, **kw_args):
×
34
    print(datetime.datetime.today(), *args, sep=" ", **kw_args)
×
35

36

37
def usage():
×
38
    printerr(
×
39
        "Usage: pipa-perf-sqlite <database name> [<columns>] [<calls>] [<callchains>] [<csv[=dir>]]"
40
    )
41
    printerr("where:  columns            'all' or 'branches'")
×
42
    printerr("        calls              'calls' => create calls and call_paths table")
×
43
    printerr(
×
44
        "        callchains         'callchains' => create call_paths table (implied by calls)"
45
    )
46
    printerr("        csv[=dir]          export all tables to CSVs (default dir '.')")
×
47
    raise Exception("Too few or bad arguments")
×
48

49

50
def do_query(sql, params=()):
×
51
    try:
×
52
        cur.execute(sql, params)
×
53
    except sqlite3.Error as e:
×
54
        raise Exception("Query failed: " + str(e))
×
55

56

57
def do_script(sql):
×
58
    try:
×
59
        cur.executescript(sql)
×
60
    except sqlite3.Error as e:
×
61
        raise Exception("Query failed: " + str(e))
×
62

63

64
def emit_to_hex(x):
×
65
    if sqlite_has_printf:
×
66
        return 'printf("%x", ' + x + ")"
×
67
    return x
×
68

69

70
def bind_exec(sql_stmt, n, x):
×
71
    params = tuple("0" if xx is None else str(xx) for xx in x[:n])
×
72
    do_query(sql_stmt, params)
×
73

74

75
def evsel_table(*x):
×
76
    bind_exec(insert_sql["evsel"], 2, x)
×
77

78

79
def machine_table(*x):
×
80
    bind_exec(insert_sql["machine"], 3, x)
×
81

82

83
def thread_table(*x):
×
84
    bind_exec(insert_sql["thread"], 5, x)
×
85

86

87
def comm_table(*x):
×
88
    bind_exec(insert_sql["comm"], 5, x)
×
89

90

91
def comm_thread_table(*x):
×
92
    bind_exec(insert_sql["comm_thread"], 3, x)
×
93

94

95
def dso_table(*x):
×
96
    bind_exec(insert_sql["dso"], 5, x)
×
97

98

99
def symbol_table(*x):
×
100
    bind_exec(insert_sql["symbol"], 6, x)
×
101

102

103
def branch_type_table(*x):
×
104
    bind_exec(insert_sql["branch_type"], 2, x)
×
105

106

107
def sample_table(*x):
×
108
    vals = list(x)
×
109
    if len(vals) < 25:
×
110
        vals += [0] * (25 - len(vals))
×
111
    elif len(vals) > 25:
×
112
        vals = vals[:25]
×
113

114
    if branches:
×
115
        params = vals[:15] + vals[19:25]
×
116
        do_query(
×
117
            sample_insert_sql, tuple("0" if xx is None else str(xx) for xx in params)
118
        )
119
    else:
120
        bind_exec(sample_insert_sql, 25, vals)
×
121

122

123
def call_path_table(*x):
×
124
    global call_path_events
125
    if call_path_insert_sql is None:
×
126
        return
×
127
    call_path_events += 1
×
128
    bind_exec(call_path_insert_sql, 4, x)
×
129

130

131
def call_return_table(*x):
×
132
    global call_return_events
133
    if call_insert_sql is None:
×
134
        return
×
135
    call_return_events += 1
×
136
    bind_exec(call_insert_sql, 14, x)
×
137

138

139
def ptwrite(id, raw_buf):
×
140
    data = struct.unpack_from("<IQ", raw_buf)
×
141
    flags = data[0]
×
142
    payload = data[1]
×
143
    exact_ip = flags & 1
×
144
    do_query(insert_sql["ptwrite"], (str(id), str(payload), str(exact_ip)))
×
145

146

147
def cbr(id, raw_buf):
×
148
    data = struct.unpack_from("<BBBBII", raw_buf)
×
149
    cbr_val = data[0]
×
150
    mhz = (data[4] + 500) // 1000
×
151
    percent = ((cbr_val * 1000 // data[2]) + 5) // 10
×
152
    do_query(insert_sql["cbr"], (str(id), str(cbr_val), str(mhz), str(percent)))
×
153

154

155
def mwait(id, raw_buf):
×
156
    data = struct.unpack_from("<IQ", raw_buf)
×
157
    payload = data[1]
×
158
    hints = payload & 0xFF
×
159
    extensions = (payload >> 32) & 0x3
×
160
    do_query(insert_sql["mwait"], (str(id), str(hints), str(extensions)))
×
161

162

163
def pwre(id, raw_buf):
×
164
    data = struct.unpack_from("<IQ", raw_buf)
×
165
    payload = data[1]
×
166
    hw = (payload >> 7) & 1
×
167
    cstate = (payload >> 12) & 0xF
×
168
    subcstate = (payload >> 8) & 0xF
×
169
    do_query(insert_sql["pwre"], (str(id), str(cstate), str(subcstate), str(hw)))
×
170

171

172
def exstop(id, raw_buf):
×
173
    data = struct.unpack_from("<I", raw_buf)
×
174
    flags = data[0]
×
175
    exact_ip = flags & 1
×
176
    do_query(insert_sql["exstop"], (str(id), str(exact_ip)))
×
177

178

179
def pwrx(id, raw_buf):
×
180
    data = struct.unpack_from("<IQ", raw_buf)
×
181
    payload = data[1]
×
182
    deepest_cstate = payload & 0xF
×
183
    last_cstate = (payload >> 4) & 0xF
×
184
    wake_reason = (payload >> 8) & 0xF
×
185
    do_query(
×
186
        insert_sql["pwrx"],
187
        (str(id), str(deepest_cstate), str(last_cstate), str(wake_reason)),
188
    )
189

190

191
def synth_data(id, config, raw_buf, *x):
×
192
    if config == 0:
×
193
        ptwrite(id, raw_buf)
×
194
    elif config == 1:
×
195
        mwait(id, raw_buf)
×
196
    elif config == 2:
×
197
        pwre(id, raw_buf)
×
198
    elif config == 3:
×
199
        exstop(id, raw_buf)
×
200
    elif config == 4:
×
201
        pwrx(id, raw_buf)
×
202
    elif config == 5:
×
203
        cbr(id, raw_buf)
×
204

205

206
def context_switch_table(*x):
×
207
    bind_exec(insert_sql["context_switch"], 9, x)
×
208

209

210
def trace_begin():
×
211
    printdate("Writing records...")
×
212
    do_query("BEGIN TRANSACTION")
×
213
    evsel_table(0, "unknown")
×
214
    machine_table(0, 0, "unknown")
×
215
    thread_table(0, 0, 0, -1, -1)
×
216
    comm_table(0, "unknown", 0, 0, 0)
×
217
    dso_table(0, 0, "unknown", "unknown", "")
×
218
    symbol_table(0, 0, 0, 0, 0, "unknown")
×
219
    sample_table(
×
220
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
221
    )
222
    if call_path_insert_sql is not None:
×
223
        call_path_table(0, 0, 0, 0)
×
224
    if call_insert_sql is not None:
×
225
        call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
×
226

227

228
def is_table_empty(table_name):
×
229
    try:
×
230
        do_query("SELECT 1 FROM " + table_name + " LIMIT 1")
×
231
        return cur.fetchone() is None
×
232
    except Exception:
×
233
        return True
×
234

235

236
def drop(table_name):
×
237
    do_query("DROP VIEW IF EXISTS " + table_name + "_view")
×
238
    do_query("DROP TABLE IF EXISTS " + table_name)
×
239

240

241
def export_all_tables_to_csv(out_dir):
×
242
    if out_dir is None:
×
243
        return
×
244
    try:
×
245
        os.makedirs(out_dir, exist_ok=True)
×
246
        cur.execute(
×
247
            "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'"
248
        )
249
        tables = [r[0] for r in cur.fetchall()]
×
250
        for t in tables:
×
251
            safe_table = '"' + t.replace('"', '""') + '"'
×
252
            cur.execute(f"SELECT * FROM {safe_table}")
×
253
            cols = [desc[0] for desc in cur.description]
×
254
            out_path = os.path.join(out_dir, f"{t}.csv")
×
255
            with open(out_path, "w", newline="") as f:
×
256
                writer = csv.writer(f)
×
257
                writer.writerow(cols)
×
258
                while True:
×
259
                    rows = cur.fetchmany(10000)
×
260
                    if not rows:
×
261
                        break
×
262
                    writer.writerows(rows)
×
263
            printdate("Exported", out_path)
×
264
    except Exception as e:
×
265
        printerr("CSV export failed:", e)
×
266

267

268
def trace_end():
×
269
    do_query("END TRANSACTION")
×
270

271
    printdate("Adding indexes")
×
272
    if perf_db_export_calls:
×
273
        do_query("CREATE INDEX IF NOT EXISTS pcpid_idx ON calls (parent_call_path_id)")
×
274
        do_query("CREATE INDEX IF NOT EXISTS pid_idx ON calls (parent_id)")
×
275
        try:
×
276
            do_query("ALTER TABLE comms ADD COLUMN has_calls boolean")
×
277
        except Exception:
×
278
            pass
×
279
        do_query(
×
280
            "UPDATE comms SET has_calls = 1 WHERE comms.id IN (SELECT DISTINCT comm_id FROM calls)"
281
        )
282

283
    printdate("Dropping unused tables")
×
284
    if is_table_empty("ptwrite"):
×
285
        drop("ptwrite")
×
286
    if (
×
287
        is_table_empty("mwait")
288
        and is_table_empty("pwre")
289
        and is_table_empty("exstop")
290
        and is_table_empty("pwrx")
291
    ):
292
        drop("power_events")
×
293
        drop("mwait")
×
294
        drop("pwre")
×
295
        drop("exstop")
×
296
        drop("pwrx")
×
297
        if is_table_empty("cbr"):
×
298
            drop("cbr")
×
299
    if is_table_empty("context_switches"):
×
300
        drop("context_switches")
×
301

302
    if unhandled_count:
×
303
        printdate("Warning: ", unhandled_count, " unhandled events")
×
304
    printdate("Done")
×
305
    printdate("Stats:", "call_paths=", call_path_events, "calls=", call_return_events)
×
306
    conn.commit()
×
307
    export_all_tables_to_csv(export_csv_dir)
×
308

309

310
def trace_unhandled(event_name, context, event_fields_dict):
×
311
    global unhandled_count
312
    unhandled_count += 1
×
313

314

315
def sched__sched_switch(*x):
×
316
    pass
×
317

318

319
def main(argv=None):
×
320
    global perf_db_export_mode
321
    global perf_db_export_calls
322
    global perf_db_export_callchains
323
    global export_csv_dir
324
    global call_path_events
325
    global call_return_events
326
    global conn
327
    global cur
328
    global branches
329
    global call_path_insert_sql
330
    global call_insert_sql
331
    global sample_insert_sql
332
    global unhandled_count
333
    global sqlite_has_printf
334
    global dbname
335
    global insert_sql
336

337
    argv = list(sys.argv[1:] if argv is None else argv)
×
338

339
    perf_db_export_mode = True
×
340
    perf_db_export_calls = False
×
341
    perf_db_export_callchains = False
×
342
    export_csv_dir = None
×
343
    call_path_events = 0
×
344
    call_return_events = 0
×
345
    unhandled_count = 0
×
346

347
    if len(argv) < 1:
×
348
        usage()
×
349

350
    dbname = argv[0]
×
351

352
    columns = "all"
×
353
    arg_start = 1
×
354
    if len(argv) >= 2 and argv[1] in ("all", "branches"):
×
355
        columns = argv[1]
×
356
        arg_start = 2
×
357

358
    if columns not in ("all", "branches"):
×
359
        usage()
×
360

361
    branches = columns == "branches"
×
362

363
    for arg in argv[arg_start:]:
×
364
        if arg == "calls":
×
365
            perf_db_export_calls = True
×
366
        elif arg == "callchains":
×
367
            perf_db_export_callchains = True
×
368
        elif arg.startswith("csv"):
×
369
            if export_csv_dir is not None:
×
370
                usage()
×
371
            if arg == "csv":
×
372
                export_csv_dir = os.getcwd()
×
373
            elif arg.startswith("csv="):
×
374
                export_csv_dir = os.path.abspath(arg.split("=", 1)[1])
×
375
            else:
376
                usage()
×
377
        else:
378
            usage()
×
379

380
    if perf_db_export_calls:
×
381
        perf_db_export_callchains = True
×
382

383
    printdate("Creating database ...")
×
384

385
    db_exists = False
×
386
    try:
×
387
        with open(dbname):
×
388
            db_exists = True
×
389
    except Exception:
×
390
        pass
×
391

392
    if db_exists:
×
393
        raise Exception(dbname + " already exists")
×
394

395
    conn = sqlite3.connect(dbname)
×
396
    cur = conn.cursor()
×
397

398
    do_query("PRAGMA journal_mode = OFF")
×
399
    do_query("BEGIN TRANSACTION")
×
400

401
    schema_statements = []
×
402
    schema_statements.append(
×
403
        """CREATE TABLE selected_events (
404
    id          integer     NOT NULL    PRIMARY KEY,
405
    name        varchar(80)
406
)"""
407
    )
408
    schema_statements.append(
×
409
        """CREATE TABLE machines (
410
    id          integer     NOT NULL    PRIMARY KEY,
411
    pid         integer,
412
    root_dir    varchar(4096)
413
)"""
414
    )
415
    schema_statements.append(
×
416
        """CREATE TABLE threads (
417
    id          integer     NOT NULL    PRIMARY KEY,
418
    machine_id  bigint,
419
    process_id  bigint,
420
    pid         integer,
421
    tid         integer
422
)"""
423
    )
424
    schema_statements.append(
×
425
        """CREATE TABLE comms (
426
    id          integer     NOT NULL    PRIMARY KEY,
427
    comm        varchar(16),
428
    c_thread_id bigint,
429
    c_time      bigint,
430
    exec_flag   boolean
431
)"""
432
    )
433
    schema_statements.append(
×
434
        """CREATE TABLE comm_threads (
435
    id          integer     NOT NULL    PRIMARY KEY,
436
    comm_id     bigint,
437
    thread_id   bigint
438
)"""
439
    )
440
    schema_statements.append(
×
441
        """CREATE TABLE dsos (
442
    id          integer     NOT NULL    PRIMARY KEY,
443
    machine_id  bigint,
444
    short_name  varchar(256),
445
    long_name   varchar(4096),
446
    build_id    varchar(64)
447
)"""
448
    )
449
    schema_statements.append(
×
450
        """CREATE TABLE symbols (
451
    id          integer     NOT NULL    PRIMARY KEY,
452
    dso_id      bigint,
453
    sym_start   bigint,
454
    sym_end     bigint,
455
    binding     integer,
456
    name        varchar(2048)
457
)"""
458
    )
459
    schema_statements.append(
×
460
        """CREATE TABLE branch_types (
461
    id          integer     NOT NULL    PRIMARY KEY,
462
    name        varchar(80)
463
)"""
464
    )
465

466
    if branches:
×
467
        schema_statements.append(
×
468
            """CREATE TABLE samples (
469
        id          integer     NOT NULL    PRIMARY KEY,
470
        evsel_id    bigint,
471
        machine_id  bigint,
472
        thread_id   bigint,
473
        comm_id     bigint,
474
        dso_id      bigint,
475
        symbol_id   bigint,
476
        sym_offset  bigint,
477
        ip          bigint,
478
        time        bigint,
479
        cpu         integer,
480
        to_dso_id   bigint,
481
        to_symbol_id bigint,
482
        to_sym_offset bigint,
483
        to_ip       bigint,
484
        branch_type integer,
485
        in_tx       boolean,
486
        call_path_id bigint,
487
        insn_count  bigint,
488
        cyc_count   bigint,
489
        flags       integer
490
    )"""
491
        )
492
    else:
493
        schema_statements.append(
×
494
            """CREATE TABLE samples (
495
        id          integer     NOT NULL    PRIMARY KEY,
496
        evsel_id    bigint,
497
        machine_id  bigint,
498
        thread_id   bigint,
499
        comm_id     bigint,
500
        dso_id      bigint,
501
        symbol_id   bigint,
502
        sym_offset  bigint,
503
        ip          bigint,
504
        time        bigint,
505
        cpu         integer,
506
        to_dso_id   bigint,
507
        to_symbol_id bigint,
508
        to_sym_offset bigint,
509
        to_ip       bigint,
510
        period      bigint,
511
        weight      bigint,
512
        transaction_ bigint,
513
        data_src    bigint,
514
        branch_type integer,
515
        in_tx       boolean,
516
        call_path_id bigint,
517
        insn_count  bigint,
518
        cyc_count   bigint,
519
        flags       integer
520
    )"""
521
        )
522

523
    if perf_db_export_calls or perf_db_export_callchains:
×
524
        schema_statements.append(
×
525
            """CREATE TABLE call_paths (
526
        id          integer     NOT NULL    PRIMARY KEY,
527
        parent_id   bigint,
528
        symbol_id   bigint,
529
        ip          bigint
530
    )"""
531
        )
532
    if perf_db_export_calls:
×
533
        schema_statements.append(
×
534
            """CREATE TABLE calls (
535
        id          integer     NOT NULL    PRIMARY KEY,
536
        thread_id   bigint,
537
        comm_id     bigint,
538
        call_path_id bigint,
539
        call_time   bigint,
540
        return_time bigint,
541
        branch_count bigint,
542
        call_id     bigint,
543
        return_id   bigint,
544
        parent_call_path_id bigint,
545
        flags       integer,
546
        parent_id   bigint,
547
        insn_count  bigint,
548
        cyc_count   bigint
549
    )"""
550
        )
551

552
    schema_statements.append(
×
553
        """CREATE TABLE ptwrite (
554
    id          integer     NOT NULL    PRIMARY KEY,
555
    payload     bigint,
556
    exact_ip    integer
557
)"""
558
    )
559
    schema_statements.append(
×
560
        """CREATE TABLE cbr (
561
    id          integer     NOT NULL    PRIMARY KEY,
562
    cbr         integer,
563
    mhz         integer,
564
    percent     integer
565
)"""
566
    )
567
    schema_statements.append(
×
568
        """CREATE TABLE mwait (
569
    id          integer     NOT NULL    PRIMARY KEY,
570
    hints       integer,
571
    extensions  integer
572
)"""
573
    )
574
    schema_statements.append(
×
575
        """CREATE TABLE pwre (
576
    id          integer     NOT NULL    PRIMARY KEY,
577
    cstate      integer,
578
    subcstate   integer,
579
    hw          integer
580
)"""
581
    )
582
    schema_statements.append(
×
583
        """CREATE TABLE exstop (
584
    id          integer     NOT NULL    PRIMARY KEY,
585
    exact_ip    integer
586
)"""
587
    )
588
    schema_statements.append(
×
589
        """CREATE TABLE pwrx (
590
    id              integer     NOT NULL    PRIMARY KEY,
591
    deepest_cstate  integer,
592
    last_cstate     integer,
593
    wake_reason     integer
594
)"""
595
    )
596
    schema_statements.append(
×
597
        """CREATE TABLE context_switches (
598
    id              integer     NOT NULL    PRIMARY KEY,
599
    machine_id      bigint,
600
    time            bigint,
601
    cpu             integer,
602
    thread_out_id   bigint,
603
    comm_out_id     bigint,
604
    thread_in_id    bigint,
605
    comm_in_id      bigint,
606
    flags           integer
607
)"""
608
    )
609

610
    for stmt in schema_statements:
×
611
        do_query(stmt)
×
612

613
    try:
×
614
        do_query('SELECT printf("")')
×
615
        sqlite_has_printf = True
×
616
    except Exception:
×
617
        sqlite_has_printf = False
×
618

619
    views = []
×
620
    views.append(
×
621
        """CREATE VIEW machines_view AS
622
SELECT id, pid, root_dir,
623
    CASE WHEN id=0 THEN 'unknown' WHEN pid=-1 THEN 'host' ELSE 'guest' END AS host_or_guest
624
FROM machines"""
625
    )
626
    views.append(
×
627
        """CREATE VIEW dsos_view AS
628
SELECT id, machine_id,
629
    (SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,
630
    short_name, long_name, build_id
631
FROM dsos"""
632
    )
633
    views.append(
×
634
        """CREATE VIEW symbols_view AS
635
SELECT id, name,
636
    (SELECT short_name FROM dsos WHERE id=dso_id) AS dso,
637
    dso_id, sym_start, sym_end,
638
    CASE WHEN binding=0 THEN 'local' WHEN binding=1 THEN 'global' ELSE 'weak' END AS binding
639
FROM symbols"""
640
    )
641
    views.append(
×
642
        """CREATE VIEW threads_view AS
643
SELECT id, machine_id,
644
    (SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,
645
    process_id, pid, tid
646
FROM threads"""
647
    )
648
    views.append(
×
649
        """CREATE VIEW comm_threads_view AS
650
SELECT comm_id,
651
    (SELECT comm FROM comms WHERE id = comm_id) AS command,
652
    thread_id,
653
    (SELECT pid FROM threads WHERE id = thread_id) AS pid,
654
    (SELECT tid FROM threads WHERE id = thread_id) AS tid
655
FROM comm_threads"""
656
    )
657

658
    if perf_db_export_calls or perf_db_export_callchains:
×
659
        views.append(
×
660
            """CREATE VIEW call_paths_view AS
661
SELECT
662
    c.id,
663
    """
664
            + emit_to_hex("c.ip")
665
            + """ AS ip,
666
    c.symbol_id,
667
    (SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,
668
    (SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,
669
    (SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,
670
    c.parent_id,
671
    """
672
            + emit_to_hex("p.ip")
673
            + """ AS parent_ip,
674
    p.symbol_id AS parent_symbol_id,
675
    (SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,
676
    (SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,
677
    (SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name
678
FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id"""
679
        )
680
    if perf_db_export_calls:
×
681
        views.append(
×
682
            """CREATE VIEW calls_view AS
683
SELECT
684
    calls.id,
685
    thread_id,
686
    (SELECT pid FROM threads WHERE id = thread_id) AS pid,
687
    (SELECT tid FROM threads WHERE id = thread_id) AS tid,
688
    (SELECT comm FROM comms WHERE id = comm_id) AS command,
689
    call_path_id,
690
    """
691
            + emit_to_hex("ip")
692
            + """ AS ip,
693
    symbol_id,
694
    (SELECT name FROM symbols WHERE id = symbol_id) AS symbol,
695
    call_time,
696
    return_time,
697
    return_time - call_time AS elapsed_time,
698
    branch_count,
699
    insn_count,
700
    cyc_count,
701
    CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,
702
    call_id,
703
    return_id,
704
    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,
705
    parent_call_path_id,
706
    calls.parent_id
707
FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id"""
708
        )
709

710
    views.append(
×
711
        """CREATE VIEW samples_view AS
712
SELECT
713
    id,
714
    time,
715
    cpu,
716
    (SELECT pid FROM threads WHERE id = thread_id) AS pid,
717
    (SELECT tid FROM threads WHERE id = thread_id) AS tid,
718
    (SELECT comm FROM comms WHERE id = comm_id) AS command,
719
    (SELECT name FROM selected_events WHERE id = evsel_id) AS event,
720
    """
721
        + emit_to_hex("ip")
722
        + """ AS ip_hex,
723
    (SELECT name FROM symbols WHERE id = symbol_id) AS symbol,
724
    sym_offset,
725
    (SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,
726
    """
727
        + emit_to_hex("to_ip")
728
        + """ AS to_ip_hex,
729
    (SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,
730
    to_sym_offset,
731
    (SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,
732
    (SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,
733
    in_tx,
734
    insn_count,
735
    cyc_count,
736
    CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,
737
    flags
738
FROM samples"""
739
    )
740

741
    views.append(
×
742
        """CREATE VIEW ptwrite_view AS
743
SELECT ptwrite.id, time, cpu,
744
    """
745
        + emit_to_hex("payload")
746
        + """ AS payload_hex,
747
    CASE WHEN exact_ip=0 THEN 'False' ELSE 'True' END AS exact_ip
748
FROM ptwrite INNER JOIN samples ON samples.id = ptwrite.id"""
749
    )
750

751
    views.append(
×
752
        """CREATE VIEW cbr_view AS
753
SELECT cbr.id, time, cpu, cbr, mhz, percent
754
FROM cbr INNER JOIN samples ON samples.id = cbr.id"""
755
    )
756

757
    views.append(
×
758
        """CREATE VIEW mwait_view AS
759
SELECT mwait.id, time, cpu,
760
    """
761
        + emit_to_hex("hints")
762
        + """ AS hints_hex,
763
    """
764
        + emit_to_hex("extensions")
765
        + """ AS extensions_hex
766
FROM mwait INNER JOIN samples ON samples.id = mwait.id"""
767
    )
768

769
    views.append(
×
770
        """CREATE VIEW pwre_view AS
771
SELECT pwre.id, time, cpu, cstate, subcstate,
772
    CASE WHEN hw=0 THEN 'False' ELSE 'True' END AS hw
773
FROM pwre INNER JOIN samples ON samples.id = pwre.id"""
774
    )
775

776
    views.append(
×
777
        """CREATE VIEW exstop_view AS
778
SELECT exstop.id, time, cpu,
779
    CASE WHEN exact_ip=0 THEN 'False' ELSE 'True' END AS exact_ip
780
FROM exstop INNER JOIN samples ON samples.id = exstop.id"""
781
    )
782

783
    views.append(
×
784
        """CREATE VIEW pwrx_view AS
785
SELECT pwrx.id, time, cpu, deepest_cstate, last_cstate,
786
    CASE WHEN wake_reason=1 THEN 'Interrupt'
787
         WHEN wake_reason=2 THEN 'Timer Deadline'
788
         WHEN wake_reason=4 THEN 'Monitored Address'
789
         WHEN wake_reason=8 THEN 'HW'
790
         ELSE wake_reason END AS wake_reason
791
FROM pwrx INNER JOIN samples ON samples.id = pwrx.id"""
792
    )
793

794
    views.append(
×
795
        """CREATE VIEW power_events_view AS
796
SELECT
797
    samples.id,
798
    time,
799
    cpu,
800
    selected_events.name AS event,
801
    CASE WHEN selected_events.name='cbr' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE '' END AS cbr,
802
    CASE WHEN selected_events.name='cbr' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE '' END AS mhz,
803
    CASE WHEN selected_events.name='cbr' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE '' END AS percent,
804
    CASE WHEN selected_events.name='mwait' THEN (SELECT """
805
        + emit_to_hex("hints")
806
        + """ FROM mwait WHERE mwait.id = samples.id) ELSE '' END AS hints_hex,
807
    CASE WHEN selected_events.name='mwait' THEN (SELECT """
808
        + emit_to_hex("extensions")
809
        + """ FROM mwait WHERE mwait.id = samples.id) ELSE '' END AS extensions_hex,
810
    CASE WHEN selected_events.name='pwre' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE '' END AS cstate,
811
    CASE WHEN selected_events.name='pwre' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE '' END AS subcstate,
812
    CASE WHEN selected_events.name='pwre' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE '' END AS hw,
813
    CASE WHEN selected_events.name='exstop' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE '' END AS exact_ip,
814
    CASE WHEN selected_events.name='pwrx' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE '' END AS deepest_cstate,
815
    CASE WHEN selected_events.name='pwrx' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE '' END AS last_cstate,
816
    CASE WHEN selected_events.name='pwrx' THEN (
817
        SELECT CASE WHEN wake_reason=1 THEN 'Interrupt'
818
                    WHEN wake_reason=2 THEN 'Timer Deadline'
819
                    WHEN wake_reason=4 THEN 'Monitored Address'
820
                    WHEN wake_reason=8 THEN 'HW'
821
                    ELSE wake_reason END
822
        FROM pwrx WHERE pwrx.id = samples.id) ELSE '' END AS wake_reason
823
FROM samples
824
INNER JOIN selected_events ON selected_events.id = evsel_id
825
WHERE selected_events.name IN ('cbr','mwait','exstop','pwre','pwrx')"""
826
    )
827

828
    views.append(
×
829
        """CREATE VIEW context_switches_view AS
830
SELECT
831
    context_switches.id,
832
    context_switches.machine_id,
833
    context_switches.time,
834
    context_switches.cpu,
835
    th_out.pid AS pid_out,
836
    th_out.tid AS tid_out,
837
    comm_out.comm AS comm_out,
838
    th_in.pid AS pid_in,
839
    th_in.tid AS tid_in,
840
    comm_in.comm AS comm_in,
841
    CASE WHEN context_switches.flags = 0 THEN 'in'
842
         WHEN context_switches.flags = 1 THEN 'out'
843
         WHEN context_switches.flags = 3 THEN 'out preempt'
844
         ELSE context_switches.flags END AS flags
845
FROM context_switches
846
INNER JOIN threads AS th_out ON th_out.id   = context_switches.thread_out_id
847
INNER JOIN threads AS th_in  ON th_in.id    = context_switches.thread_in_id
848
INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id
849
INNER JOIN comms AS comm_in  ON comm_in.id  = context_switches.comm_in_id"""
850
    )
851

852
    for v in views:
×
853
        do_query(v)
×
854

855
    do_query("END TRANSACTION")
×
856

857
    insert_sql = {
×
858
        "evsel": "INSERT INTO selected_events VALUES (?, ?)",
859
        "machine": "INSERT INTO machines VALUES (?, ?, ?)",
860
        "thread": "INSERT INTO threads VALUES (?, ?, ?, ?, ?)",
861
        "comm": "INSERT INTO comms VALUES (?, ?, ?, ?, ?)",
862
        "comm_thread": "INSERT INTO comm_threads VALUES (?, ?, ?)",
863
        "dso": "INSERT INTO dsos VALUES (?, ?, ?, ?, ?)",
864
        "symbol": "INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)",
865
        "branch_type": "INSERT INTO branch_types VALUES (?, ?)",
866
        "sample_branches": "INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
867
        "sample_all": "INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
868
        "call_path": "INSERT INTO call_paths VALUES (?, ?, ?, ?)",
869
        "call": "INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
870
        "ptwrite": "INSERT INTO ptwrite VALUES (?, ?, ?)",
871
        "cbr": "INSERT INTO cbr VALUES (?, ?, ?, ?)",
872
        "mwait": "INSERT INTO mwait VALUES (?, ?, ?)",
873
        "pwre": "INSERT INTO pwre VALUES (?, ?, ?, ?)",
874
        "exstop": "INSERT INTO exstop VALUES (?, ?)",
875
        "pwrx": "INSERT INTO pwrx VALUES (?, ?, ?, ?)",
876
        "context_switch": "INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
877
    }
878

879
    call_path_insert_sql = (
×
880
        insert_sql["call_path"]
881
        if (perf_db_export_calls or perf_db_export_callchains)
882
        else None
883
    )
884
    call_insert_sql = insert_sql["call"] if perf_db_export_calls else None
×
NEW
885
    sample_insert_sql = (
×
886
        insert_sql["sample_branches"] if branches else insert_sql["sample_all"]
887
    )
888

889
    return 0
×
890

891

892
if __name__ == "__main__":
×
893
    sys.exit(main())
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc