我正在编写一个小型实用程序(VC 2010,无 clr),它使用第 3 方库执行一项简单的任务(光栅化)。稍后的实用程序将被更大的应用程序使用。有时,该实用程序会因第 3 方库中的某些堆损坏而崩溃。没关系,但 Windows (Vista/2008) 显示众所周知的对话框“程序已停止工作...关闭/调试程序”。这不适合我的情况(服务器端)。实用程序应该静默地崩溃/终止,没有任何可见的影响。
为此,我为未处理的异常安装了 SEH (SetUnhandledExceptionFilter)。对于 AV ( *(PDWORD)0 = 0 ) 等异常,可以完美调用该处理程序,但由于某种原因,在堆损坏的情况下不会调用该处理程序。卸载第 3 方库 dll 之一的 dllmain 时发生损坏。
有几个问题。谁能解释为什么不调用处理程序?还有其他方法可以阻止该对话框吗?
我在 linux 上玩了很长时间的二进制开发,最近我正在写一些基于ptmalloc 的堆开发笔记,所以我回去查看我过去解决的安全挑战中的一些有效负载,令人惊讶的是他们没有不再工作了。
比如基本的double free corruption(不是fastbin)
char *chunk1 = malloc(0xc0);
free(chunk1);
free(chunk1);
Run Code Online (Sandbox Code Playgroud)
我希望看到类似的东西
*** Error in `main': double free or corruption (top): 0x0000000000c85010 ***
Run Code Online (Sandbox Code Playgroud)
但是没有,什么也没有发生,程序正常退出。
为此,我去检查了与我的机器相对应的 glibc 源代码Debian GLIBC 2.27-2
,发现malloc.c
.
void *
__libc_malloc (size_t bytes)
{
...
#if USE_TCACHE
/* int_free also calls request2size, be careful to not pad twice. */
size_t tbytes;
checked_request2size (bytes, tbytes);
size_t tc_idx = csize2tidx (tbytes);
MAYBE_INIT_TCACHE ();
DIAG_PUSH_NEEDS_COMMENT;
if (tc_idx < mp_.tcache_bins
/*&& tc_idx < TCACHE_MAX_BINS*/ /* …
Run Code Online (Sandbox Code Playgroud) int main()
{
char myString = NULL;
realloc(&myString, 5);
strncpy((char *)&myString, "test", 5);
}
Run Code Online (Sandbox Code Playgroud)
似乎工作正常,但我仍然有点困惑堆栈与堆,这是允许的吗?myString是否需要手动释放,还是在超出范围时释放?
编辑:感谢您的回复,所以我认为这同样是非法的
//I want the code to change myString to "tests"
char myString[5] = "test";
realloc(&myString, strlen(myString)+2);
myString[4] = 's';
myString[5] = '\0';
Run Code Online (Sandbox Code Playgroud) int main ()
{
int * b;
b = (int*) malloc (1);
*b=110000;
free (b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么堆腐败发生在free (b);
?
IMO,堆腐败已经发生在*b=110000;
.
我一生都无法弄清楚为什么会出现此调试错误:
检测到堆损坏:在 0x004cF6c0 处的正常块 (#126) 之后,CRT 检测到应用程序在堆 bugger 结束后写入内存。
我知道每当使用 new 运算符时都需要释放内存,我就是这样做的,但仍然遇到问题。
由于某种原因,程序无法在递归函数中正确结束。我对其进行了调试,并使用断点检查了每一行代码。
在 countSum 中 if 语句的末尾,它以某种方式从 i 中减去 1,然后重新进入 if 块......这是不应该做的。
为什么会出现这种情况?
/*this program calculates the sum of all the numbers in the array*/
#include <iostream>
#include <time.h>
using namespace std;
/*prototype*/
void countSum(int, int, int, int*);
int main(){
bool flag;
int num;
int sum = 0, j=0;
int *array = new int;
do{
system("cls");
cout<<"Enter a number into an array: ";
cin>>array[j];
cout<<"add another?(y/n):";
char choice;
cin>>choice; …
Run Code Online (Sandbox Code Playgroud) 阅读了这篇有趣的文章,概述了调试堆损坏的技术,我开始想知道如何根据自己的需要调整它.基本思想是提供一个自定义的malloc()来分配整个内存页面,然后为这些页面启用一些内存保护位,这样程序在写入时会崩溃,并且可以在行为中捕获有问题的写入指令.示例代码是Linux下的C(mprotect()用于启用保护),我很好奇如何将其应用于本机C++和Windows.VirtualAlloc()和/或VirtualProtect()看起来很有前途,但我不确定使用场景会是什么样子.
Fred *p = new Fred[100];
ProtectBuffer(p);
p[10] = Fred(); // like this to crash please
Run Code Online (Sandbox Code Playgroud)
我知道在Windows中存在用于调试内存损坏的专用工具,但我仍然很好奇是否可以使用这种方法"手动"执行此操作.
编辑:此外,这是一个在Windows下的好主意,还是只是一个有趣的智力练习?
我知道这个问题已被问到我无法修复我的程序
void swap1(char*str1,char*str2)
{
char *ezer =new char[strlen(str1)];
for (int i = 0 ; i <= strlen(str1);i++)
ezer[i]=str1[i];
delete [] str1;
str1= new char[strlen(str2)];
for (int i = 0 ; i <= strlen(str2);i++)
str1[i]=str2[i];
delete [] str2;
str2= new char[strlen(ezer)];
for (int i = 0 ; i <= strlen(ezer);i++)
str2[i]=ezer[i];
delete[] ezer;
}
Run Code Online (Sandbox Code Playgroud)
有一次第一次它的工作蝙蝠在第二次(有其他值)时间我得到一个错误错误来自最后一行delete[] ezer;
为什么我不能删除ezer
?
错误:
heap corruption detected after normal block (#174) at 0x007D7A48
CRT detected that the application wrote to memory end of heap …
Run Code Online (Sandbox Code Playgroud) 我一直在delete []指令上遇到堆损坏错误.项目是在VC++ 2008中进行的,其要求是(所以请不要关注它).整个构建过程运行正常,但在运行时我得到错误:(prs_2013是我的项目的名称)
Windows已在prs_2013.exe中触发了断点.
这可能是由于堆的损坏,这表示prs_2013.exe或它已加载的任何DLL中的错误.
这也可能是由于用户在prs_2013.exe具有焦点时按下F12.
输出窗口可能包含更多诊断信息.
这是发生错误的代码,它只是整个项目的一小部分,但错误仅限于此区域:
// Function used for swapping row of matrix with new values
void Main::swap(double* matrix, double* row, unsigned index, unsigned size){
double temp = 0;
for(unsigned i = 0; i < size; i++){
temp = matrix[i*size + index];
matrix[i*size + index] = row[i];
row[i] = temp;
}
}
// Function that do some calculations, not really relevant for this problem
// but still used in code
double Main::determinat(double* matrix, unsigned size){
double ud …
Run Code Online (Sandbox Code Playgroud) 我最近在阅读C&C++中的堆栈和堆损坏.该网站的作者使用以下示例演示了堆栈损坏.
#include<stdio.h>
int main(void)
{
int b = 10;
int a[3];
a[0] = 1;
a[1] = 2;
a[2] = 3;
printf(" b = %d \n",b);
a[3] = 12; // oops it is invalid, behaviour is undefined
printf(" b = %d \n",b);
printf("address of b= %x\n",&b);
printf("address of a[3]= %x\n",&a[3]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在visual studio 2010编译器(VC++)上测试了上面的程序,它给了我运行时错误,说:
变量a周围的堆栈被破坏了
现在我的问题是:堆栈是否已终生损坏,或者仅在上述错误程序执行期间?
同样,我知道两次删除相同的指针可能会造成堆损坏等非常糟糕的事情.以下代码:
int* p=new int();
delete p;
delete p; // oops disaster here, undefined behaviour
Run Code Online (Sandbox Code Playgroud)
当上面的代码片段执行时,VC++在运行时显示堆损坏错误.
我是 C++ 的新手,正在尝试一些东西。所以最近我尝试在堆上创建一个 int 数组,并使用寻址方式迭代它,而不是使用 [x] 的标准方式。
每次我执行我的代码时,我都会收到一个堆损坏错误。我尝试了几件事(也在 stackoverflow 上搜索过)但找不到任何答案。
int* p = new int[5];
for (int i = 0; i <= 4; i++){
/*p[i] = i;
cout << p[i] << endl;*/ //This is the standard way and works
*p = i;
cout << *p << endl;
p = (p + sizeof(*p)); //iterate the pointer through the heap addresses
}
delete[] p;
Run Code Online (Sandbox Code Playgroud)
应用程序运行并向我显示填充的数组值 {0,1,2,3,4} 但随后崩溃。
我收到以下错误消息:
检测到堆损坏:在 0x00C31B68 处的 CRT 块(#225)之后。CRT 检测到应用程序在堆缓冲区结束后写入内存...
提前致谢