[译]在SciTE中使用符号调试器

作者 Steve Donovan, 2007 原文链接

SciTE对产生交互式程序的支持有限; 当前只有Win32版本可以做到这一点(例如python),并且它非常绑定到作业队列机制中。 我想在两个平台上都将gdb和其他调试器与我最喜欢的代码编辑器一起使用,因此解决方案是创建一个Lua扩展库,该库提供缺少的功能而不干扰任何现有的精密机械。

此版本使调试器机制通用化,可以接受不同的调试器后端,因此现在您还可以调试Python,Lua,Java和C#Mono程序。 由于有了OnKey扩展,它现在可以在两个平台上使用相同的快捷键-我已将此有用的功能集成到新版本的extman中

使用SciTE进行调试

此扩展假定您选择的调试器/语言在您的路径上,因此如果您在Windows上具有Python或Lua,请确保做到这一点。

应将属性debug.target设置为要调试的程序的完整路径。如果未设置,则debugger.lua将根据目标的扩展推断出所需的实际调试器。如果为“ .lua”,它将选择clidebugger;如果为“ .py”,它将选择pydb;如果为“ .java”,它将选择jdb;如果为“ .cs”或“ .exe”,它将选择mdb。否则,它会退回到gdb。

(Mono调试器mdb在Windows上可能没什么用,因此您可以从scite_lua文件夹中删除mdb.lua。始终可以通过在两个平台上都指定没有扩展名的目标可执行文件来避免’.exe’冲突。)

在输出窗口中,可以键入$ debug.target = any-file;。任何SciTE属性都可以通过这种方式设置。

Tools | Run(Alt + R)将开始会话;如果已经用Tools | Breakpoint(F9)定义了任何断点,则会设置它们,然后您将移至任何断点位置。一旦到达那里,您就可以以类似的方式添加其他断点。注意,mdb和pydb的工作方式略有不同。您将始终被带到程序的第一可执行行。对于Python,这可能不是您要启动的地方,因此请在主程序实际开始运行的地方放置一个断点。 Lua调试器clidebugger通常是这样工作的,但是我以需要明确断点的方式来驱动它。

工具| Step(Alt + C)和工具| Step Over(Alt + N)可用于单步执行代码,而工具| Inspect(Alt + I)和Tools | Locals(Alt + Ctrl + L)可用于查看光标下任何变量的值。您当然可以在输出窗格中输入任何调试器命令,但是不会进行任何简化。

Alt + R将恢复执行。您也可以使用工具|转到(Alt + G)创建一个临时断点,然后继续执行该位置。 (可能并非所有调试器都支持此功能。)

如果发生崩溃,该位置将以红色突出显示。 Tools | Backtrace(Alt + Ctrl + B)将显示堆栈跟踪,双击堆栈跟踪行将带您到该帧号。 (当前仅针对gdb,mdb和clidebug实施。)此时,Tools | Up(Alt + U)和Tools | Down(Alt + D)也很有用; Alt + U将带您进入调用当前函数的函数,依此类推;函数堆栈具有深度,因此任何错误或断点都定义了最深的函数级别。

如果在暂停时将鼠标悬停在符号上,则scite-debug将尝试评估该符号并将其显示为工具提示。

一些调试器的特定功能

该版本带有两个简化,可以识别两种常见的C ++字符串模式。 std :: string和Scintilla的SString。 这些尝试从结构转储中提取实际的字符串值。 (显然,这些模式非常依赖于相关类型的实际实现!)这是gdb中std :: string值的原始转储:

(gdb) p s
$1 = {static npos = 4294967295,
  _M_dataplus = {<allocator<char>> = {<No data fields>},
    _M_p = 0x3d3acc "hellohelp"}, static _S_empty_rep_storage = {0, 0, 0, 0}}
(gdb) quit

t也将尝试通过将每一帧收集到一行来简化帧转储。

可以跳过库调用。 这些通常发生在C ++中,当您调用实现为模板的标准库功能时,以及在Python中调用模块方法时。 (您可以通过将属性debug.skip.includes设置为false来关闭此功能。)在Windows上,还必须通过设置debug.skip.file.matching(对于gdb)和debug.skip来指定编译器包含文件的位置。 .file.matching.py(适用于Python)。 在GTK平台上,默认情况下,我们将跳过以’/ usr /’开头的所有文件。 在我的Windows框上,我有以下定义-请注意Mingw的正斜杠和Python的小写(即使它以Explorer中的大写字母开头!)

debug.skip.file.matching=d:/stuff/MinGW
debug.skip.file.matching.py=d:\python25

提示和技巧

与往常一样,您可以直接在输出窗格中键入调试器命令。 一个有用的技巧是,如果您想查看全局变量何时在gdb中更改; 暂停后,您可以在提示符下键入watch var并键入Alt + R继续,当var更改时,您将中断。

