首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有办法检查指针是否仍然有效?

是否有办法检查指针是否仍然有效?
EN

Stack Overflow用户
提问于 2010-12-09 17:22:09
回答 4查看 2.4K关注 0票数 0

我计划创建一个日志/跟踪机制,它将字符串文本的地址(const char*)写到一个环缓冲区中。这些字符串位于只读数据段中,由使用__function____file__的预处理器创建。

问题:如果所有指针都是有效的,是否有可能在分段错误之后分析这个环缓冲区内容?使用“有效”,我的意思是它们指向映射的内存区域,取消引用不会导致分段错误。

我正在使用Linux2.6.3x和GCC 4.4.x。

诚挚的问候,

查莉

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-09 18:32:42

当然,如果您所依赖的堆栈或其他内存已损坏,则可能会出现问题,但对于任何代码来说都是如此。

假设您所依赖的堆栈或其他内存没有问题,假设您没有调用任何像malloc()这样的非异步信号安全函数,并且假设您不尝试从信号处理程序返回,那么从信号处理程序中读取或写入缓冲区应该没有问题。

如果试图测试特定地址是否有效,可以使用系统调用(如mincore() )并检查错误结果。

票数 1
EN

Stack Overflow用户

发布于 2010-12-09 17:39:25

我认为您正在寻找的方法是通过SIGSEGV处理sigaction信号。

代码语言:javascript
复制
void handler(int, siginfo_t *info, ucontext_t *uap)
{
   /* Peek at parameters here...  I'm not sure exactly what you want to do. */
}

/* Set up the signal handler... */

struct sigaction sa, old_sa;
memset(&sa, 0 sizeof(sa));

sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;

if (sigaction(SIGSEGV, &sa, &old_sa))
{
   /* TODO: handle error */
}

但是请注意,在您自己的过程中捕获SIGSEGV是有点奇怪的。该进程很可能处于无法恢复的糟糕状态。你所能做的回应它的行动可能是有限的,而且很有可能被杀死的过程是一件好事。

如果希望它更稳定一些,可以使用sigaltstack调用来指定一个备用堆栈缓冲区,这样如果您已经完全清理了堆栈,那么仍然可以处理SIGSEGV。要使用这一点,您需要在上面的SA_ONSTACK中设置sa.sa_flags

如果您想要从另一个进程的安全性中响应SEGV (从而将自己与行为不佳的错误代码隔离开来,并使其不会在检查时崩溃),则可以使用ptrace。该接口复杂,有许多不可移植的部件,主要用于编写调试器.但是,您可以使用它完成伟大的任务,比如读取和写入进程的内存和寄存器,并更改其执行。

票数 2
EN

Stack Overflow用户

发布于 2010-12-09 23:16:51

检查取消引用内存区域是否会导致分段错误的通常方法是使用read()write()。为了检查ptr指出的头128个字节是否安全可读性:

代码语言:javascript
复制
int fd[2];
if (pipe(fd) >= 0) {
    if (write(fd[1], ptr, 128) > 0)
        /* OK */
    else
        /* not OK */
    close(fd[0]);
    close(fd[1]);
}

(如果区域不可读,write()将返回EFAULT,而不是发出信号)。

如果您想一次测试多个PIPE_BUF字节,则需要从管道的读取端读取和丢弃。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4401193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档