获取“free():无效指针”配备定制 TCL 口译员
我有一个定制的 TCL 口译员。如下:
// file main.cpp
#include <tcl.h>
#include <string>
int argc = 0;
char** argv = 0;
int
Tcl_AppInit( Tcl_Interp* interp )
{
if ( Tcl_Init( interp ) == TCL_ERROR ) {
return TCL_ERROR;
}
for ( int i = 1; i < argc; ++i ) {
if ( Tcl_Eval( interp, ("source " + std::string( argv[i] )).c_str() ) == TCL_ERROR ) {
return TCL_ERROR;
}
}
return TCL_OK;
}
int
main( int argc, char** argv )
{
::argc = argc;
::argv = argv;
Tcl_Main( 1, argv, &Tcl_AppInit );
return 0;
}
我使用以下命令构建 main.cpp
:
g++ -DNDEBUG -O3 -fpic -Wall -pedantic -fno-strict-aliasing \
-Wl,-R/usr/local/lib -L/usr/local/lib -ltcl main.cpp -o myinterp
有时 myinterp
会崩溃,并显示如下错误消息:
free(): invalid pointer: 0x00002b04078aa000 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3723c722ef]
/lib64/libc.so.6(cfree+0x4b)[0x3723c7273b]
/lib64/libc.so.6(_IO_free_backup_area+0x18)[0x3723c6e1d8]
/lib64/libc.so.6(_IO_file_overflow+0x1d2)[0x3723c6c1d2]
/lib64/libc.so.6(_IO_file_xsputn+0xf2)[0x3723c6ce22]
/lib64/libc.so.6(_IO_vfprintf+0x1b0)[0x3723c428a0]
/lib64/libc.so.6(_IO_fprintf+0x88)[0x3723c4d358]
main.cpp
有问题吗?代码>?什么可能导致这次崩溃?
I have a custom TCL interpreter. Here it is:
// file main.cpp
#include <tcl.h>
#include <string>
int argc = 0;
char** argv = 0;
int
Tcl_AppInit( Tcl_Interp* interp )
{
if ( Tcl_Init( interp ) == TCL_ERROR ) {
return TCL_ERROR;
}
for ( int i = 1; i < argc; ++i ) {
if ( Tcl_Eval( interp, ("source " + std::string( argv[i] )).c_str() ) == TCL_ERROR ) {
return TCL_ERROR;
}
}
return TCL_OK;
}
int
main( int argc, char** argv )
{
::argc = argc;
::argv = argv;
Tcl_Main( 1, argv, &Tcl_AppInit );
return 0;
}
I build main.cpp
with the following command:
g++ -DNDEBUG -O3 -fpic -Wall -pedantic -fno-strict-aliasing \
-Wl,-R/usr/local/lib -L/usr/local/lib -ltcl main.cpp -o myinterp
Sometimes myinterp
crushes with an error message like this:
free(): invalid pointer: 0x00002b04078aa000 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3723c722ef]
/lib64/libc.so.6(cfree+0x4b)[0x3723c7273b]
/lib64/libc.so.6(_IO_free_backup_area+0x18)[0x3723c6e1d8]
/lib64/libc.so.6(_IO_file_overflow+0x1d2)[0x3723c6c1d2]
/lib64/libc.so.6(_IO_file_xsputn+0xf2)[0x3723c6ce22]
/lib64/libc.so.6(_IO_vfprintf+0x1b0)[0x3723c428a0]
/lib64/libc.so.6(_IO_fprintf+0x88)[0x3723c4d358]
Is something wrong with main.cpp
? What could cause this crash?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您最好像这样编写代码:
这样, std::string 中缓冲区的生命周期将是正确的,这就是我的直觉表明的可能是您真正的问题。 (一旦内存损坏,崩溃几乎可能在任何地方出现。)但是,您还应该意识到,如果您在任何这些文件名中包含空格,这仍然会完全错误。也许这对你来说没问题(例如,如果都是带有“好”名称的本地文件名),但否则使用 Tcl 的
Tcl_EvalObjv
来执行执行,如下所示(有点长;它实际上是 C,而不是 C++):You might be better off writing the code like this:
Like that, the lifetime of the buffer in the
std::string
will be correct, which is what my intuition indicates is probably your real problem. (Once there's corrupted memory about, the crash can crop up nearly anywhere.) However, you should also be aware that this will still go thoroughly wrong if you've got spaces in any of those filenames. Maybe that's OK for you (e.g., if it's all local filenames with “nice” names) but otherwise use Tcl'sTcl_EvalObjv
to do the execution, like this (which is a bit longer; it's really C, not C++):我相信Tcl_Main应该是这样的:
没有addressof &操作员。请参阅此处查看示例。我认为您在 argv 的大小问题上向 Tcl_Main 撒谎,以绕过参数的自动处理?
编辑:就其价值而言,我没有看到代码有任何明显的错误,但考虑到我对运算符地址的心理偏差,我的意见可能没有多大价值。您能否将脚本输入到标准 tclsh 解释器中而不会出现任何问题?他们是否加载任何其他扩展或库?
I believe that Tcl_Main should be like this:
without the addressof & operator. See here here for an example. I take it you are fibbing to Tcl_Main about the size of argv in order to bypass the automatic processing of arguments?
Edit: For what its worth, I don't see anything obviously wrong with the code, but then given my mental aberration over the address of operator my opinion might not be worth much. Can you source the scripts into a standard tclsh interpreter without any problems? Do they load any other extensions or libraries?