【问题标题】:Writing an Iron Python debugger编写 Iron Python 调试器
【发布时间】:2011-01-30 09:59:09
【问题描述】:

作为学习练习,我正在使用 IronPython 为自己编写一个简单的扩展/插件/宏框架 - 我已经掌握了基础知识,但我想添加一些基本的调试支持,以使我的脚本编辑器更易于使用.

我一直在互联网上四处寻找,我发现了一些关于编写托管调试器的好资源(包括 Mike Stall 的出色 .Net Debugging blogCLR Debugging API 上的 MSDN 文档) - 我明白IronPython 本质上是 IL,但除此之外我对如何开始有点迷茫,特别是:

  • 调试动态语言(如 IronPython)与调试静态语言(如 C#)之间是否存在显着差异?
  • 是否需要以特殊方式执行我的脚本才能让 IronPython 输出合适的调试信息?
  • 调试在当前进程中运行的脚本会导致死锁,还是 IronPython 在子进程中执行我的脚本?
  • 我最好先研究一下如何生成一个简单的 C# 调试器以了解总体思路吗?

(我现在对制作调试器的 GUI 方面不感兴趣 - 我已经很好地了解了它的工作原理)

【问题讨论】:

标签: clr debugging ironpython


【解决方案1】:

在 AlterNET 软件 (www.alternetsoft.com) 我们已经为 C# 和 IronPython 实现了调试,我们发现 C# 调试的主要区别在于你不能真正将调试器和脚本调试为相同的一部分过程。我们尝试了这里描述的几种技术,但无法真正使其以可靠的方式工作。

https://docs.microsoft.com/en-us/archive/blogs/jmstall/you-cant-debug-yourself

因此,为了调试您的脚本,您要么需要使用独立的调试器,要么以这样的方式编写脚本,以便它们可以在单独的可执行文件中编译(但这意味着为了访问应用程序-定义对象,此类脚本将需要使用进程间通信技术与应用程序交互)。 您可以在此处找到更多信息: https://www.alternetsoft.com/news/known-issues-of-net-script-executing-and-debugging

从这个意义上说,IronPython 等动态语言更为宽松 - 您可以在自己的进程中实现调试。

虽然被调试的脚本需要在单独的线程中运行,所以如果它需要访问应用程序对象,这应该以线程安全的方式完成 - 比如通过使用 Invoke 对 UI 线程的同步调用。在调试期间实现自己的消息循环可能可以避免这种情况,但我们还没有尝试过(还)。

德米特里

【讨论】:

    【解决方案2】:

    我不是 IronPython 方面的专家,但我在使用 WinDbg 调试托管应用程序方面有一些经验。我简要了解了 IronPython 应用程序在调试器中的外观。由于 Python 的动态特性,在运行时会发出大量代码。这使得 IronPython 应用程序的调试比 C# 应用程序更复杂一些,因为可以说你有一个额外的代码生成层。

    曾经大量参与 Iron-languages 开发的 Harry Pierson 在writing an IronPython debugger 上发表了一系列博文,其中有很多细节。

    【讨论】:

    • 感谢您的链接 - 我正在阅读它,它看起来不错。
    【解决方案3】:

    更多链接已经开始使这一点变得更加清晰 - 我见过有两种添加调试器支持的方法:

    将 IronPython 作为 CLR 应用程序进行调试

    第一个是利用 IronPython 发出 IL 的事实,并使用用于调试 .Net 应用程序的标准技术对其进行调试。 Harry Pierson here 有一系列关于这种方法的博客文章关于 ipydbg 的开发 - 一个使用这种方法的 python 调试器。

    • 请参阅 this post 了解 .Net 调试功能的公开位置以及围绕它的各种包装 (mdbg) 的概述
    • 这种方法的缺点是这种调试形式会完全阻止正在调试的应用程序,因此您必须在第二个应用程序中执行脚本。

    使用 Microsoft.Scripting.Debugging

    由于这个限制,生成了 Microsoft.Scripting.Debugging 库,它更适合运行 IronPython “嵌入式”(即在同一进程中)的应用程序。

    有一个关于它的介绍 here 和一个更广泛的博客文章关于它如何使用 here - 本质上它由一个回调函数组成,每次发生任何“有趣”的事情时都会执行(每次我们输入一个函数, 每次我们从函数返回并且每次执行一行时)。回调函数运行时脚本的执行被阻止,这允许您“中断”脚本。

    我决定采用第二种方法 - 我会更新这篇文章,因为我发现更多信息可能有助于其他尝试这样做的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      相关资源
      最近更新 更多