- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的项目广泛使用 SDL2-2.0.8 来显示来自各种科学成像相机的数据帧。我的实际项目使用的是 wxWidgets 3.1.1 和 SDL_CreateWindowFrom(xid),而不是 SDL_CreateWindow()。
我最近开始使用 AddressSanitizer 来帮助调试我的应用程序并查找可能的内存泄漏(Valgrind 对我的应用程序来说太慢了)。 AddressSanitizer 通知我存在严重的内存泄漏,我正在努力修复。下面是一个独立的完全可编译的例子,它说明了我的问题。
#include <iostream>
#include <unistd.h>
#include <random>
#include <SDL2/SDL.h>
int main()
{
SDL_Window *window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_Texture *texture = nullptr;
uint8_t *pixels = new uint8_t[640 * 480 * 3];
// Random Numbers
std::mt19937 rng;
rng.seed(std::random_device()());
std::uniform_int_distribution<std::mt19937::result_type> random(0, 255);
int pitch;
if ((window = SDL_CreateWindow("Test", 0, 0, 640, 480, 0)) == nullptr)
{
std::cerr << SDL_GetError() << "\n";
return -1;
}
if ((renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED)) == nullptr)
{
std::cerr << SDL_GetError() << "\n";
return -1;
}
// Create the SDL Texture
if ((texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, 640, 480)) == nullptr)
{
std::cerr << SDL_GetError() << "\n";
return -1;
}
int counter = 0;
while (counter < 500)
{
SDL_LockTexture(texture, nullptr, (void**) &pixels, &pitch);
// Create greyscale noise - a bit like old television sets without an antenna
for (int n = 0; n < 640 * 480 * 3; n += 3)
{
int random_pix = random(rng);
pixels[n] = random_pix;
pixels[n + 1] = random_pix;
pixels[n + 2] = random_pix;
}
SDL_UnlockTexture(texture);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
counter++;
}
// If the following line is uncommented and delete [] pixels commented, then I get a double-free in SDL
//free(pixels);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
// This line causes a double-free error, if it's commented out then I get a memory leak of 921600 bytes
delete[] pixels;
atexit(SDL_Quit);
return 0;
}
似乎 SDL 正在尝试取消分配分配给我的像素缓冲区的内存,但失败并导致内存泄漏。有趣的是,如果我使用:
SDL_UpdateTexture(texture, NULL, pixels, m_Width * 3);
然后我可以自己释放像素,从而修复内存泄漏。有人知道发生了什么事吗?这仅仅是 AddressSanitizer 的误报吗?
更多信息:我的项目是用 C++ 编写的,并在 Fedora 28 上使用 GCC-8 编译。AddressSanitizer 来自标准 Fedora 存储库。我知道你们中的许多人会认为我应该使用智能指针,但这样做需要对我的项目进行重大重构,而我根本没有时间。
非常感谢阅读,我感谢提供的任何帮助。
阿曼达
最佳答案
请注意 SDL_LockTexture()
的签名采用指向指针的指针。这暗示您不应该传递自己的缓冲区。您正在泄漏,因为 SDL_LockTexture()
正在更改您正在传递的 address 指针的值以指向它自己的内部缓冲区,现在您无法删除您的(无用的)分配缓冲。显然,双重释放正在发生,因为您正在删除一个不属于您的缓冲区,该缓冲区在您调用 SDL_DestroyTexture()
时已经被释放(可能,我不确定确切的实现)。
另请注意,数据实际上可能不是您期望的格式。 SDL_CreateTexture()
随意忽略你的建议,给你后端支持的“最接近”的匹配格式。您需要查询纹理的实际格式才能知道如何处理像素。
如评论中所述:如果您想以自己的格式提供自己的像素,则必须使用 SDL_UpdateTexture()
,但这当然会慢得多。
关于地址清理器的注释:它不会产生误报。如果它报告了一个问题,那么您确实遇到了问题。
关于c++ - SDL_LockTexture()/AddressSanitizer/双免,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51918664/
所以我正在使用 AddressSanitizer。但是在描述问题时它使用了一些密集的术语。 Shadow bytes around the buggy address: 0x0c067fff7fb
想要抑制 AddressSanitizer 检测到的以下错误。 ==114064==ERROR: AddressSanitizer: stack-use-after-scope on address
我试图抑制 clang/gcc 中地址清理程序发出的警告 我的源文件如下所示: int foo(){ double bar[] = {7,8}; return bar[3]; } int ma
我有一个管理容器的类。我的 insert-a-value 函数返回一个对象,其析构函数删除了插入的值。这个想法是我可以在容器中注册一个值,保存结果 Registration对象,然后让该对象超出范围以
我这样编译代码来启用 Asan: g++ -O0 -g -fsanitize=address -fno-omit-frame-pointer 但它永远不会生成核心转储,以便我稍后可以检查错误的详细信息
似乎 AddressSanitizer 检测到 heap-buffer-overflow 但输出不那么清晰,例如 here . 如何获取发生溢出的行? 我该如何解释这个结果? [1m[31m==274
我的项目广泛使用 SDL2-2.0.8 来显示来自各种科学成像相机的数据帧。我的实际项目使用的是 wxWidgets 3.1.1 和 SDL_CreateWindowFrom(xid),而不是 SDL
我正在开发一个 C++ cmake 项目。除了我自己的源代码外,我的项目还使用了很多第三方库。因此,我正在使用/usr/local/lib 中存在的共享库(带有 .so 扩展名),对于某些代码,它们存
我最近开始使用 XCode AddressSanitizer,我认为它是在 XCode 7 中引入的(参见例如 Apple WWDC presentation ),以帮助解决难以发现的奇怪错误。 sa
以下代码计算两个相邻元素之间的最大气体。输入 vector 未排序。 class Solution { public: int maximumGap(vector& nums) { int m
我试图让 ASAN 使用一个程序,但我所做的任何事情都会导致 ASAN:DEADLYSIGNAL ,所以我尝试缩小范围并使用只有几个编译器选项的小型测试程序,只是为了看看它是否可以工作: $ cat
我应该使用哪些 Asan 标志来检测更多错误?目前,我使用 ASAN_OPTIONS=detect_stack_use_after_return=1 . 最佳答案 来自 Asan FAQ : Q: C
为了能够对整个 Linux 发行版进行调试和模糊测试,我想将 ASAN(AddressSanitizer,https://en.wikipedia.org/wiki/AddressSanitizer)
我正在查看我的一个守护进程的问题,它非常耗费内存。看起来某些部分永远不会释放内存,即使当我让那个守护进程干净地退出时,也没有泄漏。 我想看看在守护进程运行时添加和保留了哪些缓冲区。由于我已经使用 -f
AddressSanitizer 默认情况下会将所有错误抛给 shell 本身,因此我尝试使用以下命令运行我的 ASAN 构建; >MCTester_ASAN>asan.log ==15619==ER
我在所有项目中都使用 AddressSanitizer 来检测内存泄漏、堆损坏等。但是,在运行时通过 dlopen 加载动态库时,AddressSanitizer 的输出有很多不足之处。我写了一个简单
AddressSanitizer 和 MemorySanitizer 是非常有用的工具,但它们需要对整个程序进行适当的检测。 (至少,对于 AddressSanitizer 的 Clang 版本;请参
我有几个版本的项目结帐和编译。如果我发现错误,我会比较版本以缩小问题范围。有时我会启用像 AddressSanitizer 这样的 sanitizer 。如果我重新使用一个可执行文件,我不记得它是否是
我有一个自定义 assert() - 类似宏调用 abort()失败。使用 AddressSanitizer 时,我更喜欢在断言失败时打印通常的漂亮堆栈跟踪。如何做到这一点? 是否可以在 abort(
或者我必须使用单独的版本吗? -fsanitize 标志仅允许地址或线程,但是否允许多个? 问候 最佳答案 不,不可能将 AddressSanitizer 和 ThreadSanitizer 组合到一
我是一名优秀的程序员,十分优秀!