简体   繁体   English

如何在gdb/lldb调试中打印模板成员函数返回的值

[英]how to print value returned by template member function in gdb/lldb debugging

There is a template member function named at in class cv::Mat of OpenCV: OpenCV 的cv::Mat类中有一个名为at的模板成员函数:

//definition of at 
template<typename _Tp> inline const _Tp& Mat::at(int i0, int i1) const{
  // ...
}

//my codes
cv::Mat eyePts_left;
// ...
if(std::max(eyePts_left.at<float>(0,0),eyePts_left.at<float>(16,0)) > eyePts_left.at<float>(61,0)){ 
  //do something
}

I want to print the value of the expression:我想打印表达式的值:

eyePts_left.at<float>(0,0)

in an lldb debugging session, but it complains:在 lldb 调试会话中,但它抱怨:

(lldb) p eyePts_left.at<float>(0, 0)
error: warning: warning: got name from symbols: at
error: <user expression 21>:1:13: no member named 'at' in 'cv::Mat'
eyePts_left.at<float>(0, 0)
~~~~~~~~~~~ ^
error: <user expression 21>:1:21: expected '(' for function-style cast or type construction
eyePts_left.at<float>(0, 0)
               ~~~~~^

So, what is the proper way to check the value of this template-related expression?那么,检查这个模板相关表达式的值的正确方法是什么?

The current debug information for template functions, and templated entities in general is awkward because it only describes instantiations, and not templates as abstract entities, so templated functions just show up in the debug info just as functions with angle brackets somewhere in the names.模板函数和模板化实体的当前调试信息通常很尴尬,因为它只描述实例化,而不是将模板描述为抽象实体,因此模板化函数只显示在调试信息中,就像名称中带有尖括号的函数一样。 That makes it tricky to go from the debug info to a compiler representation that lldb can feed into its copy of clang so that clang can parse them correctly in expressions.这使得从调试信息转到 lldb 可以将其输入其 clang 副本的编译器表示变得棘手,以便 clang 可以在表达式中正确解析它们。 As you have found, that doesn't work at present.正如您所发现的,目前这行不通。

If you really need to do this however, you can work around the problem with a little creative casting, for instance:但是,如果您确实需要这样做,您可以通过一些创造性的演员来解决这个问题,例如:

Find the function address, eg找到函数地址,例如

(lldb) image lookup -n Mat::at<float>
1 match found in /tmp/a.out:
        Address: a.out[0x0000000100003f30] (a.out.__TEXT.__text + 64)
        Summary: a.out`float const& Mat::at<float>(int, int) at template_fun.cpp:4

Cast the call to that address by hand:手动将调用投射到该地址:

(lldb) expr ((float &(*) (Mat *, int, int))0x0000000100003f30)(&my_mat, 10, 20)
Called with 10 20
(float) $0 = 30

This isn't your real function, just a toy I made so don't pay attention to the actual result.这不是你真正的功能,只是我做的一个玩具,所以不要关注实际结果。

Note, if you end up doing this often and don't 100% love C function casting syntax, you can make a typedef for it, either in the code or in lldb like:请注意,如果您最终经常这样做并且不是 100% 喜欢 C 函数转换语法,您可以为它制作一个 typedef,无论是在代码中还是在 lldb 中,如:

(lldb) expr typedef float &(*$Mat_at_type) (Mat *, int, int)

That simplifies the call:这简化了调用:

(lldb) expr (($Mat_at_type)0x0000000100003f30)(&my_mat, 10, 20)
Called with 10 20
(float) $1 = 30

And then if you end up doing this a whole lot, you could even do:然后,如果你最终这样做了很多,你甚至可以这样做:

(lldb) command alias call_at expr -- (($Mat_at_type)0x0000000100003f30)
(lldb) call_at (&my_mat, 10, 20)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM