为什么一个程序访问非法指针的指针不会崩溃? [英] Why does a program accessing illegal pointer to pointer not crash?

查看:412
本文介绍了为什么一个程序访问非法指针的指针不会崩溃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个程序访问非法指针,指针不随SIGSEGV崩溃。这是不是一件好事,但我想,这可能是和过程如何存活在生产中多日。令人感到迷惑我。

我已经给本程序在Windows,Linux和OpenVMS的,和Mac OS一去,他们从来没有抱怨过。

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;无效printx(无效* REC){//我知道这应该是一个**
    焦炭海峡[1000];
    的memcpy(STR,REC,1000);
    的printf(%S * \\ n,1000,STR);
    的printf(哇.. !!我还没有崩溃但:-P);
}INT主(INT ARGC,字符** argv的){
    无效* X = 0; //你也可以说无效* X =(无效*)10;
    printx(安培; X);
}


解决方案

我并不是因缺乏内存故障的惊讶。该方案的的取消引用未初始化的指针。相反,它被复印和打印内存中的内容在一个指针变量开始,和996(或992)个字节超越它。

由于指针堆栈的变量,它是印刷靠近堆顶部存储器的方式向下。该内存包含的堆栈帧的main():可能是一些保存的寄存器值,程序参数计数,一个指向程序参数,一个指向环境的列表变量和保存的指令寄存器的main()返回,通常在C运行时库启动code。在我已经研究了所有的实现中,堆栈帧下方具有自己的环境变量的副本,指针将它们的阵列,和指针数组的程序参数。在Unix环境(你提示你正在使用)程序参数字符串将低于

所有这些记忆的是安全的打印,除了一些非打印字符会出现可能搞砸了一个显示终端。

的主要潜在问题是是否有分配和访问数据时映射到prevent一个SIGSEGV足够的堆栈内存。 A 段故障的可能,如果有太少环境中的数据发生。或者如果实现把其他地方的数据,以便只有堆栈几个字在这里。我建议在确认通过清理出环境变量,并重新运行该程序。

这code也不会这么无害,如果任何C运行时约定是不正确的:


  • 该架构使用堆栈

  • 的局部变量(无效* X )在栈上分配

  • 的堆栈向低版本的内存

  • 的参数在栈上传递

  • 无论的main()被调用的参数。 (一些轻型的环境中,如嵌入式处理器,调用的main()不带参数。)

在所有的主流的现代实现方式中,所有这些都是通常真

A program accessing illegal pointer to pointer does not crash with SIGSEGV. This is not a good thing, but I’m wondering how this could be and how the process survived for many days in production. It is bewildering to me.

I have given this program a go in Windows, Linux, OpenVMS, and Mac OS and they have never complained.

#include <stdio.h>
#include <string.h>

void printx(void *rec) { // I know this should have been a **
    char str[1000];
    memcpy(str, rec, 1000);
    printf("%*.s\n", 1000, str);
    printf("Whoa..!! I have not crashed yet :-P");
}

int main(int argc, char **argv) {
    void *x = 0; // you could also say void *x = (void *)10;
    printx(&x);
}

解决方案

I am not surprised by the lack of a memory fault. The program is not dereferencing an uninitialized pointer. Instead, it is copying and printing the contents of memory beginning at a pointer variable, and the 996 (or 992) bytes beyond it.

Since the pointer is a stack variable, it is printing memory near the top of stack for a ways down. That memory contains the stack frame of main(): possibly some saved register values, a count of program arguments, a pointer to the program arguments, a pointer to a list of environment variables, and a saved instruction register for main() to return, usually in the C runtime library startup code. In all implementations I have investigated, the stack frames below that has copies of the environment variables themselves, an array of pointers to them, and an array of pointers to the program arguments. In Unix environments (which you hint you are using) the program argument strings will be below that.

All of this memory is "safe" to print, except some non-printable characters will appear which might mess up a display terminal.

The chief potential problem is whether there is enough stack memory allocated and mapped to prevent a SIGSEGV during access. A segment fault could happen if there is too little environment data. Or if the implementation puts that data elsewhere so that there are only a few words of stack here. I suggest confirming that by cleaning out the environment variables and re-running the program.

This code would not be so harmless if any of the C runtime conventions are not true:

  • The architecture uses a stack
  • A local variable (void *x) is allocated on the stack
  • The stack grows toward lower numbered memory
  • Parameters are passed on the stack
  • Whether main() is called with arguments. (Some light duty environments, like embedded processors, invoke main() without parameters.)

In all mainstream modern implementations, all of these are generally true.

这篇关于为什么一个程序访问非法指针的指针不会崩溃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