VC++程序DEBUG调试时触发一个断点

最近刚接触MFC,在调试项目的时候,点击退出时总会触发一个断点,如果直接运行exe(无论是debug还是release)都没有问题。

 


设置断点发现是在GdiplusShutdown(m_pGdiToken);处触发的的断点。

basic::basic()
	{
		GdiplusStartup(&m_pGdiToken, &m_gdiplusStartupInput, NULL);
	}
	basic::~basic()
	{
		GdiplusShutdown(m_pGdiToken);
	}

查看相关代码始终没有找到,触发断点原因,相关代码如下:
 

bool ui::img_from_res(UINT nID, LPCTSTR sTR, Image * &pImg)
    {
        HINSTANCE hInst = AfxGetResourceHandle();
        HRSRC hRsrc = ::FindResource (hInst, MAKEINTRESOURCE(nID), sTR); // type
        if (!hRsrc)
            return false;
        // load resource into memory
        DWORD len = SizeofResource(hInst, hRsrc);
        BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
        if (!lpRsrc)
            return false;
        // Allocate global memory on which to create stream
        HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
        BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
        memcpy(pmem,lpRsrc,len);
        IStream* pstm;
        CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
        // load from stream
        pImg = Gdiplus::Image::FromStream(pstm);
        // free/release stuff
        GlobalUnlock(m_hMem);
        pstm->Release();
        FreeResource(lpRsrc);
        return true;
    }
DWORD ui::gifproc(LPVOID lpParam)
    {
        Image *img = (Image *)lpParam;
        UINT  nCount = img->GetFrameDimensionsCount();
        GUID* pDimensionsIDs = (GUID*)new GUID[nCount];
        img->GetFrameDimensionsList(pDimensionsIDs,nCount);
        wchar_t strGUID[39]={0};
        StringFromGUID2(pDimensionsIDs[0], strGUID, 39);
        UINT nFrameCount = img->GetFrameCount(&pDimensionsIDs[0]);
        delete[] pDimensionsIDs;
        
        int size = img->GetPropertyItemSize(PropertyTagFrameDelay);
        byte *p  = new byte[size];
        PropertyItem*  pItem = (PropertyItem*)p;
        img->GetPropertyItem(PropertyTagFrameDelay,size, pItem);
        
        int  fcount = 0;
        GUID guid  = FrameDimensionTime;
        HDC hDC = ::GetDC(m_gifwnd);
        Graphics gc(hDC);

        RECT rect = {0};
        GetClientRect(m_gifwnd, &rect);
        int x = (rect.right  - img->GetWidth()) / 2;
        int y = (rect.bottom - img->GetHeight()) / 2;

        while (m_gifruning)
        {            
            gc.DrawImage(img, x, y, img->GetWidth(), img->GetHeight());            
            img->SelectActiveFrame(&guid, fcount++);
            if (fcount == nFrameCount)
            {
                fcount = 0;
            }
            //long pause = ((long*)pItem->value)[fcount];
            //Sleep(pause);
        }
        ::ReleaseDC(m_gifwnd, hDC);
        delete []p;
        return 0;
    }
void ui::bitmap_ex(HDC hDC, HBITMAP hbitmap, int x, int y, int w, int h, int hv)
    {
        if (hDC != NULL && hbitmap != NULL)
        {
            if (hv == 0)
            {
                BITMAP bmp;            
                HDC hMM = CreateCompatibleDC(hDC);        
                GetObject(hbitmap, sizeof(BITMAP), &bmp);
                SelectObject(hMM, hbitmap);
                SetStretchBltMode(hDC, HALFTONE);
                StretchBlt(hDC, x, y, w, h, hMM, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);            
                DeleteObject(hbitmap);
                DeleteObject(hMM);
            }
            else
            {
                Graphics gr(hDC);
                Bitmap bitmap(hbitmap, NULL);
                if (hv == 1)
                {
                    Point HoPoints[] = {Point(x + w, y), Point(x, y), Point(x + w, y + h)};
                    gr.DrawImage(&bitmap, HoPoints, 3);
                }        
                else if (hv == 2)
                {
                    Point VePoints[] = {Point(x, y + h), Point(x + w, y + h), Point(x, y)};
                    gr.DrawImage(&bitmap, VePoints, 3);
                }
            }
        }
    }

求大神指点一下。

主程序退出前,确保子线程已经退出。否则可能存在资源冲突,比如主线程退出了,资源释放了,但子线程还在使用该资源

