堆栈跟踪在叶寄存器 (lr) 处停止 [英] stack traces stop at the leaf register (lr)

查看:31
本文介绍了堆栈跟踪在叶寄存器 (lr) 处停止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常看到以 lr 指针终止的 ARM 堆栈跟踪(阅读:Android NDK 堆栈跟踪),如下所示:

Often I see ARM stack traces (read: Android NDK stack traces) that terminate with an lr pointer, like so:

      #00  pc 001c6c20  /data/data/com.audia.dev.qt/lib/libQtGui.so
      #01  lr 80a356cc  /data/data/com.audia.dev.rta/lib/librta.so

我知道 lr 在 ARM 和其他架构上代表 link register,这是一种存储返回地址的快捷方式,但我不明白为什么它似乎总是存储一个无用的地址.在这个例子中,80a356cc 不能被映射到任何使用 addr2linegdb 的代码.

I know that lr stands for link register on ARM and other architectures, and that it's a quick way to store a return address, but I don't understand why it always seems to store a useless address. In this example, 80a356cc cannot be mapped to any code using addr2line or gdb.

有什么方法可以获得更多信息吗?为什么跟踪必须在 lr 地址处停止?

Is there any way to get more information? Why must the trace stop at the lr address anyway?

推荐答案

终于找到答案了.我只需要更加细心.查看以下简短的堆栈跟踪及其后的信息:

Stumbled on the answer finally. I just had to be more observant. Look at the following short stack trace and the information that comes after it:

         #00  pc 000099d6  /system/lib/libandroid.so
         #01  lr 80b6c17c  /data/data/com.audia.dev.rta/lib/librta.so

code around pc:
a9d899b4 bf00bd0e 2102b507 aa016d43 28004798 
a9d899c4 9801bfa8 bf00bd0e 460eb573 93004615 
a9d899d4 6d842105 462b4632 200047a0 bf00bd7c 
a9d899e4 b100b510 f7fe3808 2800edf4 f04fbf14 
a9d899f4 200030ff bf00bd10 b097b5f0 4614af01 

code around lr:
80b6c15c e51b3078 e5933038 e5932024 e51b302c 
80b6c16c e1a00002 e3a01000 e3a02000 ebfeee5c 
80b6c17c e1a03000 e50b303c e51b303c e1a03fa3 
80b6c18c e6ef3073 e3530000 0a000005 e59f34fc 
80b6c19c e08f3003 e1a00003 e51b103c ebfeebe6 

现在lr地址仍然是一个对我们没有用的80xxxxxx地址.

Now the lr address is still a 80xxxxxx address that isn't useful to us.

它从pc 打印的地址是000099d6,但请看下一节,code around pc.第一列是地址列表(你可以从它每次递增 16 的事实中看出.)这些地址看起来都不像 pc 地址,除非你砍掉前 16 位.然后你会注意到 a9d899d4 必须对应于 000099d4,程序停止的代码是从那里开始的两个字节.

The address it prints from the pc is 000099d6, but look at the next section, code around pc. The first column is a list of addresses (you can tell from the fact that it increments by 16 each time.) None of those addresses looks like the pc address, unless you chop off the first 16 bits. Then you'll notice that the a9d899d4 must correspond to 000099d4, and the code where the program stopped is two bytes in from that.

Android 的堆栈跟踪似乎为我砍掉"了 pc 地址的前 2 个字节,但无论出于何种原因,它都没有对叶寄存器中的地址执行此操作.这给我们带来了解决方案:

Android's stack trace seems to have "chopped off" the first 2 bytes of the pc address for me, but for whatever reason it does not do it for addresses in the leaf register. Which brings us to the solution:

简而言之,我能够从 80b6c17c 地址中砍掉前 16 位,使其成为 0000c17c,到目前为止每次我可以使用 gdbaddr2line 查找时,都会给我一个有效的代码地址.(我发现它实际上是通常前 12 位或前 3 个十六进制数字.您可以通过查看自己决定我上面描述的堆栈跟踪输出.)我可以确认它也是正确代码地址.这无疑让调试变得更容易了!

In short, I was able to chop off the first 16 bits from the 80b6c17c address to make it 0000c17c, and so far that has given me a valid code address every time that I can look up with gdb or addr2line. (edit: I've found it's actually usually the first 12 bits or first 3 hexadecimal digits. You can decide this for yourself by looking at the stack trace output like I described above.) I can confirm that it is the right code address as well. This has definitely made debugging a great bit easier!

这篇关于堆栈跟踪在叶寄存器 (lr) 处停止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