Отладка в Visual Studio без файлов Pdb (Voilation доступа к C++ )
Я построил двоичные файлы OpenCV(.dll) с помощью Cmake и visual studio, которые сгенерированы .pdb-файл, который помог мне найти проблему в коде (частично!)
как вызвана эта авария. .
Я использую программное обеспечение, с помощью которого мы можем установить ограничение скорости загрузки интернета (скорость передачи) для любой конкретной программы.
теперь, если я подключу IP-камеру к приведенному ниже коду, я заметил, что моему приложению требуется около 100 кб / с использования интернета ( скорость передачи) - только тогда я могу смотреть прямую трансляцию без проблем. Скажем, я сократил (установил) использование интернета в приложении до 10Kb/s [это причина аварии] в этом случае я должен иметь возможность видеть новый кадр один раз в 4+ секунды.
Я получаю ошибку нарушения доступа, вероятно, потому что (cap>>img;
) cap пытается достичь местоположения в ОЗУ и получить кадр, но пока нет кадра, потому что его все еще загружают из-за низкой скорости интернета.
Ясно, что указатель достигает некоторых расположение в ОЗУ, чтобы захватить кадр, которого еще нет.
интересное поведение . . .
Void OpenCamera()
{
VideoCapture cap("http://192.168.1.3:8080/video?x.xmjpeg");
Mat img;
while(true)
{
try
{
if(cap.isOpened()) //also tried grab + retrieve, crashes at grab
cap>>img; //code crashes here
}
catch(...)
{
cout<<"Camera Disconnected"<<endl;
}
}
}
если я использую весь код в том же классе (в том же файле заголовка), нет никаких проблем вообще(новый кадр отображается через 4+ секунды без сбоя программы), но если я помещаю код в отдельный класс(другой файл заголовка), то вызовите функцию, чтобы открыть камеру из объекта класса, то он вылетает если интернет скорость снижается.
странное поведение - если я отлаживать шаг за шагом, он никогда не падает!
когда я создаю библиотеку opencv с ffmpeg, я получаю .pdb файл только для opencv (opencv_world310.pdb) - поэтому нет проблем с отладкой с помощью стека вызовов но я не получаю pdb для ffmpeg (потому что Opencv_ffmpeg.dll предварительно скомпилирована, и именно там ее сбой)
следовательно, его становится трудно отлаживать, здание ffmpeg не производит pdb-файл, потому что он построен с использованием Префикса msys
Итак, можно ли отлаживать то, что у нас есть?
Я включаю снимок из отладки visual studio, некоторые из переменных, которые помогут в понимании:
typedef int (*CvGrabFrame_Plugin)( void* capture_handle ); [cap_ffmpeg_api.cpp]
protected: void* ffmpegCapture; [cap_ffmpeg.cpp]
static CvGrabFrame_Plugin icvGrabFrame_FFMPEG_p = 0; [cap_ffmpeg.cpp]
исключение в 0x0A0AF6F0 (opencv_ffmpeg310.dll) в образце.исполняемый: 0xC0000005: место чтения нарушения доступа 0x00000020. Если есть обработчик этого исключения, программа может быть безопасно продолженный.
в исходном коде я включил ниже строки и скомпилировал и использовал его в проекте - не работал, снова разбился!
if(ffmpegCapture)
- проверка нулевого указателя
можем ли мы внести некоторые изменения в строку 214 в [cap_ffmpeg.cpp] чтобы избежать аварии?
другие заголовочные файлы - это только одна папка.
обновление: я заметил, что программа падает сразу, когда я ограничиваю скорость потребления интернета. Я использую C++ / Cli(winforms, target dot net Framework = 4.6), у меня есть CameraClass (в отдельном файле заголовка) и основная функция (отдельный файл заголовка)
основная функция ниже код
CameraClass ^CC = gcnew CameraClass();
CC->OpenCamera();
Я не могу создать тип неуправляемого объекта в управляемом классе, поэтому я помещаю собственные типы (переменные Opencv) в отдельное пространство имен, как показано ниже, чтобы я мог использовать в этом классе. возможно, мне придется использовать внутренние указатели?
#pragma once
#include"opencv2opencv.hpp"
#include <msclrmarshal_cppstd.h>
namespace SampleApp{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;
using namespace System::IO;
using namespace std;
namespace
{
cv::VideoCapture cap[5]; //max 5 instance for this class
cv::Mat image[5];
cv::IplImage pic1[5];
cv::IplImage *pic2[5];
}
public ref class CamWindow : public WeifenLuo::WinFormsUI::Docking::DockContent
{
public: CamWindow(void)
{
InitializeComponent();
}
Void OpenCamera()
{
}
.
.
.
.
};
}
определенно столкновение между обработкой памяти .net и памятью c++ обращение?
1 ответов
можно объявить неуправляемый класс. Есть указатель на него из управляемого класса.
public class OpenCVClass
{
public:
Void OpenCamera()
{
VideoCapture cap("http://192.168.1.3:8080/video?x.xmjpeg");
Mat img;
while(true)
{
try
{
if(cap.isOpened())
cap>>img;
}
catch(...)
{
cout<<"Camera Disconnected"<<endl;
}
}
}
public ref class managed
{
public:
managed(){}
~managed(){}
static OpenCVClass* unmanaged = new OpenCVClass();
unmanaged->OpenCVClass();
};
}
Если dll была построена на MSYS, вы можете использовать команда addr2line чтобы преобразовать адрес внутри DLL в исходную строку или использовать неуправляемую переменную в функции управляемого класса.