【问题标题】:Is there a way to get the pointer that was access during the handling of a signal?有没有办法获取在处理信号期间访问的指针?
【发布时间】:2016-05-13 12:37:41
【问题描述】:

代码大概是这样的:

#include <signal.h>

void SegmentationFaultHandler( int signal ) {
    if ( signal == SIGSEGV ) {
        // how to check here if it's actual null pointer?
        Throw( NullPointerException, "Object pointer not set to an instance of an object." );
    }
    else
        Throw( InvalidOperationException, "Signal has been intercepted by wrong function." );
}

int main( ) {
    signal( SIGSEGV, SegmentationFaultHandler );
    try {
        int *i = null;
        *i = 0;
...

如何检查我是否没有仔细检查指针,或者只是访问了未初始化的数据并尊重它?

我知道这是可能的,因为调试器可以知道程序试图访问哪个地址。

【问题讨论】:

  • 我不认为调试器是这样工作的。
  • @Boiethios 调试器通过覆盖信号然后植入错误指令来创建断点(?)
  • 也许你可以改用sigaction
  • 调试器知道这一点,因为他们分析进程内存(从崩溃时的调用堆栈和寄存器内容开始)。如果您希望您的软件也能够做到这一点,您只需在其中嵌入一个调试器。换句话说:如果你可以只运行一个调试器,为什么还要麻烦?
  • 如果您只需要在 Windows 上使用它,您可以使用结构化异常处理程序。你会得到一个包含详细信息的 EXCEPTION_RECORD 和 CONTEXT 结构。

标签: c++ windows segmentation-fault signals


【解决方案1】:

看来您可以使用在 signal.h 中声明的 _pxcptinfoptrs 全局变量在处理程序中检索 PEXCEPTION_POINTERS。然后在下面的例子中使用这个指针。

static void sigsegv_handler(int signo)
{
    PEXCEPTION_POINTERS excptr = _pxcptinfoptrs;
    if (excptr != NULL) {

    }
    // ...
}

向量异常处理程序

在windows下你可以使用Vectored Exception Handler。您的处理程序将如下所示:

LONG WINAPI ExceptionFilter( struct _EXCEPTION_POINTERS * pExceptionPointers ) {

然后:

pExceptionPointers->ExceptionRecord->ExceptionCode

是你的异常码,EXCEPTION_ACCESS_VIOLATION是你访问无效内存的时候。

pExceptionPointers->ExceptionRecord->ExceptionInformation[0] == 0

当读操作完成时为真

pExceptionPointers->ExceptionRecord->ExceptionInformation[0] == 1

用于写操作

pExceptionPointers->ExceptionRecord->ExceptionInformation[1]

是发生异常时正在读取/写入的地址

结构化异常过滤

如果您不能使用向量异常处理程序,那么您可以在代码的最低级别添加 __try/__except,即。在 main() 或线程函数正在执行的地方:

 __try {
    // Code which might cause access violation or any other hardware exceptions
 } 
 __except(ExceptionFilter(GetExceptionInformation())) {
 }

【讨论】:

  • 我无法设置 __try 和 __except,我必须让它抛出正确的异常。无论如何,我找到了一种像信号处理程序一样的方法。你可以用AddVectoredExceptionHandler( 0, ... )来做。
  • @LyingOnTheSky 我刚刚更新了答案,请参见顶部 - 但老实说,我从未使用过 _pxcptinfoptrs
  • 别介意,我漏掉了一行。 (答案从一开始就OK)
猜你喜欢
  • 1970-01-01
  • 2015-02-17
  • 2016-07-04
  • 2021-03-09
  • 1970-01-01
  • 2011-01-24
  • 2021-08-24
  • 2023-04-05
  • 2023-04-08
相关资源
最近更新 更多