在Windows上调试tcl崩溃

时间:2014-08-28 06:33:55

标签: windows tkinter tcl tk pyinstaller

我有一个Tkinter应用程序,有时会在Windows下崩溃。该错误是一个通用的'程序已停止工作,需要关闭'。

检查事件日志后,我发现tcl85.dll是导致崩溃的库。

我的猜测是我的程序中有一个错误,它会滥用tcl api并导致tcl进入未定义状态,最终导致崩溃,或者tcl85本身存在错误。

我的问题是,如何诊断出这个问题的原因?哪些工具可以帮助获得类似程序错误的回溯?我已经检查了Windows事件日志中的错误,但是那里的信息似乎不足以确定原因。

以下是事件日志错误的xml:

 Name="Application Error"></Provider>
<EventID Qualifiers="0">1000</EventID>
<Level>2</Level>
<Task>100</Task>
<Keywords>0x0080000000000000</Keywords>
<TimeCreated SystemTime="2014-08-27 08:54:13"></TimeCreated>
<EventRecordID>6173</EventRecordID>
<Channel>Application</Channel>
<Computer>my.windows.8.tablet.computer</Computer>
<Security UserID=""></Security>
</System>
<EventData><Data><string>my_tkinter_app.exe</string>
<string>0.0.0.0</string>
<string>514e2c2f</string>
<string>tcl85.dll</string>
<string>8.5.2.15</string>
<string>53b1e888</string>
<string>c0000005</string>
<string>0007697f</string>
<string>1378</string>
<string>01cfc1d44828ecb0</string>
<string>C:\Users\ADMINI~1\DOWNLO~1\my_tkinter_app.exe</string>
<string>C:\Users\ADMINI~1\AppData\Local\Temp\_MEI35042\tcl85.dll</string>
<string>b7745a30-2dc7-11e4-9732-88124e8c7600</string>
<string></string>
<string></string>
</Data>
<Binary></Binary>
</EventData>
</Event>

c0000005我收集到存在访问冲突,但这仍然过于通用,无法确定原因。

不幸的是,我无法在Linux下重现崩溃,因此我正在寻找一种特定于Windows的方法来跟踪此问题。

3 个答案:

答案 0 :(得分:1)

如果你有一个涉及Tcl的PDB文件(例如,因为你是自己构建的),最简单的方法就是在进程崩溃时简单地指示windows安全地使用MiniDump。

Windows错误报告(WER)系统具有执行此操作所需的部分,您只需设置一些注册表项并找到生成的.dmp文件。

查看所需内容http://msdn.microsoft.com/en-us/library/windows/desktop/bb787181%28v=vs.85%29.aspx

一旦你有了崩溃转储,你只需用你选择的调试器(Visual Studio或Windbg)打开它并开始调试,将它指向你的PDB文件和微软符号服务器,并获得一个很好的崩溃堆栈跟踪。 / p>

答案 1 :(得分:1)

我在安装了Python 2.7.9的Windows 7桌面上出现了相同的错误,这在我的程序中是一个线程安全的问题。我不确定您的问题是否可以通过我的解决方案解决,只需分享即可。

对于在其他(主要)线程中运行tkinter的所有人,tkinter NOT THREAD SAFE 。在我的程序中,我必须在主线程中运行twisted reactor,所以我在另一个线程中运行tkinter UI。由于我在主线程中直接调用tkinter方法(如Text.insert()),因此偶尔会因c0000005错误而崩溃。

阅读this bug report后,我用:

修改了基于tkinter的UI模块
  1. 为特定小部件添加了命令队列(在我的情况下为文本小部件)
  2. 添加了after()queue.get_nowait()的处理程序方法,如下所示:

    def commandQueueHandler(self):
        try:
            while 1:
                your_command = self.textCommandQueue.get_nowait()
                if your_command is not None:
                    # execute the command ....
                self.Text.update_idletasks()
        except Queue.Empty:
            pass
        self.Text.after(100, self.commandQueueHandler)  
    

    此方法每100ms自触发一次以处理队列中的命令,但您必须触发 一次 才能使其正常工作。 (在初始化所有小部件之后,我在__init__中触发此内容。)

  3. 在主线程中,我所要做的只是将命令/消息放入命令队列并等待它被处理。当然,在命令执行之前会有一点延迟。

    那就是它!通过这个修改,我的程序在2周的压力测试后没有运行tcl c0000005错误。希望这会有所帮助。

    P.S。请注意,只有窗口小部件类提供after()方法,check this page for details

答案 2 :(得分:0)

关于Tkinter不是线程安全的这个建议是现货。 就我而言,我以下列方式解决了问题:

self.root.after(10, self.monitor) #sets up the queue monitor
self.root.update_idletasks() # adding this call resolved the issue for me