diff options
author | Aditya Chitnis <chitnis@google.com> | 2023-04-27 00:43:35 +0000 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-04-27 00:43:35 +0000 |
commit | baf334a37e485f846790924eb531cd897b797c5f (patch) | |
tree | 7930d20cce91b6eac05ddf1fa69f68585028962e /pw_trace | |
parent | db61395dfd837ab777a0f62c686c04c4ea20df96 (diff) | |
download | pigweed-baf334a37e485f846790924eb531cd897b797c5f.tar.gz |
pw_trace: Decode byte array for string data
JSON library cannot dump trace events with byte arrays so we have to
decode them before adding them as arguments
Bug: 269176238
Test: updated trace_test.py passes, using TDD
Change-Id: I55e22222f533c1ae8f8206bcd5b36524169678fb
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/139570
Commit-Queue: Aditya Chitnis <chitnis@google.com>
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Erik Gilling <konkers@google.com>
Diffstat (limited to 'pw_trace')
-rwxr-xr-x | pw_trace/py/pw_trace/trace.py | 22 | ||||
-rwxr-xr-x | pw_trace/py/trace_test.py | 12 |
2 files changed, 22 insertions, 12 deletions
diff --git a/pw_trace/py/pw_trace/trace.py b/pw_trace/py/pw_trace/trace.py index 571d66f0c..7535520c9 100755 --- a/pw_trace/py/pw_trace/trace.py +++ b/pw_trace/py/pw_trace/trace.py @@ -73,16 +73,21 @@ def event_has_trace_id(event_type): def decode_struct_fmt_args(event): """Decodes the trace's event data for struct-formatted data""" args = {} - # we assume all data is packed, little-endian ordering if not specified + # We assume all data is packed, little-endian ordering if not specified. struct_fmt = event.data_fmt[len("@pw_py_struct_fmt:") :] if not struct_fmt.startswith(_ORDERING_CHARS): struct_fmt = "<" + struct_fmt try: - # needed in case the buffer is larger than expected + # Assert is needed in case the buffer is larger than expected. assert struct.calcsize(struct_fmt) == len(event.data) items = struct.unpack_from(struct_fmt, event.data) for i, item in enumerate(items): - args["data_" + str(i)] = item + # Try to decode the item in case it is a byte array (string) since + # the JSON lib cannot serialize byte arrays. + try: + args["data_" + str(i)] = item.decode() + except (UnicodeDecodeError, AttributeError): + args["data_" + str(i)] = item except (AssertionError, struct.error): args["error"] = ( f"Mismatched struct/data format {event.data_fmt} " @@ -98,7 +103,7 @@ def decode_map_fmt_args(event): args = {} fmt = event.data_fmt[len("@pw_py_map_fmt:") :] - # we assume all data is packed, little-endian ordering if not specified + # We assume all data is packed, little-endian ordering if not specified. if not fmt.startswith(_ORDERING_CHARS): fmt = '<' + fmt @@ -115,11 +120,16 @@ def decode_map_fmt_args(event): args["error"] = f"Invalid map format {event.data_fmt}" else: try: - # needed in case the buffer is larger than expected + # Assert is needed in case the buffer is larger than expected. assert struct.calcsize(fmt_bytes) == len(event.data) items = struct.unpack_from(fmt_bytes, event.data) for i, item in enumerate(items): - args[names[i]] = item + # Try to decode the item in case it is a byte array (string) + # since the JSON lib cannot serialize byte arrays. + try: + args[names[i]] = item.decode() + except (UnicodeDecodeError, AttributeError): + args[names[i]] = item except (AssertionError, struct.error): args["error"] = ( f"Mismatched map/data format {event.data_fmt} " diff --git a/pw_trace/py/trace_test.py b/pw_trace/py/trace_test.py index 60249623d..181824553 100755 --- a/pw_trace/py/trace_test.py +++ b/pw_trace/py/trace_test.py @@ -194,8 +194,8 @@ class TestTraceGenerateJson(unittest.TestCase): label="counter", timestamp_us=10, has_data=True, - data_fmt="@pw_py_struct_fmt:Hl", - data=struct.pack("<Hl", 5, 2), + data_fmt="@pw_py_struct_fmt:Hl3s", + data=struct.pack("<Hl3s", 5, 2, b'abc'), ) json_lines = trace.generate_trace_json([event]) self.assertEqual(1, len(json_lines)) @@ -207,7 +207,7 @@ class TestTraceGenerateJson(unittest.TestCase): "name": "counter", "ts": 10, "s": "p", - "args": {"data_0": 5, "data_1": 2}, + "args": {"data_0": 5, "data_1": 2, "data_2": 'abc'}, }, ) @@ -298,8 +298,8 @@ class TestTraceGenerateJson(unittest.TestCase): label="label", timestamp_us=10, has_data=True, - data_fmt="@pw_py_map_fmt:{Field: l, Field2: l }", - data=struct.pack("<ll", 20, 40), + data_fmt="@pw_py_map_fmt:{Field: l, Field2: l , Field3: 3s}", + data=struct.pack("<ll3s", 20, 40, b'abc'), ) json_lines = trace.generate_trace_json([event]) self.assertEqual(1, len(json_lines)) @@ -311,7 +311,7 @@ class TestTraceGenerateJson(unittest.TestCase): "name": "label", "ts": 10, "s": "p", - "args": {"Field": 20, "Field2": 40}, + "args": {"Field": 20, "Field2": 40, "Field3": 'abc'}, }, ) |