Finding types of TVM objects and accessing their attributes in GDB

Hi all,

Just a generic question about debugging in GDB. Is there a good way to find the proper type of an "object" in GDB?

What I mean by that is, say there is an AddNode passed to a function as a PrimExpr and while debugging this function, is there way to find that it actually belongs to an AddNode. Trying whatis object or ptype object just prints that it’s a PrimExpr.

I found a rather hacky way to do this by printing

the object.deleter_ if it’s a subclass of tvm::runtime::Object, and

object.get().deleter_ if it’s a subclass of tvm::runtime::ObjectRef

This prints the type of the Deleter_ for that object and the template argument to the Handler contains the proper type (a sample output for AddNode is as shown below:)

$65 = (tvm::runtime::Object::FDeleter) 0x7fffaf6c9300 <tvm::runtime::SimpleObjAllocator::Handler<tvm::tir::AddNode>::Deleter_(tvm::runtime::Object*)>

I was just wondering whether there’s a stable/reliable way to get this info.

1 Like

I use the same way, and when I need inspect more details of the class object, I will use p PrettyPrint(xxx).c_str(), in addition if I want a more clear display(do the real line break instead of just print it as “\n”), the gdb command call (size_t)puts(PrettyPrint(xxx).c_str()) will be used.

for the last command, it is better to set the standard output of the process to another terminal.

1 Like

Thanks for the reply, atleast I’m not the only one who is using the deleter_ hack to find the types of nodes.

And thanks for the ideas with PrettyPrint, I haven’t used it too much in gdb, I normally use the p tvm::Dump(xxx) for printing Objects and ObjectRefs.

So, out of curiosity, is there a difference between what’s printed by tvm::Dump vs what’s printed by call (size_t)puts(PrettyPrint(xxx).c_str()). I tried it on a couple of simple examples and did not see any major differences.

I haven’t used tvm::Dump(xxx), I use call (size_t)puts(PrettyPrint(xxx).c_str()) when the xxx is a large node, e.g., the whole of PrimFunc, you can try with these large node.

Right, I think tvm::Dump(xxx) also supports printing entire PrimFunc. The main question I had was, is there a clean way to find the underlying type of an Object/ObjectRef. Basically, if I have a PrimFunc is there a way to find that the underlying type is say an AddNode.

I am using GetTypeKey() function to query the type information in a gdb session. It seems to be able to print a string representation of the underlying type of an Object/ObjectRef.

relay_module->GetTypeKey()
"IRModule"
2 Likes

Thanks for the info. Yes, I did realize that we can use GetTypeKey() sometime after I had created this initial thread. I thought of using that in my extension, but I realized that GetTypeKey() returns the type as a string that matches the python types mostly, and to be able to recursively access attributes of Stmts or Exprs it was good to get the exact type of the class in c++, which we did get from the deleter_ node, so I decided not to make any changes.

For example, if we have a StmtNode which is actually a BufferStoreNode, the _type_key assigned is tir.BufferStore, whereas the deleter would give us tvm::tir::BufferStoreNode. The second version turns out to be more useful to recursively access the attributes of the BufferStoreNode like buffer, value and indices (In the extension I access value attribute as tvat stmt.value).