commit a54f9321a440fa6eb1efc2f4f02fd90eed839b84
parent 7396723211635a381c065fb1ee9632bd69bbaa2c
Author: Florian Quèze <florian@queze.net>
Date: Tue, 7 Oct 2025 19:14:30 +0000
Bug 1993018 - Show crash markers in resource usage profiles, r=ahal.
Differential Revision: https://phabricator.services.mozilla.com/D267833
Diffstat:
3 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/testing/mozbase/mozlog/mozlog/handlers/resourcehandler.py b/testing/mozbase/mozlog/mozlog/handlers/resourcehandler.py
@@ -61,3 +61,6 @@ class ResourceHandler(LogHandler):
def process_output(self, data):
SystemResourceMonitor.test_status(data)
+
+ def crash(self, data):
+ SystemResourceMonitor.crash(data)
diff --git a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
@@ -712,6 +712,45 @@ class SystemResourceMonitor:
SystemResourceMonitor.record_event(marker_name, timestamp, marker_data)
+ @staticmethod
+ def crash(data):
+ """Record a crash event.
+
+ Args:
+ data: Dictionary containing crash data including:
+ - "signature": crash signature
+ - "reason": crash reason (optional)
+ - "test": test name (optional)
+ - "minidump_path": path to minidump file (optional)
+ - "time": timestamp in milliseconds
+ """
+ if not SystemResourceMonitor.instance:
+ return
+
+ time_sec = data["time"] / 1000
+ timestamp = SystemResourceMonitor.instance.convert_to_monotonic_time(time_sec)
+
+ marker_data = {
+ "type": "Crash",
+ "color": "red",
+ }
+
+ if signature := data.get("signature"):
+ marker_data["signature"] = signature
+ if reason := data.get("reason"):
+ marker_data["reason"] = reason
+ if test := data.get("test"):
+ marker_data["test"] = test
+
+ if minidump_path := data.get("minidump_path"):
+ # Extract the minidump name (without extension) from the path
+ # e.g., "/tmp/xpc-other-k49po531/7a7f1343-4dc3-224c-638b-5806ab642301.dmp"
+ # -> "7a7f1343-4dc3-224c-638b-5806ab642301"
+ minidump_name = os.path.splitext(os.path.basename(minidump_path))[0]
+ marker_data["minidump"] = minidump_name
+
+ SystemResourceMonitor.record_event("CRASH", timestamp, marker_data)
+
@contextmanager
def phase(self, name):
"""Context manager for recording an active phase."""
@@ -1202,6 +1241,38 @@ class SystemResourceMonitor:
],
},
{
+ "name": "Crash",
+ "tableLabel": "{marker.data.signature} — {marker.data.test}",
+ "display": ["marker-chart", "marker-table"],
+ "colorField": "color",
+ "data": [
+ {
+ "key": "signature",
+ "label": "Signature",
+ "format": "string",
+ },
+ {
+ "key": "reason",
+ "label": "Reason",
+ "format": "string",
+ },
+ {
+ "key": "test",
+ "label": "Test Name",
+ "format": "string",
+ },
+ {
+ "key": "minidump",
+ "label": "Minidump",
+ "format": "string",
+ },
+ {
+ "key": "color",
+ "hidden": True,
+ },
+ ],
+ },
+ {
"name": "Mem",
"tooltipLabel": "{marker.name}",
"display": [],
diff --git a/testing/mozharness/mozharness/mozilla/structuredlog.py b/testing/mozharness/mozharness/mozilla/structuredlog.py
@@ -112,6 +112,8 @@ class StructuredOutputParser(OutputParser):
SystemResourceMonitor.test_status(data)
elif action == "process_output":
SystemResourceMonitor.test_status(data)
+ elif action == "crash":
+ SystemResourceMonitor.crash(data)
elif action == "suite_start":
SystemResourceMonitor.begin_marker("suite", data["source"])
elif action == "suite_end":