具有运行时错误的业力生成器的调试技术是什么
What debugging technique for a karma generator with runtime error
容易解决我的编程问题是什么,因为我真的看不出问题出在哪里。事实上,我在提升精神业力库中的某个地方丢失了一个运行时错误。我想我在这里错过了调试技术。
我已经看到宏BOOST_SPIRIT_DEBUG_NODE(S)对解析器有很大帮助,尽管我在手册中找不到任何对它的引用。对于生成器,这似乎不起作用,我(老实说)没有勇气(我应该吗?)深入研究这个库的代码以了解问题所在。
我试图在语法中单独生成三种类型的联合状结构,没有任何问题。所以我假设错误来自将 U 结构转换为提升变体,再次(请参阅将属性转换为 boost::variant),但我没有证据。
对于那些可以通过简单的代码检查来解决它的人,这是我问题的最小示例:
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
//#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/karma.hpp>
#include <boost/variant/variant.hpp>
namespace ka = boost::spirit::karma;
typedef std::back_insert_iterator<std::string> iterator;
typedef enum {A, B, C } E;
typedef enum {FOO, BAR, POINTER } K;
struct U /* Union like */
{
K kind;
double foo;
E bar;
unsigned int * p;
};
class EName : public ka::symbols<E, std::string>
{
public:
EName()
{
add (A,"A") (B,"B") (C,"C");
}
};
typedef boost::variant<E, double, unsigned int *> UVariant;
namespace boost { namespace spirit { namespace traits {
template<>
struct transform_attribute<const U,UVariant,ka::domain>
{
typedef UVariant type;
static type pre(const U & u) {
switch (u.kind)
{
case FOO:
return type(u.foo);
case BAR:
return type(u.bar);
case POINTER:
return type(u.p);
}
return type(A);
}
};
}}}
class grm: public ka::grammar<iterator, U()>
{
public:
grm():grm::base_type(start)
{
start = ka::attr_cast<UVariant >(bar | foo | pointer);
bar = b;
foo = ka::double_;
pointer = ka::hex;
}
private:
ka::rule<iterator,U()> start;
ka::rule<iterator,double()> foo;
ka::rule<iterator,E()> bar;
ka::rule<iterator,unsigned int *()> pointer;
EName b;
};
int main(int argc, char * argv[])
{
grm g;
U u;
//unsigned int a;
u.kind = BAR;
//u.foo = 1.0;
u.bar = B;
//u.p = &a;
std::string generated;
std::back_insert_iterator<std::string> sink(generated);
ka::generate(sink,g,u);
std::cout << generated;
return 0;
}
更新:编译器:Visual C++ Express 版本 11 和 12。调用堆栈在 :
// If you are seeing a compilation error here stating that the
// third parameter can't be converted to a karma::reference
// then you are probably trying to use a rule or a grammar with
// an incompatible delimiter type.
if (f(sink, context, delim)) // <--- call stack stops here (last boost spirit reference)
我还发现_SCL_SECURE_NO_WARNINGS宏的定义掩盖了以下编译器警告:
警告 C4996:"std::_Copy_impl":使用参数调用 可能不安全 - 此调用依赖于调用方来检查 传递的值是正确的。要禁用此警告,请使用 -D_SCL_SECURE_NO_WARNINGS。请参阅有关如何使用可视化C++"已检查迭代器"的文档
此警告指的是几个增强精神文件:
- 精神\家\业力\细节\output_iterator.hpp(242)
精神\家\业力\细节\output_iterator.hpp(577)
精神\家\业力\细节\output_iterator.hpp(574)
精神\家\业力\细节\alternative_function.hpp(170)
精神\家\业力\细节\alternative_function.hpp(162)
精神\家\业力\操作员\替代.hpp(122)
精神\家\业力\辅助\attr_cast.hpp(85)
精神\家\业力\非终端\细节\generator_binder.hpp(43)
精神\家\业力\非终端\细节\generator_binder.hpp(52)
精神\家\业力\非终端\规则.hpp(193)
精神\家\业力\非终端\规则.hpp(230)
我无法重现错误。
我也无法通过一点代码检查来"解决它"。但是,我可以做两件事:
-
我可以确认调试宏似乎没有为 Karma 实现
-
我可以冒昧地说,也许
bar|foo|pointer
需要深度复制:start = ka::attr_cast<UVariant >(boost::proto::deep_copy(bar | foo | pointer));
我尝试启用 UB 消毒剂和地址消毒器,但它们都没有报告任何问题。
更新 事实上,看起来我可以通过一点代码检查(和幸运的脑电波)来"解决"它:
事实上,在valgrind 下运行确实显示出一个问题,事实上,在添加deep_copy
时它会消失。
我将添加一些关于我如何假设这些事情的参考资料:
一般:在(原型)表达式模板中悬空引用临时的问题
- 将解析器分配给自动变量
特别是几年前在
qi::attr_cast<>
中看到的问题:- 2014 年 1 月的这条评论:语法树空节点问题与 Spirit Qi MiniC 示例
- 当回溯以零开始时,如何调试崩溃
- 在linux上调试巨大的C++项目
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 正在VS调试器中监视映射条目
- 使用调试/崩溃报告将应用程序部署到客户端
- VC++本机单元测试,找不到调试符号
- 如何在C++生成器中禁用"使用调试.dcus"
- 使用vscode调试时,GDB意外退出
- 即使使用调试编译标志,表达式也是"optimized out"
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 调试 CUDA MMU 故障
- 小字符串优化(调试与发布模式)
- 反调试器技术:如何使用 VB.NET 对调试器隐藏线程?
- 如何在程序崩溃后释放managedsharedmemory:在调试过程中使用哪些有效的技术
- 调试"multiple definition of ..."错误的一般技术?
- 没有调试工具的调试技术
- Visual Studio 2013中的c++调试技术
- 未捕获的异常调试技术(C++)
- 具有运行时错误的业力生成器的调试技术是什么