将tcl连接到C ++并调用虚方法的段错误

时间:2016-08-11 16:22:50

标签: c++ tcl

我看到一些我无法在传统C ++应用程序中解释的行为,其中通过桥接器在TCL中实现了通信接口。我对TCL了解不多,我不知道这是否与问题有关。

我有一个回调方法,它接受一个TCL ClientData对象,一个TCL解释器和一个标准的argc / argv对。 ClientData可以强制转换为指向我的应用程序TclOb中定义的类型的指针。 TclOb是一个虚拟基类,但没有一个子类覆盖我想要调用的虚方法。

int TclCallBack(ClientData clientdata, Tcl_Interp* interp, int argc, const char** argv)
{
    // ok - pointer is good
    TclOb* ob = static_cast<TclOb*>(clientdata);
    int result;

    // ok - runs method fine
    result = ob->nonvirtualMethod();

    // segfault
    result = ob->virtualmethod();
    ::debug("we never get here");
    return result;
}

TclOb类是相当复杂的虚拟基类,但最小的示例可能如下所示:

class TclOb {
public:
    TclOb() {}
    virtual ~TclOb() {}

    int nonvirtualMethod() {
        ::debug("got into the non-virtual method");
        return 1;
    }

    virtual int virtualMethod() {
        ::debug("we never get into the virtual method");
        return 1; 
    }
};

据我所知,当我们从构建中删除-m32编译器标志并改进了应用程序的无关部分的可移植性时,崩溃就开始发生了。我们在构建系统上进行手术时发现了这个问题,因此很难回过头来找出它发生了什么变化以及究竟是什么原因。

之前有没有遇到过这个?我很难理解它。

更新:我无法使用调试器或Valgrind,因为此应用程序仅通过TCL脚本启动并进行通信,因此插入它并获取任何内容都非常棘手有用的数据。

1 个答案:

答案 0 :(得分:0)

我最终走到了最底层。

事实证明,我曾尝试使用RAII 修复内存泄漏,其中现有代码在将其传递给TCL解释器之前新建了指向某个对象的指针。在此之后,TCL管理内存的生命周期,因此使用RAII进行清理会导致解释器取消引用释放的指针,从而导致分段错误。

解决方案是恢复更改,并向指针记录指针,向任何未来的开发人员发出关于尝试修复非问题所浪费的小时数的严厉警告。