正在尝试减少在另一个线程中分配的Tcl_Obj的引用计数

正在尝试减少在另一个线程中分配的Tcl_Obj的引用计数,tcl,Tcl,我编译了sourceforge tcl可执行文件,它通过了提供的所有测试,并且使用我在下载的可执行文件8.6.9中看到的相同segfault运行。我在AMD处理器上运行Ubuntu 16.04(出于传统原因)。(我在笔记本电脑上运行过ubuntu 18.04,它也有同样的故障。) 因此,接下来我在启用“-enable symbols=mem”的情况下重新编译,以查看是否是内存泄漏导致segfault,现在它会立即失败,原因是: Trying to decr ref count of Tcl_Ob

我编译了sourceforge tcl可执行文件,它通过了提供的所有测试,并且使用我在下载的可执行文件8.6.9中看到的相同segfault运行。我在AMD处理器上运行Ubuntu 16.04(出于传统原因)。(我在笔记本电脑上运行过ubuntu 18.04,它也有同样的故障。)

因此,接下来我在启用“-enable symbols=mem”的情况下重新编译,以查看是否是内存泄漏导致segfault,现在它会立即失败,原因是:

Trying to decr ref count of Tcl_Obj allocated in another thread
./runMeg.sh: line 3: 29972 Aborted (core dumped) ../source/main_megatron.
我看不到任何关于如何处理此响应的答案,有人能建议我需要解决的问题吗

我的所有线程的形式如下:

set graphDisplayThread [ thread::create {
  after [expr {int(1000) }]
  .....
  puts "...Initialized graphDisplayUpdate_02 ID $c update."
  thread::wait
  }]
以及:


所有共享变量都是在捕获互斥后通过TSV变量引用的。应用程序中有5个线程,其中根本没有C代码。总共大约2000行代码

该应用程序运行数千个周期,然后使用先前的ActiveState 8.6.9预编译版本在随机点进行故障隔离。因此,作为第一步,现在我尝试使用编译的SourceForge 8.6.9内存检查来隔离故障点,但上面的问题是我遇到的第一个问题,它在启动后立即发生

更新(美国东部时间5/16/19 8:28):回答以下评论的新细节。。。。这个应用程序中没有C代码,Tcl_Obj错误只出现在基于sourceForge的8.6.9编译版本中(2)我自己编写的,而不是ActiveState 8.6.9预编译的下载版本中。sourceForge代码中的错误发生在我串联并测试的两个“MEM_DEBUG”和NO“MEM_DEBUG”构建中。两者都通过了所有安装测试

总结如下:

sourceForge 8.6.9 compile w/MEM_DEBUG option:   Tcl_Obj Abort error 
sourceForge 8.6.9 compile w/o MEM_DEBUG option: Tcl_Obj Abort error
ActiveState 8.6.9 build:                    does not Abort, random seg fault   
为什么我应该相信我自己制作的sourceForge构建,而不是不存在问题的ActiveState预构建的可执行文件?如果我们确实信任sourceForge编译版本,我如何隔离TCL对象错误是由有问题的TCL代码创建的


更新5/16/19@13:34EST:Ubuntu 18.04上的ActiveState 8.6.9也会出现相同的错误。我还没有检查我的SourceForge版本,看看它们是如何运行的

通过有条不紊地破解代码块并观察Tcl_Obj错误是否出现,我发现了两个错误:

  • 我不止一次地重新声明了互斥和cond变量。现在它只声明一次,并在所有其他地方引用
  • 在我不再需要的地方发现了删除TSV的代码残留
这也修复了segfault


谢谢你的帮助和提示,卡尔文先生

通过有条不紊地破解代码块并观察Tcl_Obj错误是否出现,我发现了两个错误:

  • 我不止一次地重新声明了互斥和cond变量。现在它只声明一次,并在所有其他地方引用
  • 在我不再需要的地方发现了删除TSV的代码残留
这也修复了segfault


谢谢你的帮助和提示,卡尔文先生

您必须显示C代码,调试语句“[…]Tcl_Obj allocated in other thread”显示您的C代码试图在一个线程(interp)中处理(递减)由另一个(thread)interp创建的Tcl_Obj。“捕获互斥后,通过TSV变量引用所有共享变量。”。。。这听起来像是重复的努力,TSV在内部设置了互斥保护,所以在TSV调用时不需要它们。“导致SEGFULT的内存泄漏”。。。没有内存泄漏,在Tcl的线程和存储模型方面存在访问冲突。为此,
--enable symbols=mem
并不深刻,因为您的问题不是在Tcl_Obj的生命周期中平衡增量和减量,而是在线程之间不访问Tcl_Obj。第一条评论回复:卡尔文先生,我在这个应用程序中没有Ccode。如何“显示C代码”并将其连接到导致问题的适用TCL代码?感谢您提供的任何帮助我了解这一情况的指南。第二条评论回复:该应用程序有许多TSV列表,所有这些列表都必须在锁定步骤中准备好,因此互斥锁仅允许其他线程在所有3个数组都已完全填充后读取这三个数组。现在使用互斥来同步从多个阵列读取的数据听起来合适吗?您必须显示C代码,调试语句“[…]Tcl_Obj allocated in other thread”显示您的C代码试图在一个线程(interp)中处理(递减)由另一个(thread)interp创建的Tcl_Obj。“捕获互斥后,通过TSV变量引用所有共享变量。”…这听起来像是重复的工作,TSV在内部设置互斥保护,以便在TSV调用时不需要它们。”内存泄漏导致SEGV故障" ... 没有内存泄漏,在Tcl的线程和存储模型方面存在访问冲突。为此,
--enable symbols=mem
并不深刻,因为您的问题不是在Tcl_Obj的生命周期中平衡增量和减量,而是在线程之间不访问Tcl_Obj。第一条评论回复:卡尔文先生,我在这个应用程序中没有Ccode。如何“显示C代码”并将其连接到导致问题的适用TCL代码?感谢您提供的任何帮助我了解这一情况的指南。第二条评论回复:该应用程序有许多TSV列表,所有这些列表都必须在锁定步骤中准备好,因此互斥锁仅允许其他线程在所有3个数组都已完全填充后读取这三个数组。现在使用互斥来同步从多个阵列读取的数据听起来合适吗?毕竟,很高兴您的应用程序稳定了。但是,您是否有机会共享最小的、可验证的脚本,以便我们可以调查该问题?从脚本级别,通过扩展,一个人永远不可能在另一个线程中分配到
[…]Tcl_Obj
sourceForge 8.6.9 compile w/MEM_DEBUG option:   Tcl_Obj Abort error 
sourceForge 8.6.9 compile w/o MEM_DEBUG option: Tcl_Obj Abort error
ActiveState 8.6.9 build:                    does not Abort, random seg fault