[PATCH v3 7/9] perf python event_analyzing_sample: Default to in-memory SQLite database

From: Ian Rogers

Date: Tue Sep 29 2026 - 03:01:00 EST


When -d/--db is not specified, event_analyzing_sample.py created a
temporary file in /tmp via tempfile.mkstemp() and deleted it in
trace_end(). As noted during review, creating the database in a shared
/tmp directory does not reserve SQLite's auxiliary sidecar filenames
(-journal or -wal), and a temporary on-disk file is unnecessary when the
caller did not ask to persist the database.

Default to sqlite3.connect(":memory:") when db_path is not provided,
removing the temporary file creation and cleanup logic, and test both
the default in-memory mode and explicit -d file mode in
test_event_analyzing_sample_python.sh.

Fixes: eeb70645a809 ("perf python: Port event_analyzing_sample to perf module")
Assisted-by: Antigravity:gemini-3.1-pro
Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
tools/perf/python/event_analyzing_sample.py | 35 ++++++-------------
.../test_event_analyzing_sample_python.sh | 8 ++++-
2 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/tools/perf/python/event_analyzing_sample.py b/tools/perf/python/event_analyzing_sample.py
index 15b47cff9fa3..b4efee88d94b 100755
--- a/tools/perf/python/event_analyzing_sample.py
+++ b/tools/perf/python/event_analyzing_sample.py
@@ -17,10 +17,8 @@ from __future__ import annotations

import argparse
import math
-import os
import sqlite3
import struct
-import tempfile
from typing import Any
import perf

@@ -117,16 +115,11 @@ session: Any = None

class _DB:
con: sqlite3.Connection | None = None
- temp_path: str | None = None

def trace_begin(db_path: str | None = None) -> None:
"""Initialize database tables."""
print("In trace_begin:\n")
- if not db_path:
- fd, db_path = tempfile.mkstemp(prefix="perf_events_", suffix=".db")
- os.close(fd)
- _DB.temp_path = db_path
- con = sqlite3.connect(db_path)
+ con = sqlite3.connect(db_path or ":memory:")
try:
# Drop any pre-existing tables so repeated runs do not accumulate duplicate events.
con.execute("drop table if exists gen_events;")
@@ -297,28 +290,20 @@ def show_pebs_ll() -> None:
def trace_end() -> None:
"""Called at the end of trace processing."""
print("In trace_end:\n")
- try:
- if _DB.con:
- try:
- _DB.con.commit()
- show_general_events()
- show_pebs_ll()
- finally:
- _DB.con.close()
- _DB.con = None
- finally:
- if _DB.temp_path and os.path.exists(_DB.temp_path):
- try:
- os.remove(_DB.temp_path)
- except OSError:
- pass
- _DB.temp_path = None
+ if _DB.con:
+ try:
+ _DB.con.commit()
+ show_general_events()
+ show_pebs_ll()
+ finally:
+ _DB.con.close()
+ _DB.con = None

if __name__ == "__main__":
ap = argparse.ArgumentParser(description="Analyze events with SQLite")
ap.add_argument("-i", "--input", default="perf.data", help="Input file name")
ap.add_argument("-d", "--db", "--database", dest="database", default=None,
- help="Database file name (defaults to a temporary file cleaned up on exit)")
+ help="Database file name (defaults to an in-memory database)")
args = ap.parse_args()

try:
diff --git a/tools/perf/tests/shell/test_event_analyzing_sample_python.sh b/tools/perf/tests/shell/test_event_analyzing_sample_python.sh
index 5f0a41080acf..cddb12b67698 100755
--- a/tools/perf/tests/shell/test_event_analyzing_sample_python.sh
+++ b/tools/perf/tests/shell/test_event_analyzing_sample_python.sh
@@ -45,8 +45,14 @@ test_file_mode() {
exit 2
fi

- # Run the script
+ # Run the script with default (:memory:) database and with explicit -d path
if ! perf script event_analyzing_sample -i "${temp_data}" \
+ > "${temp_dir}/perf.mem.out" 2>&1 || \
+ ! grep -q "Statistics about the general events" "${temp_dir}/perf.mem.out" || \
+ grep -q "Error creating/inserting event" "${temp_dir}/perf.mem.out"; then
+ echo "Default in-memory database mode test failed."
+ err=1
+ elif ! perf script event_analyzing_sample -i "${temp_data}" \
-d "${temp_db}" > "${temp_dir}/perf.out" 2>&1; then
echo "File mode test failed."
err=1
--
2.56.0.rc1.315.gc6ed9934b7-goog