[PATCH 2/2] rteval: timerlat: Improve handling of truncated histogram output

John Kacur <[email protected]> Fri, 5 Jun 2026 17:06:48 -0400
Newsgroups org.kernel.vger.linux-rt-users
Message-ID <[email protected]>
When timerlat is terminated with SIGINT during rteval shutdown, the
output buffer may not be fully flushed, resulting in an incomplete
final histogram line. This caused IndexError warnings when parsing.

Changes:
- Validate histogram lines have expected field count before parsing
  (1 index + numcores * 3 values) to skip incomplete lines early
- Downgrade parsing error from WARN to DEBUG since incomplete output
  is expected during normal process termination
- Calculate expected field count dynamically based on actual core count
  instead of using magic number 49

This eliminates confusing warnings during normal operation while still
catching unexpected parsing issues in debug logs.

Assisted-by: Claude Sonnet 4.5 <[email protected]>
Signed-off-by: John Kacur <[email protected]>
---
 rteval/modules/measurement/timerlat.py | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/rteval/modules/measurement/timerlat.py b/rteval/modules/measurement/timerlat.py
index a3219e216296..7f592ea697af 100644
--- a/rteval/modules/measurement/timerlat.py
+++ b/rteval/modules/measurement/timerlat.py
@@ -480,6 +480,13 @@ class Timerlat(rtevalModulePrototype):
                     self._log(Log.DEBUG, f'timerlat: unexpected output: {line}')
                     continue
 
+                # Validate line has expected number of fields: 1 index + (cores * 3 values)
+                expected_fields = 1 + self.__numcores * 3
+                if len(vals) < expected_fields:
+                    self._log(Log.DEBUG, f'Skipping incomplete histogram line at bucket {index} '
+                              f'({len(vals)} fields, expected {expected_fields})')
+                    continue
+
                 for i, core in enumerate(self.__cpus):
                     # There might not be a count on every cpu if tracing invoked
                     try:
@@ -495,7 +502,8 @@ class Timerlat(rtevalModulePrototype):
                                                          int(vals[i*3+3]))
                     except (IndexError, ValueError) as e:
                         # Handle partial output from rtla (can happen on SIGINT during cleanup)
-                        self._log(Log.WARN, f"Error parsing timerlat bucket data for core {core}: {e}")
+                        self._log(Log.DEBUG, f"Skipping incomplete bucket data for core {core} "
+                                  f"(expected during process termination): {e}")
                         continue
 
                 # Generate statistics for each RunData object
-- 
2.54.0