[Concept,03/27] proftool: Fix funcgraph depth for exit records

Message ID 20260119204130.3972647-4-sjg@u-boot.org
State New
Headers
Series Expo debugging and textedit improvements (part E) |

Commit Message

Simon Glass Jan. 19, 2026, 8:40 p.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

The funcgraph format requires entry and exit records for the same
function to have matching depth values. Currently, exit records have
their depth written before decrementing, causing trace-cmd to display
incorrect or missing function exits.

Move the depth decrement and stack handling to before writing the exit
record. This ensures entry at depth N writes depth=N, and exit for the
same function also writes depth=N.

Fixes: b54d8cf0b5b8 ("trace: Support output of funcgraph records")
Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 tools/proftool.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)
  

Patch

diff --git a/tools/proftool.c b/tools/proftool.c
index c7b427f3078..1f7df6d1973 100644
--- a/tools/proftool.c
+++ b/tools/proftool.c
@@ -1435,6 +1435,21 @@  static int write_pages(struct twriter *tw, enum out_format_t out_format,
 			tw->ptr += tputq(fout,
 					 text_offset + caller_func->offset);
 		} else {
+			ulong func_duration = 0;
+
+			/*
+			 * For funcgraph, entry and exit of a function must
+			 * have the same depth. Decrement before writing the
+			 * exit record.
+			 */
+			if (!entry) {
+				depth--;
+				if (stack_ptr && stack_ptr <= MAX_STACK_DEPTH) {
+					ulong start = func_stack[--stack_ptr];
+
+					func_duration = timestamp - start;
+				}
+			}
 			tw->ptr += tputl(fout, rec_words | delta << 5);
 			tw->ptr += tputh(fout, entry ? TRACE_GRAPH_ENT
 						: TRACE_GRAPH_RET);
@@ -1449,14 +1464,6 @@  static int write_pages(struct twriter *tw, enum out_format_t out_format,
 					func_stack[stack_ptr] = timestamp;
 				stack_ptr++;
 			} else {
-				ulong func_duration = 0;
-
-				depth--;
-				if (stack_ptr && stack_ptr <= MAX_STACK_DEPTH) {
-					ulong start = func_stack[--stack_ptr];
-
-					func_duration = timestamp - start;
-				}
 				tw->ptr += tputl(fout, 0);	/* overrun */
 				tw->ptr += tputq(fout, 0);	/* calltime */
 				/* rettime (nanoseconds) */