在windows上调试tcl崩溃

在windows上调试tcl崩溃,windows,tkinter,tcl,tk,pyinstaller,Windows,Tkinter,Tcl,Tk,Pyinstaller,我有一个Tkinter应用程序,有时会在Windows下崩溃。该错误是一个通用的“程序已停止工作,需要关闭” 检查事件日志后,我发现tcl85.dll是导致崩溃的库 我的猜测是,我的程序中有一个错误,它误用了tcl api并导致tcl进入未定义状态,最终导致崩溃,或者tcl85本身有一个错误 我的问题是,如何诊断此问题的原因?哪些工具有助于对程序出错的地方进行回溯?我已经检查了windows事件日志中的错误,但其中的信息似乎不足以确定原因 以下是事件日志错误的xml: Name="Applic

我有一个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>
Name=“应用程序错误”>
1000
2.
100
0x0080000000000000
6173
应用
my.windows.8.tablet.computer
my_tkinter_app.exe
0.0.0.0
514e2c2f
tcl85.dll
8.5.2.15
53b1e888
c0000005
0007697f
1378
01cfc1d44828ecb0
C:\Users\ADMINI~1\DOWNLO~1\my\u tkinter\u app.exe
C:\Users\ADMINI~1\AppData\Local\Temp\\u MEI35042\tcl85.dll
b7745a30-2dc7-11e4-9732-88124e8c7600
c0000005
中,我发现存在访问冲突,但这仍然太笼统,无法确定原因


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

如果您有一个涉及Tcl的PDB文件(例如,因为您自己构建了它),最简单的方法就是在进程崩溃时简单地指示windows保护一个小型转储

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

查看所需的内容:


一旦你有了崩溃转储,你只需用你选择的调试器(Visual Studio或Windbg)打开它并开始调试,将它指向你的PDB文件和Microsofts Symbol服务器,并获得崩溃的良好堆栈跟踪。

我在安装了Python 2.7.9的Windows 7桌面上遇到了相同的错误,这在我的程序中是一个线程安全问题。我不确定我的解决方案是否能解决您的问题,请分享

对于所有在非主线程中运行tkinter的人来说,tkinter不是线程安全的。在我的程序中,我必须在主线程中运行Twistedreactor,所以我在另一个线程中运行TkinterUI。因为我在主线程中直接调用了tkinter方法(比如
Text.insert()
),所以它偶尔会因c0000005错误而崩溃

阅读后,我使用以下内容修改了基于tkinter的UI模块:

  • 将命令队列添加到特定的小部件(在我的例子中是文本小部件)
  • 添加了一个带有
    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自触发一次,以处理队列中的命令,但您必须触发一次才能使其工作。(在所有小部件初始化后,我在
    \uuuuu init\uuuuuuu
    中触发此操作。)

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

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


    p、 注意,只有小部件类提供
    after()
    方法。

    关于Tkinter不是线程安全的建议是正确的。 就我而言,我通过以下方式解决了问题:

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

    我想这很难说。是你自己包装的应用程序吗?可能包装的库不适合windows;例如,我尝试使用Tclkit创建exe,不同的操作系统使用不同的文件;还有一个starpack,我认为它能够在linux和Win操作系统上工作。我只是说可能有点类似,更可能是API误用,但不能保证。访问冲突可能是空的取消引用。@JasonMArcher,非常感谢!虽然我的具体问题(及其最终解决方案)与此不同,但您通过有关线程安全和tkinter的信息使我走上了正确的轨道。(基本上,我有一个可靠的工作程序——一个非常类似的程序,几乎每次都会崩溃——我看不出它们之间有什么实质性的区别来识别问题。根据你答案中的线索,我找到了它:后一个程序在一个单独的线程中执行一些额外的不必要的tkinter杂技。一旦我简化了在我们看来,它工作得非常好。)