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

芬利

有一个atcv::MatOpenCV的命名的模板成员函数

//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
}

我想打印表达式的值:

eyePts_left.at<float>(0,0)

在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)
               ~~~~~^

那么,检查此模板相关表达式的值的正确方法是什么?

吉姆·英厄姆(Jim Ingham)

模板功能和模板化实体的当前调试信息通常很尴尬,因为它仅描述实例化,而不将模板描述为抽象实体,因此模板化功能仅在调试信息中显示,就像名称中带有尖括号的功能一样。这使得从调试信息转到lldb可以将其馈送到其clang副本的编译器表示形式变得很棘手,以便clang可以在表达式中正确解析它们。正如您所发现的那样,目前不起作用。

但是,如果确实需要执行此操作,则可以进行一些创造性的转换来解决此问题,例如:

查找功能地址,例如

(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

手动将呼叫投射到该地址:

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

这不是您的真正功能,只是我制作的一个玩具,所以不要关注实际结果。

注意,如果您经常这样做,并且不100%喜欢C函数转换语法,则可以在代码或lldb中为它创建一个typedef,例如:

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

这简化了呼叫:

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

然后,如果您最终做了很多,甚至可以这样做:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章