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

ZJU-SPAIL / pipa / 22699554347

05 Mar 2026 02:33AM UTC coverage: 19.922% (-50.1%) from 70.041%
22699554347

push

github

Rui Hu
Merge github/main, resolve two version conflicts by keeping gitlab local

6 of 2484 new or added lines in 35 files covered. (0.24%)

871 of 4372 relevant lines covered (19.92%)

0.2 hits per line

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

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

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

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

NEW
15
call_path_events = 0
×
NEW
16
call_return_events = 0
×
17

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

28

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

32

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

36

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

49

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

56

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

63

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

69

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

74

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

78

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

82

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

86

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

90

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

94

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

98

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

102

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

106

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

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

122

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

130

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

138

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

146

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

154

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

162

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

171

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

178

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

190

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

205

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

209

NEW
210
def trace_begin():
×
NEW
211
    printdate("Writing records...")
×
NEW
212
    do_query("BEGIN TRANSACTION")
×
NEW
213
    evsel_table(0, "unknown")
×
NEW
214
    machine_table(0, 0, "unknown")
×
NEW
215
    thread_table(0, 0, 0, -1, -1)
×
NEW
216
    comm_table(0, "unknown", 0, 0, 0)
×
NEW
217
    dso_table(0, 0, "unknown", "unknown", "")
×
NEW
218
    symbol_table(0, 0, 0, 0, 0, "unknown")
×
NEW
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
    )
NEW
222
    if call_path_insert_sql is not None:
×
NEW
223
        call_path_table(0, 0, 0, 0)
×
NEW
224
    if call_insert_sql is not None:
×
NEW
225
        call_return_table(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
×
226

227

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

235

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

240

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

267

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

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

NEW
283
    printdate("Dropping unused tables")
×
NEW
284
    if is_table_empty("ptwrite"):
×
NEW
285
        drop("ptwrite")
×
NEW
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
    ):
NEW
292
        drop("power_events")
×
NEW
293
        drop("mwait")
×
NEW
294
        drop("pwre")
×
NEW
295
        drop("exstop")
×
NEW
296
        drop("pwrx")
×
NEW
297
        if is_table_empty("cbr"):
×
NEW
298
            drop("cbr")
×
NEW
299
    if is_table_empty("context_switches"):
×
NEW
300
        drop("context_switches")
×
301

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

309

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

314

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

318

NEW
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

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

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

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

NEW
350
    dbname = argv[0]
×
351

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

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

NEW
361
    branches = columns == "branches"
×
362

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

NEW
380
    if perf_db_export_calls:
×
NEW
381
        perf_db_export_callchains = True
×
382

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

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

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

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

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

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

NEW
450
    if branches:
×
NEW
451
        schema_statements.append("""CREATE TABLE samples (
×
452
        id          integer     NOT NULL    PRIMARY KEY,
453
        evsel_id    bigint,
454
        machine_id  bigint,
455
        thread_id   bigint,
456
        comm_id     bigint,
457
        dso_id      bigint,
458
        symbol_id   bigint,
459
        sym_offset  bigint,
460
        ip          bigint,
461
        time        bigint,
462
        cpu         integer,
463
        to_dso_id   bigint,
464
        to_symbol_id bigint,
465
        to_sym_offset bigint,
466
        to_ip       bigint,
467
        branch_type integer,
468
        in_tx       boolean,
469
        call_path_id bigint,
470
        insn_count  bigint,
471
        cyc_count   bigint,
472
        flags       integer
473
    )""")
474
    else:
NEW
475
        schema_statements.append("""CREATE TABLE samples (
×
476
        id          integer     NOT NULL    PRIMARY KEY,
477
        evsel_id    bigint,
478
        machine_id  bigint,
479
        thread_id   bigint,
480
        comm_id     bigint,
481
        dso_id      bigint,
482
        symbol_id   bigint,
483
        sym_offset  bigint,
484
        ip          bigint,
485
        time        bigint,
486
        cpu         integer,
487
        to_dso_id   bigint,
488
        to_symbol_id bigint,
489
        to_sym_offset bigint,
490
        to_ip       bigint,
491
        period      bigint,
492
        weight      bigint,
493
        transaction_ bigint,
494
        data_src    bigint,
495
        branch_type integer,
496
        in_tx       boolean,
497
        call_path_id bigint,
498
        insn_count  bigint,
499
        cyc_count   bigint,
500
        flags       integer
501
    )""")
