相关疑难解决方法(0)

为什么在X86上使用单步执行指令?

所以有"int 3"这是一个用于调试器断点的中断指令.

但是还有"int 1"用于单步执行.但为什么需要呢?我已经读过,在EFLAGS寄存器中设置陷阱标志(TF)将启用单步执行,并将为每条指令捕获到操作系统.那么为什么需要单独的中断类型呢?

谢谢!

debugging x86 gdb

6
推荐指数
2
解决办法
5036
查看次数

gdb如何在共享库函数中设置软件断点?

我知道可执行文件中的软件断点可以通过用另一个替换所需位置的某些汇编指令来工作,这会导致中断.因此,调试器可以在此处完全停止执行,并将此指令替换为原始指令,并询问用户下一步操作或调用某些命令等.

但是这样的可执行文件的代码不被其他程序使用,并且在内存中只有一个副本.软件断点如何与共享库一起使用?例如,如果我在C库的某个内部函数中设置一个软件断点,它的工作原理(据我所知它只有一个副本用于所有应用程序,所以我们不能只替换它中的一些指令)?是否有为此目的的"软件断点"技术?

debugging gdb breakpoints internals shared-libraries

6
推荐指数
1
解决办法
956
查看次数

为什么clang用-O0生成效率低的asm(对于这个简单的浮点和)?

我在llvm clang Apple LLVM 8.0.0版(clang-800.0.42.1)上反汇编代码:

int main() {
    float a=0.151234;
    float b=0.2;
    float c=a+b;
    printf("%f", c);
}
Run Code Online (Sandbox Code Playgroud)

我编译时没有-O规范,但我也试过-O0(给出相同)和-O2(实际上计算值并存储它预先计算)

产生的反汇编如下(我删除了不相关的部分)

->  0x100000f30 <+0>:  pushq  %rbp
    0x100000f31 <+1>:  movq   %rsp, %rbp
    0x100000f34 <+4>:  subq   $0x10, %rsp
    0x100000f38 <+8>:  leaq   0x6d(%rip), %rdi       
    0x100000f3f <+15>: movss  0x5d(%rip), %xmm0           
    0x100000f47 <+23>: movss  0x59(%rip), %xmm1        
    0x100000f4f <+31>: movss  %xmm1, -0x4(%rbp)  
    0x100000f54 <+36>: movss  %xmm0, -0x8(%rbp)
    0x100000f59 <+41>: movss  -0x4(%rbp), %xmm0         
    0x100000f5e <+46>: addss  -0x8(%rbp), %xmm0
    0x100000f63 <+51>: movss  %xmm0, -0xc(%rbp)
    ...
Run Code Online (Sandbox Code Playgroud)

显然它正在做以下事情:

  1. 将两个浮点数加载到寄存器xmm0和xmm1上
  2. 把它们放在堆栈中
  3. 从堆栈加载一个值(不是之前的xmm0)到xmm0
  4. 执行添加. …

c assembly x86-64 compiler-optimization llvm-codegen

4
推荐指数
1
解决办法
333
查看次数

断点后GDB如何恢复指令

我已经读到 GDB 在目标程序内存中的所需地址处放置了一个 int 3(操作码 CC)。

Si 这个操作是擦除程序存储器中的一条指令(1 个字节)。我的问题是:当程序继续时,GDB 如何以及何时替换原始操作码?

当我在 GDB 中键入反汇编时,我看不到 CC 操作码。这是因为 GDB 知道是他放了 CC 吗?有没有办法进行原始反汇编,以便准确查看此时内存中加载了哪些操作码?

gdb

3
推荐指数
1
解决办法
437
查看次数