【问题标题】:App crash when compiled with TCL_MEM_DEBUG使用 TCL_MEM_DEBUG 编译时应用程序崩溃
【发布时间】:2019-11-01 11:18:13
【问题描述】:

在 TCL 8.6.9 上,我尝试使用 TCL_MEM_DEBUG 来帮助诊断我的应用程序中的内存泄漏,但是在使用/启用它时我遇到了崩溃。

相同的代码在没有它的情况下编译 TCL 时运行良好,但在我使用标志时崩溃。

TCL调用函数“Tcl_ResetResult->ResetObjResult->Tcl_IsShared(Tcl_DbIsShared in debug)”时代码崩溃。

在执行“Tcl_Eval()”时发生。

(这是一个多线程的应用程序(解释器))。

谢谢

更多信息: 这发生在在 DLL 中创建的线程中。因此,当从 TCL 加载 DLL 时,我们在这里执行的操作是创建一个新的 TCL 解释器(Tcl_CreateInterp),然后创建一个使用该解释器的新线程。 其他线程(使用自己的解释器)将命令发送到执行它们的线程。这是发生此崩溃的时间。

【问题讨论】:

  • 在内存调试模式下,实现检查是否遵循线程局部性规则(除其他外)。是否有与崩溃相关的错误消息(即是有序的恐慌还是无序的彻底崩溃)?
  • 您好,Donal,我不确定您的问题(恐慌或彻底)。但它确实以“恐慌”告终,说“未创建表对象”。没有把握。我现在不在工作,但明天早上我会得到确切的错误。
  • 确切的行是 "Tcl_Panic("object table not initialized");"在函数“Tcl_DbIsShared()”中。
  • 这里有一些解决方案/提示的希望吗?谢谢

标签: windows tcl


【解决方案1】:

是的,如果线程当前调用 IsShared、IncrRefCount 或 DecrRefCount 等但还没有创建任何对象本身,这种情况确实会发生在使用 TCL_MEM_DEBUG 编译的 tcl 中。
实际上,对象表是在函数 TclDbInitNewObj 中的 TSD 中的每个线程创建的(如果第一个对象在线程中创建,则按需创建)...

所以我猜想在线程 Th1 中创建了一些 obj 并提供给线程 Th2,但线程 Th2 仍然没有创建任何对象。
通常它永远不会发生,因为解释器是在线程自身中创建的(并且在初始化阶段将创建几个对象)。只是你在上面写了:

我们创建一个新的 TCL 解释器 (Tcl_CreateInterp) 然后我们创建一个使用该解释器的新线程。

虽然我认为这根本不是一个好主意(线程存储过度工作等),但我认为这对我们来说可能有点出乎意料,如果可以的话,我们应该解决这个问题。

只要它仍未修复,解决方法只需在您应用中使用 tcl-objects 的每个线程中创建 1 个空对象,如下所示:

#ifdef TCL_MEM_DEBUG
if (1) { Tcl_Obj *objPtr = Tcl_NewObj(); Tcl_DecrRefCount(objPtr); };
#endif

更新:

我认为建议的解决方法没有帮助,因为您可能会再次恐慌
Trying to check shared status of Tcl_Obj allocated in another thread.
看起来 TCL_MEM_DEBUG 的当前实现从未考虑过跨线程处理 tcl 对象。

因此,目前该问题的“解决方案”是直接在目标线程中创建解释器。

【讨论】:

  • 不确定我是否收到您的最后一条评论,您的意思是“TCL_MEM_DEBUG”不能与多线程一起使用,还是您之前的建议会使它起作用?(因此,目前该问题的“解决方案”将是直接在目标线程中创建解释器)?谢谢
  • “TCL_MEM_DEBUG”的当前概念根本不允许在另一个线程中使用在一个线程中创建的 tcl 对象。这使得我之前建议的解决方法变得不可能(只需更改恐慌消息)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 2011-12-11
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 2020-01-16
相关资源
最近更新 更多