报错的地方是在mov附近,要么是数组越界了,要么是指针失效了,访问了不能访问的地址。在你代码中,指针失效后仍在使用的可能性是最大的。在MFC中,子窗口或者bitmap这些资源在绘制的时候,使用的是系统分配给程序的资源(如DC),所以在调用GdiplusShutdown前,需要确保已经释放这些资源(如bitmap* 、Gdiplus::Graphics),或者关闭子窗口(或者结束绘制过程)。因为实在析构函数中报错,所以直接运行exe的时候,错误可能不会提示。

现在排查到问题可能出在time_proc(HWND hwnd, UINT id, UINT_PTR, DWORD)函数,

void kernel::begin(HWND hwnd)
{	
	m_f2f = 0;
	m_mainwnd = hwnd;
	m_test = test_ready;
	if (!sqlite_open())
		::MessageBox(_kernel.m_mainwnd, "打开数据库失败", "信息", MB_OK);
	memset(&m_id, 0, sizeof(m_id));
	memset(&m_drive, 0, sizeof(m_drive));
	memset(&m_config, 0, sizeof(m_config));

	_kernel.sqlite_db("select * from config", &m_config);
	_kernel.sqlite_db("select * from through", &m_through);

	char buf[MAX_PATH] = {0};
	char sztime[MAX_PATH] = {0};
	basic::get_time(sztime);
	sztime[10] = '\0';
	sprintf(buf, "select * from student where time = '%s'", sztime);
	_kernel.sqlite_db(buf, &m_student);

	ui::gif(GetDesktopWindow(), IDR_LOADING, true);
	SetTimer(m_mainwnd, 1, 1000, time_proc);
	_kernel.m_tmain.begin(main_proc);
}

在调用GdiplusShutdown(m_pGdiToken);时可能有资源没有释放

void kernel::time_proc(HWND hwnd, UINT id, UINT_PTR, DWORD)
{
	if (_kernel.m_drive.idreadr && _kernel.m_drive.camera && _kernel.m_drive.network && _kernel.m_drive.gate)
	{
		KillTimer(hwnd, id);
		return;
	}
	HDC  hDC = ::GetDC(_kernel.m_mainwnd);		
	HBITMAP ha = LoadBitmap(AfxGetApp()->m_hInstance, (LPCSTR)IDB_A);
	HBITMAP hb = LoadBitmap(AfxGetApp()->m_hInstance, (LPCSTR)IDB_B);
	HBITMAP hc = LoadBitmap(AfxGetApp()->m_hInstance, (LPCSTR)IDB_C);
	HBITMAP hd = LoadBitmap(AfxGetApp()->m_hInstance, (LPCSTR)IDB_D);
	if (_kernel.m_drive.idreadr == false)
	{
		if (_kernel.m_id_readr.begin())
		{
			//读卡器已连接
			_kernel.m_drive.idreadr = true;			
			ui::bitmap(hDC, hc, 695, 25);
		}	
	}
	if (_kernel.m_drive.camera == false)
	{
		if (_kernel.m_face.begin(_kernel.m_mainwnd))
		{
			//摄像头已连接
			_kernel.m_drive.camera = true;
			ui::gif(GetDesktopWindow(), IDR_LOADING, false);
			ui::bitmap(hDC, hb, 645, 25);
			ShowWindow(_kernel.m_mainwnd, SW_SHOW);
		}
		else
		{
			_kernel.m_drive.camera = true;
			ui::gif(GetDesktopWindow(), IDR_LOADING, false);
			MessageBox(_kernel.m_mainwnd, "请插入授权USB锁,重启程序", "信息", MB_OK);			
			ShowWindow(_kernel.m_mainwnd, SW_SHOW);
		}
	}
	if (_kernel.m_drive.network == false)
	{
		//网络已连接
		if (_kernel.m_network.begin())
		{
			_kernel.m_drive.network = true;
			ui::bitmap(hDC, ha, 596, 25);
		}		
	}
	if (_kernel.m_drive.gate == false)
	{
		if (_kernel.m_com.open(atoi(_kernel.m_config.com), 9600, 8, NULL))
		{
			//闸机器已连接
			_kernel.m_drive.gate = true;
			ui::bitmap(hDC, hd, 746, 25);	
		}		
	}
	::DeleteObject(hd);
	::DeleteObject(hc);
	::DeleteObject(hb);
	::DeleteObject(ha);
	::ReleaseDC(_kernel.m_mainwnd, hDC);
}

请问这种情况怎么处理比较好?

您好,我是有问必答小助手,您的问题已经有小伙伴解答了,您看下是否解决,可以追评进行沟通哦~

如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~

ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>>https://vip.csdn.net/askvip?utm_source=1146287632