Skip to content

create a real call graph that can have cycles in --graphviz #1500

@honggyukim

Description

@honggyukim

uftrace graph actually doesn't show a call graph, but just a call tree output. For example, t-fibonacci example's output is as follows.

$ gcc -pg -o t-fibonacci tests/s-fibonacci.c

$ uftrace record t-fibonacci

$ uftrace graph
# Function Call Graph for 't-fibonacci' (session: 7701e718f823010e)
========== FUNCTION CALL GRAPH ==========
# TOTAL TIME   FUNCTION
   20.354 us : (1) t-fibonacci
    2.199 us :  +-(1) __monstartup
             :  |
    1.129 us :  +-(1) __cxa_atexit
             :  |
   17.026 us :  +-(1) main
   16.499 us :    (1) fib
   15.859 us :    (2) fib
   14.887 us :    (4) fib
   12.782 us :    (8) fib
    8.362 us :    (14) fib
    2.976 us :    (10) fib
    0.390 us :    (2) fib

As the output shows there are multiple nodes for fib function. It's because there are multiple backtrace or call paths of each fib node.

The --graphviz output also uses the same logic when building a graph, precisely a tree. So its output doesn't show the multiple nodes for the same function, but it draws multiple edges for the same calls.

The --graphviz output of t-fibonacci is as follows.

$ gcc -pg -o t-fibonacci tests/s-fibonacci.c
$ uftrace record t-fibonacci
$ uftrace dump --graphviz
      ...
digraph G {
    "t-fibonacci"
    "t-fibonacci" -> "__monstartup" [xlabel = "1"]
    "t-fibonacci" -> "__cxa_atexit" [xlabel = "1"]
    "t-fibonacci" -> "main" [xlabel = "1"]
    "main" -> "fib" [xlabel = "1"]
    "fib" -> "fib" [xlabel = "2"]
    "fib" -> "fib" [xlabel = "4"]
    "fib" -> "fib" [xlabel = "8"]
    "fib" -> "fib" [xlabel = "14"]
    "fib" -> "fib" [xlabel = "10"]
    "fib" -> "fib" [xlabel = "2"]
}

Its image shows too many edges from fib to fib as follows.
image

But it would be much better to make it as follows.

digraph G {
    "t-fibonacci"
    "t-fibonacci" -> "__monstartup" [xlabel = "1"]
    "t-fibonacci" -> "__cxa_atexit" [xlabel = "1"]
    "t-fibonacci" -> "main" [xlabel = "1"]
    "main" -> "fib" [xlabel = "1"]
    "fib" -> "fib" [xlabel = "40"]
}

This modified dot produces much clear image as follows.
image

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions