我的CPU是arm。如果它被优化了,我怎样才能找出函数参数值?
例如:
status_t NuPlayer::GenericSource::setDataSource(
int fd, int64_t offset, int64_t length) {
resetDataSource();
mFd = dup(fd);
mOffset = offset;
mLength = length;
上面的函数有3个参数,当我尝试打印第二个参数偏移时,我会得到以下结果:
Thread 4 "Binder:15082_3" hit Breakpoint 1, android::NuPlayer::GenericSource::setDataSource (this=0xae63bb40, fd=8, offset=<optimized out>, length=9384436) at frameworks/av/media/libmediaplayerservice/nuplayer/GenericSource.cpp:123
123 resetDataSource();
(gdb) x/i $pc
=> 0xb02aaa80 <android::NuPlayer::GenericSource::setDataSource(int, long long, long long)+12>: blx 0xb0282454 <_ZN7android8NuPlayer13GenericSource15resetDataSourceEv@plt>
(gdb) n
125 mFd = dup(fd);
(gdb) print offset
$1 = <optimized out>
(gdb) p $eax
$2 = void
(gdb) disassemble /m
Dump of assembler code for function android::NuPlayer::GenericSource::setDataSource(int, long long, long long):
122 int fd, int64_t offset, int64_t length) {
0xb02aaa74 <+0>: push {r4, r5, r6, r7, lr}
0xb02aaa76 <+2>: sub sp, #4
0xb02aaa78 <+4>: mov r4, r3
0xb02aaa7a <+6>: mov r5, r2
0xb02aaa7c <+8>: mov r6, r1
0xb02aaa7e <+10>: mov r7, r0
123 resetDataSource();
=> 0xb02aaa80 <+12>: blx 0xb0282454 <_ZN7android8NuPlayer13GenericSource15resetDataSourceEv@plt>
124
125 mFd = dup(fd);
0xb02aaa84 <+16>: mov r0, r6
0xb02aaa86 <+18>: blx 0xb027e5d8 <dup@plt>
0xb02aaa8a <+22>: ldrd r2, r1, [sp, #24]
0xb02aaa8e <+26>: str.w r0, [r7, #224] ; 0xe0
0xb02aaa92 <+30>: movs r0, #0
126 mOffset = offset;
0xb02aaa94 <+32>: strd r5, r4, [r7, #232] ; 0xe8
127 mLength = length;
0xb02aaa98 <+36>: strd r2, r1, [r7, #240] ; 0xf0
128
129 // delay data source creation to prepareAsync() to avoid blocking
130 // the calling thread in setDataSource for any significant time.
131 return OK;
0xb02aaa9c <+40>: add sp, #4
0xb02aaa9e <+42>: pop {r4, r5, r6, r7, pc}
End of assembler dump.
(gdb)
我想它在某些注册表中,但$ eax的结果是无效的。
答案 0 :(得分:1)
听起来好像示例代码已将参数变量分配给局部变量,因此打印该值将与优化输出参数完全相同。
mOffset = offset;
mLength = length;
答案 1 :(得分:1)
我想这是在某个寄存器中,但$ eax的结果是无效的。
ARM上没有名为CancellationTokenSource
的注册表。
要知道参数所在的寄存器,您需要知道calling convention。
看起来您使用的是32位ARM。从上面的链接:
async Task Send()
{
using(SmtpClient c = new SmtpClient())
using(var cts = new CancellationTokenSource(30000))
{
cts.Token.Register(c.SendAsyncCancel);
await c.SendMailAsync("a@a.a","b@b.b","foo","bar");
}
}
因此,您应该eax
,验证r0 to r3: used to hold argument values passed to a subroutine
,info registers
并在r0 == 0xae63bb40
中找到r1 == 8
。