502

NEW
503
    if perf_db_export_calls or perf_db_export_callchains:
×
NEW
504
        schema_statements.append("""CREATE TABLE call_paths (
×
505
        id          integer     NOT NULL    PRIMARY KEY,
506
        parent_id   bigint,
507
        symbol_id   bigint,
508
        ip          bigint
509
    )""")
NEW
510
    if perf_db_export_calls:
×
NEW
511
        schema_statements.append("""CREATE TABLE calls (
×
512
        id          integer     NOT NULL    PRIMARY KEY,
513
        thread_id   bigint,
514
        comm_id     bigint,
515
        call_path_id bigint,
516
        call_time   bigint,
517
        return_time bigint,
518
        branch_count bigint,
519
        call_id     bigint,
520
        return_id   bigint,
521
        parent_call_path_id bigint,
522
        flags       integer,
523
        parent_id   bigint,
524
        insn_count  bigint,
525
        cyc_count   bigint
526
    )""")
527

NEW
528
    schema_statements.append("""CREATE TABLE ptwrite (
×
529
    id          integer     NOT NULL    PRIMARY KEY,
530
    payload     bigint,
531
    exact_ip    integer
532
)""")
NEW
533
    schema_statements.append("""CREATE TABLE cbr (
×
534
    id          integer     NOT NULL    PRIMARY KEY,
535
    cbr         integer,
536
    mhz         integer,
537
    percent     integer
538
)""")
NEW
539
    schema_statements.append("""CREATE TABLE mwait (
×
540
    id          integer     NOT NULL    PRIMARY KEY,
541
    hints       integer,
542
    extensions  integer
543
)""")
NEW
544
    schema_statements.append("""CREATE TABLE pwre (
×
545
    id          integer     NOT NULL    PRIMARY KEY,
546
    cstate      integer,
547
    subcstate   integer,
548
    hw          integer
549
)""")
NEW
550
    schema_statements.append("""CREATE TABLE exstop (
×
551
    id          integer     NOT NULL    PRIMARY KEY,
552
    exact_ip    integer
553
)""")
NEW
554
    schema_statements.append("""CREATE TABLE pwrx (
×
555
    id              integer     NOT NULL    PRIMARY KEY,
556
    deepest_cstate  integer,
557
    last_cstate     integer,
558
    wake_reason     integer
559
)""")
NEW
560
    schema_statements.append("""CREATE TABLE context_switches (
×
561
    id              integer     NOT NULL    PRIMARY KEY,
562
    machine_id      bigint,
563
    time            bigint,
564
    cpu             integer,
565
    thread_out_id   bigint,
566
    comm_out_id     bigint,
567
    thread_in_id    bigint,
568
    comm_in_id      bigint,
569
    flags           integer
570
)""")
571

NEW
572
    for stmt in schema_statements:
×
NEW
573
        do_query(stmt)
×
574

NEW
575
    try:
×
NEW
576
        do_query('SELECT printf("")')
×
NEW
577
        sqlite_has_printf = True
×
NEW
578
    except Exception:
×
NEW
579
        sqlite_has_printf = False
×
580

NEW
581
    views = []
×
NEW
582
    views.append("""CREATE VIEW machines_view AS
×
583
SELECT id, pid, root_dir,
584
    CASE WHEN id=0 THEN 'unknown' WHEN pid=-1 THEN 'host' ELSE 'guest' END AS host_or_guest
585
FROM machines""")
NEW
586
    views.append("""CREATE VIEW dsos_view AS
×
587
SELECT id, machine_id,
588
    (SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,
589
    short_name, long_name, build_id
590
FROM dsos""")
NEW
591
    views.append("""CREATE VIEW symbols_view AS
×
592
SELECT id, name,
593
    (SELECT short_name FROM dsos WHERE id=dso_id) AS dso,
594
    dso_id, sym_start, sym_end,
595
    CASE WHEN binding=0 THEN 'local' WHEN binding=1 THEN 'global' ELSE 'weak' END AS binding
596
FROM symbols""")
NEW
597
    views.append("""CREATE VIEW threads_view AS
×
598
SELECT id, machine_id,
599
    (SELECT host_or_guest FROM machines_view WHERE id = machine_id) AS host_or_guest,
600
    process_id, pid, tid
601
FROM threads""")
NEW
602
    views.append("""CREATE VIEW comm_threads_view AS
×
603
SELECT comm_id,
604
    (SELECT comm FROM comms WHERE id = comm_id) AS command,
605
    thread_id,
606
    (SELECT pid FROM threads WHERE id = thread_id) AS pid,
607
    (SELECT tid FROM threads WHERE id = thread_id) AS tid
608
FROM comm_threads""")
609

NEW
610
    if perf_db_export_calls or perf_db_export_callchains:
×
NEW
611
        views.append(
×
612
            """CREATE VIEW call_paths_view AS
613
SELECT
614
    c.id,
615
    """
616
            + emit_to_hex("c.ip")
617
            + """ AS ip,
618
    c.symbol_id,
619
    (SELECT name FROM symbols WHERE id = c.symbol_id) AS symbol,
620
    (SELECT dso_id FROM symbols WHERE id = c.symbol_id) AS dso_id,
621
    (SELECT dso FROM symbols_view WHERE id = c.symbol_id) AS dso_short_name,
622
    c.parent_id,
623
    """
624
            + emit_to_hex("p.ip")
625
            + """ AS parent_ip,
626
    p.symbol_id AS parent_symbol_id,
627
    (SELECT name FROM symbols WHERE id = p.symbol_id) AS parent_symbol,
628
    (SELECT dso_id FROM symbols WHERE id = p.symbol_id) AS parent_dso_id,
629
    (SELECT dso FROM symbols_view WHERE id = p.symbol_id) AS parent_dso_short_name
630
FROM call_paths c INNER JOIN call_paths p ON p.id = c.parent_id"""
631
        )
NEW
632
    if perf_db_export_calls:
×
NEW
633
        views.append(
×
634
            """CREATE VIEW calls_view AS
635
SELECT
636
    calls.id,
637
    thread_id,
638
    (SELECT pid FROM threads WHERE id = thread_id) AS pid,
639
    (SELECT tid FROM threads WHERE id = thread_id) AS tid,
640
    (SELECT comm FROM comms WHERE id = comm_id) AS command,
641
    call_path_id,
642
    """
643
            + emit_to_hex("ip")
644
            + """ AS ip,
645
    symbol_id,
646
    (SELECT name FROM symbols WHERE id = symbol_id) AS symbol,
647
    call_time,
648
    return_time,
649
    return_time - call_time AS elapsed_time,
650
    branch_count,
651
    insn_count,
652
    cyc_count,
653
    CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,
654
    call_id,
655
    return_id,
656
    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,
657
    parent_call_path_id,
658
    calls.parent_id
659
FROM calls INNER JOIN call_paths ON call_paths.id = call_path_id"""
660
        )
661

NEW
662
    views.append(
×
663
        """CREATE VIEW samples_view AS
664
SELECT
665
    id,
666
    time,
667
    cpu,
668
    (SELECT pid FROM threads WHERE id = thread_id) AS pid,
669
    (SELECT tid FROM threads WHERE id = thread_id) AS tid,
670
    (SELECT comm FROM comms WHERE id = comm_id) AS command,
671
    (SELECT name FROM selected_events WHERE id = evsel_id) AS event,
672
    """
673
        + emit_to_hex("ip")
674
        + """ AS ip_hex,
675
    (SELECT name FROM symbols WHERE id = symbol_id) AS symbol,
676
    sym_offset,
677
    (SELECT short_name FROM dsos WHERE id = dso_id) AS dso_short_name,
678
    """
679
        + emit_to_hex("to_ip")
680
        + """ AS to_ip_hex,
681
    (SELECT name FROM symbols WHERE id = to_symbol_id) AS to_symbol,
682
    to_sym_offset,
683
    (SELECT short_name FROM dsos WHERE id = to_dso_id) AS to_dso_short_name,
684
    (SELECT name FROM branch_types WHERE id = branch_type) AS branch_type_name,
685
    in_tx,
686
    insn_count,
687
    cyc_count,
688
    CASE WHEN cyc_count=0 THEN CAST(0 AS FLOAT) ELSE ROUND(CAST(insn_count AS FLOAT) / cyc_count, 2) END AS IPC,
689
    flags
690
FROM samples"""
691
    )
692

