- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编译文件 stacktrace.d:void main(){assert(false);}
关闭 ASLR,运行时我得到:
core.exception.AssertError@stacktrace.d(2): Assertion failure
----------------
??:? _d_assertp [0x55586ed8]
??:? _Dmain [0x55586e20]
objdump -t stacktrace|grep _Dmain
给出
0000000000032e0c w F .text 0000000000000019 _Dmain
如果我运行gdb -q -nx -ex start -ex 'disas/rs _Dmain' -ex q stacktrace
:
...
Dump of assembler code for function _Dmain:
0x0000555555586e0c <+0>: 55 push %rbp
0x0000555555586e0d <+1>: 48 8b ec mov %rsp,%rbp
=> 0x0000555555586e10 <+4>: be 02 00 00 00 mov $0x2,%esi
0x0000555555586e15 <+9>: 48 8d 3d 44 c0 02 00 lea 0x2c044(%rip),%rdi # 0x5555555b2e60 <_TMP0>
0x0000555555586e1c <+16>: e8 47 00 00 00 callq 0x555555586e68 <_d_assertp>
0x0000555555586e21 <+21>: 31 c0 xor %eax,%eax
0x0000555555586e23 <+23>: 5d pop %rbp
0x0000555555586e24 <+24>: c3 retq
因此,即使前两个 0x55 字节被截断,堆栈跟踪中给出的 0x...86e20 也与指令的开头不匹配。
最佳答案
好的,我刚刚从评论中找到了证明我直觉的源代码部分。
这是添加时的 git 责任:https://github.com/dlang/druntime/blame/bc940316b4cd7cf6a76e34b7396de2003867fbef/src/core/runtime.d#L756
唉,提交消息并不是非常丰富,但代码本身,加上我的内存,让我非常确信。
这就是 druntime
库中的文件 core/runtime.d
。截至撰写本文时,它恰好位于第 756 行
enum CALL_INSTRUCTION_SIZE = 1; // it may not be 1 but it is good enough to get
// in CALL instruction address range for backtrace
callstack[numframes++] = *(stackPtr + 1) - CALL_INSTRUCTION_SIZE;
请注意,抛出异常时,callstack
变量会生成当前调用的副本。当请求实际将其写出时,跟踪打印机将查看该数组以确定要写入的内容。 (看,查找调试信息以打印文件/行号和函数名称真的很慢,所以它只在必须时才这样做,以保持正常的异常使用 - 当它被抛出并稍后捕获时 - 更快。)
无论如何,我记得回溯曾经打印过错误的行。它将打印包含下一条指令的代码行 - 这可能在源代码中距实际的断言/抛出语句相当远,使得打印的帮助不大。如果您查看 git Blame 链接,您会看到旧代码用于直接从堆栈中复制地址。
call
指令的工作原理是将返回地址压入堆栈,然后跳转到子例程地址。返回地址紧接在调用指令之后,因此当CPU返回那里时,它不会再次运行调用。这就是为什么旧代码会显示错误的行号,错误地将责任归咎于以下指令。
新代码会稍微倒回该地址,使其返回到调用指令本身 - 从而将打印的函数放在它所属的行上。但是,在 x86 上,有一些不同的调用指令,我什至不确定是否可以正确倒回 - 您只能通过查看操作码来确定指令的实际大小,只有当您知道指令的大小,或者像CPU本身一样按正向顺序读取代码时,您才知道操作码在哪里。此外,在其他处理器架构上,大小也会有所不同。
就像该行中的评论所说,我们实际上不必做到完美。此回溯的目标是让用户查看正确的位置。调试信息使用一种边界框 - 如果您位于该函数或源代码行的起始地址或之后,但尚未到达下一个函数/行的起始地址,则它认为您在那里。它不知道也不关心代码的小数行。
因此,只需假设大小为 1 - 足以使其回到该边界,就大大简化了实现。
我敢打赌,gdb 在内部做了类似的事情,只是它的打印机隐藏了这一点,直接在其回溯中显示堆栈的返回地址。 (顺便说一句,有趣的提示:在 gdb 中运行程序时,将 --DRT-trapExceptions=no
传递给程序的命令行参数。然后,它会在程序仍在运行时捕获抛出点,而不是打印消息并说程序退出并显示代码 1!)
druntime 打印代码也可以在打印之前返回 +1 以隐藏这个内部实现黑客......但是,嗯。返回地址也不是实际发生调用的位置,无论如何,您都需要在反汇编程序中查看上面的内容。甚至 gdb 实际上也不显示调用的地址(至少不是我的旧版本,也许新版本会显示)。但如果它是 grep 反汇编中的一个值,那可能会很好,不管怎样......如果你想向 druntime 做一个 PR,我会支持你(注意我在那里没有权限,但可以帮助评论)。
但这至少明确地解释了现状。
关于assembly - DMD 堆栈跟踪中的地址有何含义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54550999/
有没有办法在 xdebug 跟踪输出中查看 echo 或 print 函数调用。我正在为我在我的服务器中运行的所有脚本寻找一个全局配置(或一种方法)。 例子: 我希望跟踪输出显示 echo 调用。默
我将应用程序从2.0.0M2升级到了2.1.0,但是当我尝试运行该应用程序时,出现此错误: Note: /Volumes/Info/proyectos-grails/vincoorbis/Member
我如何在共享点中执行日志记录。我想使用跟踪。 以便它记录 12 个配置单元日志。 最佳答案 微软提供了一个例子: http://msdn.microsoft.com/en-us/library/aa9
如何跟踪 eclipse 和 android 模拟器的输出。我习惯于在 Flash 和 actionscript 中这样做。 在 AS3 中它将是: trace('我的跟踪语句'); 最佳答案 您有几
是否可以在 Postgresql 上进行查询跟踪?我在带有 OLEDB 界面的 Windows 上使用 9.0。 此外,我需要它是实时的,而不是像默认情况下那样缓冲... 最佳答案 我假设您的意思是在
第一天 HaxeFlixel 编码器。愚蠢的错误,但谷歌没有帮助我。 如何使用 Haxe、NME 和 Flixel 追踪到 FlashDevelop 输出。它在使用 C++ 执行时有效,但对 Flas
我有一个关于 iPhone 上跟踪触摸的快速问题,我似乎无法就此得出结论,因此非常感谢任何建议/想法: 我希望能够跟踪和识别 iPhone 上的触摸,即。基本上每次触摸都有一个起始位置和当前/移动位置
我正在做我的大学项目,我只想跟踪错误及其信息。错误信息应该与用户源设备信息一起存储在数据库中(为了检测源设备,我正在使用MobileDetect扩展名)。我只想知道应该在哪里编写代码,以便获得所有错误
我正在 Azure 中使用多个资源,流程如下所示: 从 sftp 获取文件 使用 http 调用的数据丰富文件 将消息放入队列 处理消息 调用一些外部电话 传递数据 我们如何跟踪上述过程中特定“运行”
在我的 WCF 服务中,当尝试传输大数据时,我不断收到错误:底层连接已关闭:连接意外关闭 我想知道引发此错误的具体原因,因此我设置了 WCF 跟踪并可以读取 traces.svclog 文件。 问题是
我的目标是在 Firebase Analytics 中获取应用数据,在 Google Universal Analytics 中获取其他自定义数据和应用数据。 我的问题是我是否在我的应用上安装 Fir
我正在 Azure 中使用多个资源,流程如下所示: 从 sftp 获取文件 使用 http 调用的数据丰富文件 将消息放入队列 处理消息 调用一些外部电话 传递数据 我们如何跟踪上述过程中特定“运行”
我们正在考虑跟踪用户通过 Tridion 管理的网站的旅程的要求,然后能够根据此行为将此用户识别为“潜在客户”,然后如果他们在之后没有返回,则触发向此用户发送电子邮件X 天。 SmartTarget
在 Common Lisp 中,函数(跟踪名称)可用于查看有关函数调用的输出。 如果我的函数是用局部作用域声明的,我如何描述它以进行跟踪? 例如,如何跟踪栏,如下: (defun foo (x)
有什么方法可以检测文本框的值是否已更改,是用户明确更改还是某些 java 脚本代码修改了文本框?我需要检测这种变化。 最佳答案 要跟踪用户更改,您可以添加按键处理程序: $(selector).key
int Enable ( int pid) { int status; #if 1 { printf ( "child pid = %d \n", pid ); long ret =
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我有以下测试代码: #include int main(void) { fprintf(stderr, "This is a test.\n"); int ret = open("s
我有一个闭源 Java 应用程序,供应商已为其提供了用于自定义的 API。由于我没有其他文档,我完全依赖 API 的 javadoc。 我想跟踪特定用例在不同类中实际调用的方法。有什么办法可以用 ec
我正在学习 PHP。我在我的一个 php 函数中使用了如下所示的 for 循环。 $numbers = $data["data"]; for ($i = 0;$i send($numbers[
我是一名优秀的程序员,十分优秀!