2012-01-14 52 views
5

我在调试php。当我查看内存中一个我知道指向地址的地方时,我看到了指针 - 例如22810408(0x08048122) - 这是使用CLI的CLI版本。然而,当我使用apache2并尝试做同样的事情时,我没有看到指向真实地址的指针。相反,我看到ELF标题的偏移量,当它添加到ELF标题的地址时,会给我“真实”地址。 例如,如果“真实”地址是0x08048122,并且ELF标头是0x08048000,那么我会在同一位置看到22010000(0x122)。为什么apache将偏移量保存到php-cli拥有虚拟内存地址的内存中?

当我试图找出堆栈中某个东西的“真实”地址时,就会出现问题。 “真实”的地址应该是0xbfccxxxx,但是当我把这个数字加到ELF头部时,事情就不会加起来!我得到了所有错误的地址。

我已经试了很长时间的Google搜索,但我真的不知道如何正确地说出这个词,或者要搜索什么。

所以,我基本上寻找的是更多的信息为什么Apache有一个偏移量,而不是一个真正的内存地址,以及这是如何涉及到堆栈上的地址。任何人都可以给我任何可能澄清的材料的指针?

+0

您是否正在查看可执行文件中尚未加载的偏移量,而不是正在运行的进程中的地址? – ugoren 2012-01-14 19:50:38

+0

这可能是如何工作的。你有关于如何工作的更多信息? – optional 2012-01-14 19:59:44

+1

你的“指针”让我有更好的搜索结果。看来,对于Apache,PHP是一个.so,不是一个真正的可执行文件。所以,我看到的是偏移量,而不是实际地址,这是原因。我仍然无法完全理解的是如何从我的“偏移”转到真正的虚拟内存地址。我仍在阅读,但任何澄清或强制性阅读将不胜感激。至少现在我明白了,我不能简单地添加我的ELF地址来获得正确的地址 - 似乎我需要解析重定位表.. – optional 2012-01-14 20:47:31

回答

2

Apache利用mod_php,一个dynamically linked shared object library(.so)。请参阅what is mod_php?。 PHP-CLI作为zend API的前端(php可执行文件)。

mod_php在其侧面加载并利用zend API来解析并返回PHP文件到Apache。正如你所看到的,这里有很多的间接性。这个方法比让apache使用PHP作为守护进程或类似工具更好更快。

在调试PHP时,您通常工作在比这更高的级别上,因为即使您获得了正确的偏移量, PHP数据类型不是C的1:1(因为PHP的鸭子键入),对于关联数组和对象,内存中的表示与C对象的表示非常不同。

我建议您使用specialized PHP debugger来调试PHP应用程序。