确保程序在运行时出错时在 C++/fortran 中的适当位置崩溃
Ensure that program crash on runtime error at proper place in C++/fortran
简而言之:
是否有一些通用且可靠的方法来确保程序总是在一些坏事发生的地方崩溃(例如写入不属于我的内存(?
例如,一些像-Og -g -fbounds-check
这样的gcc flags
...?
( 或 g++
/gfortran
(
更长的解释:
我想避免的真实例子:
通常,当我遇到运行时错误时,我会像printf("DEBUG %i n", 15 );
一样将一堆编号的调试消息写入代码中,以查看它到底在哪里崩溃(在 Java 中它运行良好(。
但是最近我错误地通过一段功能类似于以下内容的代码在分配的数组之外编写:
int ny = 6;
int nz = 60;
zs = new double[ny];
for(int i=0; i<nz; i++){
zs[i] = i/(double)nz;
}
然而,这个错误并没有立即触发分割错误,而是表现为在完全不相关的地方memory corruption
(20行后调用的不同对象的内部方法,即在鼠标处理芦丁SDL_pollEvent()
(。
完全无法理解鼠标处理如何与我正在处理的代码部分(该数组的初始化(联系起来。所以我花了很长时间才找到它。
我还尝试使用gdb
,调试器Code::Blocks
甚至Valgrind
来查找错误(即使我不太熟悉它的用法(...但他们都表明内存损坏发生在SDL_pollEvent()
前段时间我在 fortran 上遇到了类似的问题(不确定是ifort
还是gfortran
(
在Fortran中,至少使用数组边界检查和指针检查(-fcheck=all
,请参阅 https://gcc.gnu.org/onlinedocs/gfortran/Code-Gen-Options.html(。它不是全能的,但可以经常拯救你。特别是,它能够诊断您在示例中遇到的那种错误。它还可以诊断,当您仍在正确的缓冲区内,但您在其中一个维度中关闭,如
allocate(a(10,10))
...
x = a(11,1)
C(动态(数组通常不能那么容易地检查,因为它们只是一个地址。您可以对 C 和 Fortran 使用清理,但它们更昂贵。它是由 fsanitize=...
启用的,请参阅编译器手册以了解所有可能性,没有像 -fcheck
那样=all
。
不,您无法确保程序可靠且一致地崩溃。C++ 不要求代码显式检查导致未定义行为的操作,因此结果是完全不可预测的。当您导致内存损坏时,它可以位于进程内存中的任何位置。这是否以及何时导致崩溃取决于你损坏的内存中碰巧是什么,以及它稍后在程序中的使用方式。
在C++中,最好的办法是避免使用低级的C式数组和指针,而使用高级数据结构,如std::vector
、std::string
、std::shared_ptr
等。
一般来说,没有。C++程序只有在调用未定义的行为时才会崩溃,这意味着任何事情都可能发生 - 包括忽略您可能碰巧添加的任何诊断。
(对不起,不能帮助Fortran。
- 当回溯以零开始时,如何调试崩溃
- 将值指定给向量(2D)的向量中的某个位置
- 使用Unreal C++获取VR耳机的世界位置/方向
- 写入位置0x0000000C时发生访问冲突
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 程序崩溃并显示"std::out_of_range"错误
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 使用向量的函数崩溃,调试器说访问冲突读取位置
- 程序的守护程序版本崩溃时的查找位置
- 如何找到检测到 Cuda API 错误时程序崩溃的位置:cudaMemcpy 返回 (0xb)
- 确保程序在运行时出错时在 C++/fortran 中的适当位置崩溃
- MEMCPY 后崩溃:访问冲突读取位置
- 使用"CS:EIP 上的字节数"找出崩溃发生的位置
- 确定应用程序崩溃的确切位置
- 调用MiniDumpWriteDump()以捕获崩溃的最佳位置
- 如何轻松地找出程序崩溃的位置和原因
- 通过WinAPI套接字连接到蓝牙设备时崩溃(读取位置0x00000004时发生访问冲突)
- PageHeap 不显示确切的崩溃位置