如果程序已完成或尚未运行,则提示的工作方式将有所不同。 您可以交互设置和评估SciTE属性。 例如,如果我在计算机上键入命令$ SciteDefaultHome,则会收到响应SciteDefaultHome =“ / usr / share / scite”。 也可以设置属性。 为了解决只能一次设置一个debug.target的限制,我在用户属性文件中添加了一些替代方案:

ucc=/home/sdonovan/underC/src/ucc
aggregator=/home/sdonovan/serial/cpp_client/aggregator

然后,如果我想调试underC,我可以简单地键入$ debug.target = $(ucc),剩下的事情就是SciTE属性扩展的魔力了。

如果该行不是以$开头,则默认操作是评估Lua表达式。 通常,这对于调试非常有用,或者在您需要进行一些算术;)的情况下。

= 20+10
30
(lua) 

此版本的新功能是还可以执行Shell命令。 如果该行的第一个字符是’>’,则该行的其余部分被假定为shell命令,并将使用spawner.popen执行。

完全可以运行一个以上的SciTE实例,调试不同的目标。 如果要调试两个用C ++编写的应用程序,同时调试Lua中的任何嵌入式脚本,这将很有用。

调试 SciTE Lua 代码

耐心一点,您不仅可以使用SciTE调试可执行文件,还可以使用任何SciTE Lua脚本。 实际上,scite-debug可以调试自己,这显示了它的灵活性。 这些指令实际上适用于使用Lua作为其扩展语言的任何程序。 我提供了Lua远程调试器remDebug的修改版本。 (此软件包需要lfs和luasocket)

您需要做的第一件事是将其放在Lua启动脚本中(我将这些行放在extman.lua的末尾)

package.path=package.path..";c:/lang/lua/lua/?.lua"
 require "remdebug.engine"
 remdebug.engine.start()

第一条语句确保SciTE可以使用require找到其他Lua软件包。 或者,您可以将engine.lua的副本放在SciTE package.path中的remdebug目录中

在调试器SciTE中,必须将属性debug.target设置为:remote.lua(这可以从调试器提示符处进行处理,如前所述。)冒号很重要,它与普通的Lua脚本区别开来。 使用clidebugger进行了调试。

转到所需的功能,用F9设置断点; 使用Alt + R启动调试器; 它将等待远程程序启动。 最后,启动另一个SciTE。

关于remDebug的绝对酷的事情是,您调试的程序实际上不必在同一台计算机上,因为所有通信都是通过套接字完成的。 要调试真正的远程Lua程序,请像以前一样使用:debug.target = remote.lua启动运行SciTE调试器,并将这些行放在远程脚本的前面(请注意大括号):

require "remdebug.engine"
remdebug.engine.start()
remdebug.engine.config { host = your-ip-address }

安装

LuaForge 下载:

对于此发行版,您将需要SciTE的新版本,该版本导出其Lua符号并启用loadlib。 最新的公共发行版是:SciTE 1.75。

在Windows上,通常在用户属性文件中包含以下内容:

ext.lua.startup.script=$(SciteDefaultHome)\scite-debug\extman.lua

which means you have to unzip scite-debug.zip in the scite\bin directory next to your SciTE executable. On Linux, unzip this file in your home directory and put this in your user properties file:

ext.lua.startup.script=$(SciteUserHome)/scite-debug/extman.lua

实现说明

这个扩展是一个小的DLL(或共享库),它捕获调试器进程并将调试器输出发送回Lua子系统。在主SciTE线程中调用Lua代码非常重要,因为子进程在其自己的线程中运行。在Windows上,我使用与SingleThreadExtension.cxx中相同的技巧,即创建一个隐藏的窗口并使用消息将输出发送给它。在GTK上,我使用gtk_input_add。

对于Windows,我自由地使用现有的SciTE代码生成进程。通常,我们会阻塞ReadFile调用,除非在最后一直保持窥视以确保进程循环正常结束(我发现,总是窥视会导致性能问题。)

在GTK / Unix方面,我使用forkpty捕获诸如gdb之类的交互式进程。然后,它在伪终端中运行,该伪终端默认为行缓冲。 (这类似于“规范”串行通信,并且可以使用相同的termios结构来控制伪终端)。调试器的提示设置为以换行符结尾的内容,因此我们总是会收到提示;对于gdb,“设置高度0”用于禁用gdb的默认分页。请注意,并非每个调试器都允许这样做,这可能需要重新考虑始终以每行为基础进行操作。

我使用-fullname标志启动gdb,该标志告诉gdb使用文件的全路径对所有换行符进行特殊编码,从重复的’\ 032’字符开始-这是Emacs使用的模式。 gdb输出的解析在很大程度上与平台无关。有一个功能simple_term,它试图取消对托管字符串的破坏,例如std :: string和SString;。这是一个有用的定制点。

更进一步的工作

