2

我正在AT91SAM9263开发板上进行嵌入式开发,并遇到一个奇怪的问题。它正在运行Debian Linux内核2.6.18.4,并使用arm-linux-gcc 3.4.6进行交叉编译,并使用uClibc-0.9.28作为C库。我正在调试一个内核设备驱动程序,并且一个特定的函数没有出现在System.map文件中。可以理解的是,我可以不在它上面设置一个断点。奇怪的是,如果我闯入它的调用函数,我不能介入它 - 使用gdb的nexti命令执行它,但跳过源。该函数是atmel_rx_chars(struct uart_port * port)。它是atmel_serial.c中声明的一个静态void函数,它的一个例子出现在[1]。在同一个文件中还有其他的静态void函数(例如atmel_tx_chars(struct uart_port * port)),它们在同一个文件中声明,实际上在System.map文件中被索引。根据[2]“System.map由'nm vmlinux'生成,而无关或不感兴趣的符号被清除。”我曾尝试使用nm(以及objdump)查看所有符号,但它仍然不出现在输出中。但是,当我grep atmel_rx_chars vmlinux它返回一个匹配。我曾经认为自己是一个超级用户,但在此之后我真的很难过。任何意见将不胜感激。从Linux System.map中缺少的函数名称和地址

谢谢

Jayce

[1] http://lxr.free-electrons.com/source/drivers/serial/atmel_serial.c#L379
[2] http://www.faqs.org/docs/Linux-HOWTO/Kernel-HOWTO.html#systemmap

+0

你是如何编译代码的?听起来好像代码是用优化开关编译的,在gdb跳过它或system.map与内核不同步的情况下? – t0mm13b 2010-02-20 02:00:21

+0

内核编译时没有进行优化,并且打开了-g(调试信息)。同样,我觉得有趣的是,在同一个文件中定义的相同返回类型和签名的其他函数映射到System.map文件中,并且对调试器可见,但是这个函数神秘地缺失。不过谢谢你的建议。 -jayce – user277453 2010-02-22 14:46:33

+0

我误会了 - 内核是用-Os编译的,而-g是打开的。我试图用-O0进行编译,但是在[kernel root] /net/core/dev.c + 1710和+1717中断了。 – user277453 2010-02-22 20:00:46

回答

0

对于任何人谁可能有兴趣,我无法弄清楚,为什么它不映射atmel_rx_chars到System.map中的地址。您仍然可以像平常一样设置断点,以便在这种情况下进行调试。我想当我寻找答案时应该更加明显。无论如何,在这个例子中,gdb的命令行中键入

b source_file.c:line# 

所以,这将是

b atmel_serial.c:381 

,它会破坏每当你打出了“失踪”的程序。不过,这仍然是一个不完整的解决方案。分解成特定的行可行,但它不会离开调用函数(atmel_handle_receive)的堆栈框架,因此atg_rx_chars的本地不能被gdb访问。一如往常,任何帮助或见解将不胜感激。希望这是一个很好的起点,如果有其他人遇到这个问题或喜欢它。

谢谢

Jayce

2

你没有看到它是因为编译器内联该功能的原因。它被声明为静态的,只在一个地方被调用,以便编译器将其内联。如果您想在其上放置断点,请更改源代码,使其不再声明为静态并重新编译。