Call Trees

If you write your queries over multiple functions that call each other, VyPR’s analysis library can be used to construct a call tree based on the top-level transaction. For example, if you’re monitoring a web service, then there will be a transaction for each HTTP request and, from there, you will be able to reconstruct the call tree(s) associated with that HTTP request.

class VyPRAnalysis.interprocedural.CallTree(transaction)

A tree derived of the calls that took place during a transaction/http request.

get_direct_callees(call)

Given a call, find its vertex and then return its children.

get_reachable(call)

Given a call, perform stack-based traversal to find all reachable calls in the tree.

write_to_file(file_name)

Write this call tree to a dot file.

Here’s an example of how you could use Call Trees. First, import everything you need and establish a connection

import VyPRAnalysis as va
import VyPRAnalysis.interprocedural.CallTree as CallTree
va.set_server("http://localhost:8080/")

Then, choose a function and gets a list of its calls

particular_function = va.list_functions()[0]
calls = particular_function.get_calls()

Finally, loop through the calls and, for each one, instantiate the call tree of that call’s transaction

for call in calls:
    transaction = va.transaction(call.trans)
    call_tree = CallTree(transaction)

Call trees then work based on individual function calls. For example, if you have a variable call that contains a call to a function that you know is in a call tree, you can explore the call tree with

callees = call_tree.get_direct_callees(call)

And if you don’t already know about any calls but want to find all callees (either indirect or direct), you can use

callees = call_tree.get_reachable()