qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: introducing vrc :)


From: Stefan Hajnoczi
Subject: Re: introducing vrc :)
Date: Wed, 20 Apr 2022 16:06:47 +0200

On Tue, Apr 19, 2022 at 04:39:13PM +0200, Paolo Bonzini wrote:
> Hi all,
> 
> a while ago I looked at tools that could be used too build a call graph.
> The simplest but most effective that I found was a small Perl program
> (called "egypt", which is rot13 for "rtlcg" aka RTL call graph) that used
> the GCC dumps to build the graph.
> 
> I have now rewritten it in Python and extended it with a lot of new
> functionality:
> 
> - consult compile_commands.json to find/build dumps automatically
> 
> - virtual (manually created) nodes and edges
> 
> - query call graph in addition to generating DOT file
> 
> - interactive mode with readline + completion
> 
> The name is unfortunately not rot13 anymore, it stands for visit RTL
> callgraph.
> 
> Here is an example (run vrc from the root build directory of QEMU):
> 
>       # load files
>       load libblock.fa.p/*.c.o
> 
>       # introduce virtual edges corresponding to function pointers
>       node BlockDriverState.bdrv_co_flush
>       edge bdrv_co_flush BlockDriverState.bdrv_co_flush
>       edge BlockDriverState.bdrv_co_flush blk_log_writes_co_do_file_flush
>       edge BlockDriverState.bdrv_co_flush preallocate_co_flush
>       edge BlockDriverState.bdrv_co_flush raw_co_invalidate_cache
>       edge BlockDriverState.bdrv_co_flush cbw_co_flush
>       edge BlockDriverState.bdrv_co_flush quorum_co_flush
>       edge BlockDriverState.bdrv_co_flush throttle_co_flush
>       edge BlockDriverState.bdrv_co_flush blkdebug_co_flush
>       edge BlockDriverState.bdrv_co_flush blkverify_co_flush
>       edge BlockDriverState.bdrv_co_flush bdrv_mirror_top_flush
>       # apply filter
>       only --callees bdrv_co_flush
>       # draw graph
>       dotty --files
> 
> The filtering functionality is a bit rough in the presence of mutual
> recursion, but hopefully this can be already useful to find the root calls
> of bdrv_*, which are the places where the graph lock has to be taken for
> read.  Continuing the previous example:
> 
>       # apply another filter
>       reset
>       omit --callees bdrv_co_flush
>       keep bdrv_co_flush
>       # example of query
>       callers bdrv_co_flush
> 
> already gives a reasonable answer (not entirely correct, but the actual
> analysis must be done on all callbacks at once):
> 
>       qed_co_request -> bdrv_co_flush
>       qed_need_check_timer_entry -> bdrv_co_flush
>       blk_log_writes_co_log -> bdrv_co_flush
>       bdrv_co_flush_entry -> bdrv_co_flush
>       bdrv_co_flush -> bdrv_co_flush
>       blk_co_do_flush -> bdrv_co_flush
>       bdrv_driver_pwritev -> bdrv_co_flush
>       blk_co_flush -> bdrv_co_flush
>       bdrv_flush -> bdrv_co_flush
>       bdrv_co_do_pwrite_zeroes -> bdrv_co_flush
>       blk_aio_flush_entry -> bdrv_co_flush

Cool, thanks for sharing. I will keep this in mind when I need to
analyze call graphs.

Stefan

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]