以下问题是从一个庞大的项目中提炼出来的,这是我能够提出的最小问题的例子.
我知道,源于std::string它是坏的,它已经在我们的代码库中发生了变化,但我试图了解这里发生的事情.
代码在Visual C++ 2017上崩溃
Microsoft Visual Studio Community 2017
Version 15.2 (26430.14) Release
Visual C++ 2017 00369-60000-00001-AA257
Run Code Online (Sandbox Code Playgroud)
仅在发布模式下(具有速度优化).没有速度优化,它不会在发布模式下崩溃.
#include <string>
#include <string_view>
#include <vector>
struct my_string : public std::string
{
__declspec(noinline)
my_string::my_string( const std::string_view& str ) :
std::string( str.data(), str.size() )
{}
template <typename T>
my_string& arg( T )
{
return *this;
}
};
struct my_string_view : public std::string_view
{
my_string_view( const std::string_view::value_type* val ) :
std::string_view( val ) {}
template <typename... PARAMS>
my_string arg( PARAMS&&... prms …Run Code Online (Sandbox Code Playgroud) 我最近收到了一位用户抱怨我的应用程序崩溃了.我从用户的错误日志中提取了以下内容,并且能够看到发生问题的原因:
12-17 10:31:12.446 I/PLAYLIST( 3158): PreparePlaylist
12-17 10:31:12.446 I/PLAYLIST( 3158): URL: http://f69cbd7a-3d91-4bf5-b4c6-ddb1175cf9e9.d40f2093-2013-4ad9-aec2-e99b015d61ca.070305e7-a706-4626-9ecb-777835065841.groovera.com/listen.pls
12-17 10:31:12.456 F/unknown ( 3158): stack corruption detected: aborted
12-17 10:31:12.466 D/Zygote ( 2204): Process 3158 terminated by signal (6)
12-17 10:31:12.471 I/ActivityManager( 2256): Process com.android.Player:remote (pid 3158) has died.
Run Code Online (Sandbox Code Playgroud)
检测到堆栈损坏.很好,所以我怎么知道为什么会这样?
我认为这个问题正在这个特定的类中发生,因为我希望在它死之前有更多的日志输出.此类使用套接字下载播放列表并解析它.我怎么能破坏堆栈?我已经处理过C/C++中的堆栈溢出,但是我如何在Java中处理它?
谢谢你的帮助!
我见过这个帖子.我的情况略有不同,我正在努力弄清楚"this"指针是如何被破坏的.
我正在使用Qt 4.6.2框架,使用他们QTreeView自己的模型.我得到的回溯(86帧长,有很多递归,这就是为什么我没有粘贴整个东西,它在这个pastebin中只涉及他们的代码.
它最终在QBasicAtomicInt :: deref中对一些汇编程序进行了段错误,但很明显它已经进一步消亡,这三个框架证明了这一点:
#15 0x01420fd3 in QFrame::event (this=0x942bba0, e=0xbf8eb624) at widgets/qframe.cpp:557
#16 0x014bb382 in QAbstractScrollArea::viewportEvent (this=0x4, e=0x93f9240) at widgets/qabstractscrollarea.cpp:1036
#17 0x0156fbd7 in QAbstractItemView::viewportEvent (this=0x942bba0, event=0xbf8eb624) at itemviews/qabstractitemview.cpp:1610
Run Code Online (Sandbox Code Playgroud)
在第17帧中,this是0x942bb0.在第16帧中,this应该是相同的,如在第17帧中它调用它的祖先的相同方法的实现.但是this变成0x4.
有趣的是在第15帧(同样,第16帧已经调用其祖先的相同函数的实现),'this'指针被恢复为0x942bba0.
如果您查看完整回溯的pastebin,您可能会看到一些"值优化输出".我已经使用优化编译了应用程序; 我现在已经设置了gcc,-g3 -O0所以下次我可能会有更多的东西.但是当然现在我不能让它崩溃 - 这是一个相当困难的错误(尽管如此仍然非常重要)所以我不认为这太可疑了.
鉴于优化,是this pointer=0x4不寻常或绝对错误?奇怪的是,在任何这些viewportEvent帧中都没有真正的代码 - 它们只是对事件的类型进行切换,它通过switch语句,并返回其祖先的实现.
Valgrind似乎没有抛出任何问题,尽管我还没有让它在Valgrind中崩溃.
以前有人见过这种行为吗?可能是什么原因造成的?
现在我正在调试一个大型项目,它有一个堆栈损坏:应用程序失败.
我想知道如何使用Visual Studio 2010查找(调试)此类堆栈损坏代码?
下面是一些导致堆栈问题的代码示例,我如何找到这种类型腐败的不太明显的案例?
void foo()
{
int i = 10;
int *p = &i;
p[-2] = 100;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这只是一个例子.我需要在当前项目中找到这样的错误代码.
我正在尝试在 linux(ARM 架构)上运行应用程序时调试段错误。我复制了核心转储文件并尝试在 x86_64 主机上使用 arm-gdb 获取回溯。这是o/p:
$ arm-arago-linux-gnueabi-gdb test_slave6_slave core
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-oesdk-linux --target=arm-oe-linux-gnueabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dvdk/test_slave6_slave...done.
warning: …Run Code Online (Sandbox Code Playgroud) 我一直在研究一堆图像处理程序......没什么特别的,大多是快速和肮脏的实验.图像数据存储在堆栈中声明的向量中(当我不需要传递数据时,我尽量避免使用指针).我注意到,尽管进行了无数的调试和步进,我的一些功能仍然表现得非常奇怪.有时调试器会给我一个错误,它无法评估某个变量等等.事情通常没有意义,过去的经验告诉我,当这发生时,这意味着存在某种溢出或内存损坏.首先想到的是,这可能是由于我将大量图像数据存储到矢量中.
但是,我的印象是向量将它们的实际数据存储在堆中,所以我认为在堆栈中有一些这样的大向量不会有什么坏处.这是错误的吗?我应该分配我的向量并将它们存储在堆而不是堆栈中吗?
谢谢,
我已使用以下代码禁用了行输入:
DWORD dwConsoleMode;
GetConsoleMode(hStdIn, &dwConsoleMode);
dwConsoleMode ^= ENABLE_LINE_INPUT;
SetConsoleMode(hStdIn, dwConsoleMode);
Run Code Online (Sandbox Code Playgroud)
然后我在循环中调用ReadConsole ...在循环中:
wchar_t cBuf;
while (1) {
/* Display Options */
do {
ReadConsole(hStdIn, &cBuf, 1, &dwNumRead, NULL);
} while (!iswdigit(cBuf));
putwchar(cBuf);
if (cBuf == L'0') break;
}
Run Code Online (Sandbox Code Playgroud)
如果我运行程序并立即按0,它就会干净利落地存在.
但是,如果我按下一串键,然后按0,当程序存在时,它会崩溃:
运行时检查失败#2 - 变量'cBuf'周围的堆栈已损坏.
为什么这会导致堆栈损坏?代码很简单,所以我无法弄清楚出了什么问题.
我可以通过以下方式重现问题的小程序:
#include <windows.h>
#include <stdio.h>
int wmain(int argc, wchar_t *argv[])
{
DWORD dwNumRead;
wchar_t cBuf;
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
DWORD dwConsoleMode;
GetConsoleMode(hStdIn, &dwConsoleMode);
dwConsoleMode ^= ENABLE_LINE_INPUT;
SetConsoleMode(hStdIn, dwConsoleMode);
while (true)
{
wprintf(L"\nEnter option: ");
do { …Run Code Online (Sandbox Code Playgroud) 什么是调试堆栈值损坏的好方法。在我的程序中,有时在返回对文件描述符进行关闭的方法后,此指针的地址会更改。我调试了几个小时的程序,但找不到问题。
找出改变此指针地址的有效方法是什么?当我在此指针上手动添加监视时,不会发生错误。当我尽可能减少代码时,仍然会发生错误。我尝试了Valgrind,但未发现任何早期堆栈损坏。
我设法检测到何时发生错误,我以64位模式编译了代码。此地址从0xxxxxxx更改为0x1000000xxxxxxx。我在发生错误的方法中检查了这个地址,发现了地址更改的时间(有关此信息,请参见第一个段落)。
还有其他方法可以找出造成此问题的原因吗?
我需要在C++中实现矩阵转置过程.问题是签名,函数必须像这样调用:
transpose(in_mat[0][0], n, m, out_mat[0][0])
Run Code Online (Sandbox Code Playgroud)
其中n和m是尺寸.所有值都是双精度,包括矩阵和维数.
由于代码是自动生成的,我无法解决这个问题.
我的解决方法如下所示:
void transpose(double& in_mat, const double _n, const double _m, double& out_mat)
{
int n = _n, m = _m;
double* in_pointer= &in_mat;
double* out_pointer= &out_mat;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
*(out_pointer+(j*n+i)) = *(in_pointer+(i*m + j));
}
}
}
Run Code Online (Sandbox Code Playgroud)
它工作正常.我构建了一个测试用例,其中包含两个不同宽度和高度的矩阵.一个用随机数填充,另一个用零填充.然后调用转置过程并比较两个矩阵.功能是正确的.
但它破坏了堆栈.在Visual Studio 2015中运行时会出现警告
运行时检查失败#2 - 变量'in_mat'周围的堆栈已损坏.
我做错了什么 ?为什么堆栈已损坏?转置调用后的代码正常工作.
编辑:
这是完整的设置:
#include <random>
#include <iostream>
void transpose(double& in_mat, const …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++在运行时显示堆损坏错误.