我正在使用LLVM编写一个小的BASIC编译器,一切正常。我试图让调试工作,并且它很顺利,但我对变量名和GDB的打印语句有一个奇怪的问题。
对于那些不熟悉的人,有一些关于BASIC的背景知识:
在BASIC中,变量名称在末尾使用符号来确定其类型。所以变量x%是整数,变量x $是一个字符串,两者都可以共存。
语句DEFINT A-Z表示任何以A到Z的任何字母开头的变量都是INT类型,即使没有尾随的%。但是,在内部,我的编译器将存储带有尾随%的名称,以避免与另一个带有尾随$的变量重叠。
这是我的小测试程序:
defint a-z
x = 5
y = 100
z = x + y
if x = 5 then
print "z=";z
else
print "z!=";z
end if
所以' x'实际上是存储在内部并作为x%放入符号表。
好的,所以我将编译好的EXE加载到GDB ......
D:\dev\BasicParser>gdb t.exe
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from D:\dev\BasicParser\t.exe...done.
(gdb) b _jbc_main
Breakpoint 1 at 0x401000: file t.bas, line 1.
(gdb) r
Starting program: D:\dev\BasicParser\t.exe
[New Thread 1532.0x25b8]
Breakpoint 1, _jbc_main () at t.bas:1
1 defint a-z
(gdb) n
4 x = 5
(gdb) info address x%
Symbol "x%" is static storage at address 0x4263c4.
此时,您可以看到GDB识别符号x%,因为它识别并显示它的地址。但是以下&#34; print&#34;失败:
(gdb) print x%
No symbol "x" in current context.
嗯...这很有趣......它掉了%符号。
但是我可以查看存储x%的内存位置,这看起来是正确的:
(gdb) x 0x4263c4
0x4263c4 <x%>: 0x00000000
如果我显示所有符号,我会按预期得到这个:
(gdb) info variables
All defined variables:
File t.bas:
static i32 x%;
static i32 y%;
static i32 z%;
继续,以显示x%确实被代码修改:
(gdb) n
5 y = 100
(gdb) print x%
No symbol "x" in current context.
(gdb) x 0x4263c4
0x4263c4 <x%>: 0x00000005
(gdb)
正如您所看到的,GDB认为x%所处的内存肯定会更新。
出于某种原因,&#34; print&#34;命令不像%符号。
这是&#34;信息来源&#34;在这个模块上的结果,你可以看到我没有指定C作为语言:
(gdb) info source
Current source file is t.bas
Compilation directory is D:\dev\BasicParser
Located in D:\dev\BasicParser\t.bas
Contains 18 lines.
Source language is minimal.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
有关解决方法的任何想法吗?我一直在搜索和搜索,无法找到解决方案。
谢谢!
答案 0 :(得分:2)
gdb
只是将您的命令解释为模运算。这不是gdb
中的错误。
请参阅info source
为您的文件显示minimal
。这是来自gdb的doc:http://sourceware.org/gdb/current/onlinedocs/gdb/Unsupported-Languages.html#Unsupported-Languages
除了其他完全支持的编程语言,GDB 还提供了一种名为
minimal
的伪语言。它不代表 一种真正的编程语言,但提供了一组关闭的功能 C语言或汇编语言提供的内容。
那么,调试会话中的这个警告是什么意思?
(gdb) print x%
No symbol "x" in current context.
由于minimal
是一组接近C的功能,因此根据C编程语言规则,gdb
必须将其解释为尝试获得除法的余数(http://en.wikipedia.org/wiki/Modulo_operation)。所以x
是arg,%
是操作,右边的arg丢失了。
让我举个例子。这是一个测试C ++程序,显示minimal
调试会话:
D:\src-c++\tests\test.vars>cat minimal.cpp
int main()
{
int k;
k = 1;
k = 2;
return 0;
}
这是一个调试会话:
D:\src-c++\tests\test.vars>gdb -q minimal.exe
Reading symbols from D:\src-c++\tests\test.vars\minimal.exe...done.
(gdb) start
Temporary breakpoint 1 at 0x4016be: file minimal.cpp, line 5.
Starting program: D:\src-c++\tests\test.vars/minimal.exe
[New Thread 2872.0x8c0]
Temporary breakpoint 1, main () at minimal.cpp:5
5 k = 1;
(gdb) show language
The current source language is "auto; currently c++".
(gdb) set language minimal
Warning: the current language does not match this frame.
(gdb) show language
The current source language is "minimal".
Warning: the current language does not match this frame.
(gdb) n
6 k = 2;
(gdb) print k
$1 = 1
(gdb) print k%
A syntax error in expression, near `'.
(gdb) print kk%
No symbol "kk" in current context.
看 - 当前上下文中没有符号“kk”,与您有相同的错误。
答案 1 :(得分:0)
只是一个交叉引用,以防其他像我这样可能需要帮助的人:我找到了这个答案
In GDB, how to print the content of a symbol which has special characters?
它们表明您可以通过以与号 (&
) 开头并用单个勾号 ('
) 引用名称来引用名称,即使用类似
p &'my@complex.symbol%name'
x &'my@complex.symbol%name'
检查名称超出通常 C 风格命名约定的符号。我不完全清楚此时您可以使用哪些字符,但似乎是一个很好的改进。
正如另一个答案也指出的那样,GDB 手册经常提到仅使用单个勾号来转义符号名称(例如 p 'foo.c'
)。在进一步阅读 GDB 手册后,我发现 &
的这种用法似乎是为 Windows 支持添加的扩展(请参阅标题为“调试 MS Windows PE 可执行文件的功能”的部分,在当前版本中编号为 21.1.4 ),所以我不确定这是否可以在 Windows 环境之外工作