NEW
693
    views.append(
×
694
        """CREATE VIEW ptwrite_view AS
695
SELECT ptwrite.id, time, cpu,
696
    """
697
        + emit_to_hex("payload")
698
        + """ AS payload_hex,
699
    CASE WHEN exact_ip=0 THEN 'False' ELSE 'True' END AS exact_ip
700
FROM ptwrite INNER JOIN samples ON samples.id = ptwrite.id"""
701
    )
702

NEW
703
    views.append("""CREATE VIEW cbr_view AS
×
704
SELECT cbr.id, time, cpu, cbr, mhz, percent
705
FROM cbr INNER JOIN samples ON samples.id = cbr.id""")
706

NEW
707
    views.append(
×
708
        """CREATE VIEW mwait_view AS
709
SELECT mwait.id, time, cpu,
710
    """
711
        + emit_to_hex("hints")
712
        + """ AS hints_hex,
713
    """
714
        + emit_to_hex("extensions")
715
        + """ AS extensions_hex
716
FROM mwait INNER JOIN samples ON samples.id = mwait.id"""
717
    )
718

NEW
719
    views.append("""CREATE VIEW pwre_view AS
×
720
SELECT pwre.id, time, cpu, cstate, subcstate,
721
    CASE WHEN hw=0 THEN 'False' ELSE 'True' END AS hw
722
FROM pwre INNER JOIN samples ON samples.id = pwre.id""")
723

NEW
724
    views.append("""CREATE VIEW exstop_view AS
×
725
SELECT exstop.id, time, cpu,
726
    CASE WHEN exact_ip=0 THEN 'False' ELSE 'True' END AS exact_ip
727
FROM exstop INNER JOIN samples ON samples.id = exstop.id""")
728

NEW
729
    views.append("""CREATE VIEW pwrx_view AS
×
730
SELECT pwrx.id, time, cpu, deepest_cstate, last_cstate,
731
    CASE WHEN wake_reason=1 THEN 'Interrupt'
732
         WHEN wake_reason=2 THEN 'Timer Deadline'
733
         WHEN wake_reason=4 THEN 'Monitored Address'
734
         WHEN wake_reason=8 THEN 'HW'
735
         ELSE wake_reason END AS wake_reason
736
FROM pwrx INNER JOIN samples ON samples.id = pwrx.id""")
737

NEW
738
    views.append(
×
739
        """CREATE VIEW power_events_view AS
740
SELECT
741
    samples.id,
742
    time,
743
    cpu,
744
    selected_events.name AS event,
745
    CASE WHEN selected_events.name='cbr' THEN (SELECT cbr FROM cbr WHERE cbr.id = samples.id) ELSE '' END AS cbr,
746
    CASE WHEN selected_events.name='cbr' THEN (SELECT mhz FROM cbr WHERE cbr.id = samples.id) ELSE '' END AS mhz,
747
    CASE WHEN selected_events.name='cbr' THEN (SELECT percent FROM cbr WHERE cbr.id = samples.id) ELSE '' END AS percent,
748
    CASE WHEN selected_events.name='mwait' THEN (SELECT """
749
        + emit_to_hex("hints")
750
        + """ FROM mwait WHERE mwait.id = samples.id) ELSE '' END AS hints_hex,
751
    CASE WHEN selected_events.name='mwait' THEN (SELECT """
752
        + emit_to_hex("extensions")
753
        + """ FROM mwait WHERE mwait.id = samples.id) ELSE '' END AS extensions_hex,
754
    CASE WHEN selected_events.name='pwre' THEN (SELECT cstate FROM pwre WHERE pwre.id = samples.id) ELSE '' END AS cstate,
755
    CASE WHEN selected_events.name='pwre' THEN (SELECT subcstate FROM pwre WHERE pwre.id = samples.id) ELSE '' END AS subcstate,
756
    CASE WHEN selected_events.name='pwre' THEN (SELECT hw FROM pwre WHERE pwre.id = samples.id) ELSE '' END AS hw,
757
    CASE WHEN selected_events.name='exstop' THEN (SELECT exact_ip FROM exstop WHERE exstop.id = samples.id) ELSE '' END AS exact_ip,
758
    CASE WHEN selected_events.name='pwrx' THEN (SELECT deepest_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE '' END AS deepest_cstate,
759
    CASE WHEN selected_events.name='pwrx' THEN (SELECT last_cstate FROM pwrx WHERE pwrx.id = samples.id) ELSE '' END AS last_cstate,
760
    CASE WHEN selected_events.name='pwrx' THEN (
761
        SELECT CASE WHEN wake_reason=1 THEN 'Interrupt'
762
                    WHEN wake_reason=2 THEN 'Timer Deadline'
763
                    WHEN wake_reason=4 THEN 'Monitored Address'
764
                    WHEN wake_reason=8 THEN 'HW'
765
                    ELSE wake_reason END
766
        FROM pwrx WHERE pwrx.id = samples.id) ELSE '' END AS wake_reason
767
FROM samples
768
INNER JOIN selected_events ON selected_events.id = evsel_id
769
WHERE selected_events.name IN ('cbr','mwait','exstop','pwre','pwrx')"""
770
    )
