Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
X86 如何获取特定帧的寄存器值?_X86_Solaris - Fatal编程技术网

X86 如何获取特定帧的寄存器值?

X86 如何获取特定帧的寄存器值?,x86,solaris,X86,Solaris,如何在每次函数调用时获取寄存器值? 我想我们可以使用帧指针,但我不知道如何使用 更新:这不是实时分析。这是用于内核崩溃转储分析。只知道帧指针对您没有帮助。EBP在XORL%EAX,%EAX之前和之后都是相同的。然后,碰巧x86指令集本身没有绑定到任何特定的ABI。这意味着,任何这样做的尝试都需要您了解EIP、EBP(从那里您可以获得每隔一帧的EBP和EIP)以及ABI,即使如此,根据ABI,某些(或全部)值也无法检索。EBP本身是一个通用寄存器,因此帧甚至不是必需的(请参见-fomit fram

如何在每次函数调用时获取寄存器值? 我想我们可以使用帧指针,但我不知道如何使用


更新:这不是实时分析。这是用于内核崩溃转储分析。

只知道帧指针对您没有帮助。EBP在
XORL%EAX,%EAX
之前和之后都是相同的。然后,碰巧x86指令集本身没有绑定到任何特定的ABI。这意味着,任何这样做的尝试都需要您了解EIP、EBP(从那里您可以获得每隔一帧的EBP和EIP)以及ABI,即使如此,根据ABI,某些(或全部)值也无法检索。EBP本身是一个通用寄存器,因此帧甚至不是必需的(请参见
-fomit frame pointer

为此,让我们假设ABI(大多数C编译器用于大多数C代码)。要研究当前函数的寄存器,只需查看它们。他们没有什么不同。然后,您需要能够从函数返回。如果你的程序崩溃了,你不能这样做,那么你就完蛋了。函数返回后,您可以查看除EAX、ECX和EDX之外的所有寄存器。这三个都是“调用方保存的”,也就是说,刚刚返回的函数可以修改它们,而不是还原它们。它们的内容很可能丢失了


然后,您可以继续,返回并调查除EAX、ECX和EDX之外的所有内容,一直到您想要的地方。无论如何,通过步进之类的方式调试是一个更好的主意。我认为您甚至无法从函数返回(至少GDB不能返回)。

只知道帧指针对您没有帮助。EBP在
XORL%EAX,%EAX
之前和之后都是相同的。然后,碰巧x86指令集本身没有绑定到任何特定的ABI。这意味着,任何这样做的尝试都需要您了解EIP、EBP(从那里您可以获得每隔一帧的EBP和EIP)以及ABI,即使如此,根据ABI,某些(或全部)值也无法检索。EBP本身是一个通用寄存器,因此帧甚至不是必需的(请参见
-fomit frame pointer

为此,让我们假设ABI(大多数C编译器用于大多数C代码)。要研究当前函数的寄存器,只需查看它们。他们没有什么不同。然后,您需要能够从函数返回。如果你的程序崩溃了,你不能这样做,那么你就完蛋了。函数返回后,您可以查看除EAX、ECX和EDX之外的所有寄存器。这三个都是“调用方保存的”,也就是说,刚刚返回的函数可以修改它们,而不是还原它们。它们的内容很可能丢失了


然后,您可以继续,返回并调查除EAX、ECX和EDX之外的所有内容,一直到您想要的地方。无论如何,通过步进之类的方式调试是一个更好的主意。我认为您甚至不能从函数返回(GDB不能,AFAIK)。

GDB
中,您可以使用
finish
命令(
f
)执行单步操作,直到当前函数返回。通常,如果不运行函数的其余部分,就无法返回,除非您知道
ESP
当前指向正确的位置。然后,您可以在函数的结束语开始时继续执行。此外,gdb还有一些记录历史的方法,可以让你在时间上倒退。我忘了它是什么;我从Jester的一条评论中发现了它的存在,但从那以后我就不再需要它了,所以我自己也没有试过。我以前没提到过,这是为了内核崩溃转储分析。@Iceman:那是更糟糕的情况!我的意思是,调试内核有时可能是一个相当不同的过程。然后,由于您有一个崩溃转储,而不是一个正在运行的进程,您无法从崩溃函数返回。在
gdb
中,您可以使用
finish
命令(
f
)执行单步操作,直到当前函数返回。通常,如果不运行函数的其余部分,就无法返回,除非您知道
ESP
当前指向正确的位置。然后,您可以在函数的结束语开始时继续执行。此外,gdb还有一些记录历史的方法,可以让你在时间上倒退。我忘了它是什么;我从Jester的一条评论中发现了它的存在,但从那以后我就不再需要它了,所以我自己也没有试过。我以前没提到过,这是为了内核崩溃转储分析。@Iceman:那是更糟糕的情况!我的意思是,调试内核有时可能是一个相当不同的过程。然后,由于您有一个崩溃转储,而不是一个正在运行的进程,因此无法从崩溃函数返回。
> ffffff00bbcc8c40::findstack -v
stack pointer for thread ffffff00bbcc8c40: ffffff00bbcc86b0
[ ffffff00bbcc86b0 _resume_from_idle+0xf4() ]
  ffffff00bbcc86e0 swtch+0x145()
  ffffff00bbcc8710 cv_wait+0x61(ffffff1a4e538bb8, ffffff1a4e538a80)
  ffffff00bbcc8770 cv_wait_sig+0x26e(ffffff1a4e538bb8, ffffff1a4e538a80)
  ffffff00bbcc8850 so_dequeue_msg+0x2a4(ffffff1a4e538a60, ffffff00bbcc88b8, ffffff00bbcc8980, ffffff00bbcc88c0, 40)
  ffffff00bbcc8920 so_recvmsg+0x1af(ffffff1a4e538a60, ffffff00bbcc89b0, ffffff00bbcc8980, ffffff198dc34db0)
  ffffff00bbcc8960 socket_recvmsg+0x3d(ffffff1a4e538a60, ffffff00bbcc89b0, ffffff00bbcc8980, ffffff198dc34db0)
  ffffff00bbcc8a40 ksocket_recv+0x124(ffffff1a4e538a60, ffffff00bbcc8aac, 4, 40, ffffff00bbcc8a58, ffffff198dc34db0)
  ffffff00bbcc8a90 smb_sorecv+0x4e(ffffff1a4e538a60, ffffff00bbcc8aac, 4)
  ffffff00bbcc8ad0 smb_session_xprt_gethdr+0x35(ffffff23b1784c38, ffffff00bbcc8ae8)
  ffffff00bbcc8b20 smb_session_message+0x214(ffffff23b1784c38)
  ffffff00bbcc8b60 smb_session_receiver+0x8c(ffffff23b1784c38)
  ffffff00bbcc8b90 smb_server_receiver+0x28(ffffff23d5ff1ce8)
  ffffff00bbcc8c20 taskq_d_thread+0xb1(ffffff19f34ec258)
  ffffff00bbcc8c30 thread_start+8()