此版本的scite-debug实现了一个重要目标,该目标是排除所有调试器的通用代码并使gdb成为特例。现在,它是一个适当的面向对象的框架,其中所有调试器都从Dbg类派生并根据需要重写方法。 Python和Lua调试器已经有用,但是其他调试器需要一些工作。特别地,jdb是一种奇怪的野兽,因为您使用类名而不是文件名指定断点。好吧,通常这就是Java代码的组织方式,但是匿名类很烦人,因为它们得到了给定的类名,例如OuterClass $ 1等,而这还不能实现自动化。而且,所有类都必须位于同一目录中,因为我还没有打包程序。但是足以完成您的作业! Mono调试器mdb仍然很年轻,但是Mono是一个平台,急需更好的调试集成。因此,SciTE现在是需要在Mono上调试C#(或Boo!)的人们可用的少数选项之一。

还有其他候选调试器。例如,Windows上与mdb相对应的是cordbg,它是.NET SDK随附的。 。另一个候选者将是英特尔Fortran调试器,它比免费的Fortran系统更加智能。通常,添加调试器会变得更加容易,因为它们倾向于遵循模式(例如,它们在流程结束时会自动退出还是在等待退出命令?),并且可以通用地捕获它们。远程调试对于在嵌入式环境中工作的人员很重要,我想添加一些必要的挂钩以使其在SciTE中工作。

SciTE具有一些接口限制;对于调试界面而言,拥有一个通用的图形小部件的通用库(如浮动工具栏,列表框和通用文件对话框)将非常有用。可以使用与生成器库使用的完全相同的技术来接口这些接口。在这里,我完全同意SciTE不是IDE的SciTE理念,它应该为开发人员提供增加其所需功能的钩子,而不会给其他用户带来负担。 (有关为什么此极简主义很重要的示例,请查看KDevelop和Anjuta。)

最后要说明的是,支持所有内容的危险是没有任何内容得到完全支持。我目前专注于C / C ++和Lua,但是所做的任何核心增强功能当然也可用于其他调试器。

额外的工具

ctags的支持

SciTE已经有一些内置的ctags支持了一段时间,但这有点尴尬。您要做的就是使用Exuberant ctags实用程序创建一个标记文件,该实用程序已广泛使用。例如,对于SciTE本身,我在Linux上运行ctags src / *。cxx gtk / *。cxx,在Windows上运行ctags src \ *。cxx gtk \ *。cxx。 ctagsdx.lua会将这个标签文件读入内部表中,然后您可以使用“工具|查找标签”(Ctrl +,即句点)导航到任何标签。到达那里后,您可以使用工具|转到标记(Alt +。)返回开始的位置。如果有多个匹配标签(C ++通常会发生这种情况),则会为您提供一个下拉列表供您选择。

如果您只想记住自己的最后位置(例如,在查找操作开始时),则|工具|设置标记(Ctrl +’)很有用。查找标签会自动推送标记堆栈。如果已设置标记,则可以使用“工具” |“从标记中选择(Ctrl + /)”选择当前位置。

您可以将快捷方式更改为更直观的方式;)

缓存切换 Buffer Switching

我一直都错过了在SciTE中最近使用的两个缓冲区之间切换的功能。 switch_buffers.lua提供了两件事:Ctrl + F12切换最后两个缓冲区,Alt + F12给出最近使用顺序的缓冲区下拉列表。

对于C / C ++文件,可以使用“工具|开关源/标题(Ctrl + Shift + H)”在源文件和头文件之间移动。

智能选择

启用select_string.lua后,您将获得更智能的双击选择。 此扩展程序尝试以相同的样式(例如,字符串或注释)收集所有字符。 使用符号,它将像以前一样运行。 与往常一样,如果此功能使您烦恼,则只需从scite_lua目录中删除select_string.lua。

微模式 Micromodes

这来自于我在Sciboo编辑器中探索的想法。 它使您可以精确地控制使用什么工具来生成或运行文件。 通常,Build(F7)通常设置为“ make”。 对于简单的项目,使用make会显得过分,特别是如果您在同一目录中有多个这样的项目。 使用微模式,您可以直接在源文件中提供构建命令。 例如,如果您的C文件是这样开始的:

// build@ gcc fred.c alice.o -o fred

然后将属性command.build。*设置为’gcc fred.c alice.o -o fred’。 “ build”,“ compile”和“ go”在此处有效。


译者:这个库距今已经十多年,本文转存安装包及其扩展文件,以防止官网失效。

本地下载:Debugger extension for SciTE.rar

原站信息:

Scitedebug is a SciTE extension for integrating various debuggers. Currently, one can debug C,C++,Lua,Python pretty well, and there is experimental support for Java and C#.

Website: http://scitedebug.luaforge.net
Admins: stevedonovan
Members: stevedonovan
License: BSD License
Language: c++, lua 5
Tags: debuggers, integrated development environments (ide)
OS: windows, posix
Registered: 2007-11-27 07:31
Archived Mailing Lists: n.a.
Archived Releases:
Archived releases may be out of date. See the project’s current website for the latest releases.
gdbpy
scitedebug
SciTEInstaller
Source Repository: n.a.

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

4 × 4 =