771

NEW
772
    views.append("""CREATE VIEW context_switches_view AS
×
773
SELECT
774
    context_switches.id,
775
    context_switches.machine_id,
776
    context_switches.time,
777
    context_switches.cpu,
778
    th_out.pid AS pid_out,
779
    th_out.tid AS tid_out,
780
    comm_out.comm AS comm_out,
781
    th_in.pid AS pid_in,
782
    th_in.tid AS tid_in,
783
    comm_in.comm AS comm_in,
784
    CASE WHEN context_switches.flags = 0 THEN 'in'
785
         WHEN context_switches.flags = 1 THEN 'out'
786
         WHEN context_switches.flags = 3 THEN 'out preempt'
787
         ELSE context_switches.flags END AS flags
788
FROM context_switches
789
INNER JOIN threads AS th_out ON th_out.id   = context_switches.thread_out_id
790
INNER JOIN threads AS th_in  ON th_in.id    = context_switches.thread_in_id
791
INNER JOIN comms AS comm_out ON comm_out.id = context_switches.comm_out_id
792
INNER JOIN comms AS comm_in  ON comm_in.id  = context_switches.comm_in_id""")
793

NEW
794
    for v in views:
×
NEW
795
        do_query(v)
×
796

NEW
797
    do_query("END TRANSACTION")
×
798

NEW
799
    insert_sql = {
×
800
        "evsel": "INSERT INTO selected_events VALUES (?, ?)",
801
        "machine": "INSERT INTO machines VALUES (?, ?, ?)",
802
        "thread": "INSERT INTO threads VALUES (?, ?, ?, ?, ?)",
803
        "comm": "INSERT INTO comms VALUES (?, ?, ?, ?, ?)",
804
        "comm_thread": "INSERT INTO comm_threads VALUES (?, ?, ?)",
805
        "dso": "INSERT INTO dsos VALUES (?, ?, ?, ?, ?)",
806
        "symbol": "INSERT INTO symbols VALUES (?, ?, ?, ?, ?, ?)",
807
        "branch_type": "INSERT INTO branch_types VALUES (?, ?)",
808
        "sample_branches": "INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
809
        "sample_all": "INSERT INTO samples VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
810
        "call_path": "INSERT INTO call_paths VALUES (?, ?, ?, ?)",
811
        "call": "INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
812
        "ptwrite": "INSERT INTO ptwrite VALUES (?, ?, ?)",
813
        "cbr": "INSERT INTO cbr VALUES (?, ?, ?, ?)",
814
        "mwait": "INSERT INTO mwait VALUES (?, ?, ?)",
815
        "pwre": "INSERT INTO pwre VALUES (?, ?, ?, ?)",
816
        "exstop": "INSERT INTO exstop VALUES (?, ?)",
817
        "pwrx": "INSERT INTO pwrx VALUES (?, ?, ?, ?)",
818
        "context_switch": "INSERT INTO context_switches VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
819
    }
820

NEW
821
    call_path_insert_sql = (
×
822
        insert_sql["call_path"]
823
        if (perf_db_export_calls or perf_db_export_callchains)
824
        else None
825
    )
NEW
826
    call_insert_sql = insert_sql["call"] if perf_db_export_calls else None
×
NEW
827
    sample_insert_sql = (
×
828
        insert_sql["sample_branches"] if branches else insert_sql["sample_all"]
829
    )
830

NEW
831
    return 0
×
832

833

NEW
834
if __name__ == "__main__":
×
NEW
835
    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