I'm writing a C++ MFC program on VS2008 and I'm getting this "Debug Assertion Error" when I first run the program sometimes. When I try to debug it, it takes me to this winhand.cpp file which is not part of the program I wrote so I'm not sure how to debug this.
It takes the error to this place in winhand.cpp
CObject* pTemp = LookupTemporary(h);
if (pTemp != NULL)
{
// temporary objects must have correct handle values
HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset); // after CObject
ASSERT(ph[0] == h || ph[0] == NULL);
if (m_nHandles == 2)
ASSERT(ph[1] == h);
}
So why does this error happen? Why does it only happen sometimes (50% of the time)? How would I debug this?
I'll provide some code if is needed.
THANKS!
The code that is asserting is part of MFC's CHandleMap class. MFC deals with windows as CWnd objects, but Windows deals with them as HWND handles. the handle map allows MFC to 'convert' an HWND into a pointer to the MFC object representing that object.
What the assertion seems to be doing is checking that when a lookup of the handle finds an MFC object, that the MFC object also thinks it's wrapping the same handle.
If they're different, then you get the assertion.
So it would appear that something is corrupting the handle map or the MFC object for that handle or you're doing something incorrect that gets these 2 data structures out of sync.
Some things you might do to try to debug the problem is to determine:
what MFC object is being found in the lookup (that's what's being pointed to by pObject)
what the MFC object thinks it's wrapping (that's the handle ph[0] and/or ph[1] - I'm not sure why there can be 2 of them)
what the handle is for (that's h)
Do the handles look like handle values or do they look like garbage? Does pObject point to something that looks like an MFC object, or garbage? Do any of these these things seem related?
The answers to these questions may point to what you need to do next (maybe set a debug write breakpoint on the item that looks like it's trashed).
I got this same assertion few days ago, and after some google search,
I found the solution for my case here:
http://forums.codeguru.com/showthread.php?216770-What-would-cause-this-assertion
In my case, change to misused
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
dc->DeleteDC();
to
CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
ReleaseDC(dc);
would fix it.
Look out for code along those lines (from memory from Stroustrup's book):
c1 = (t2+t3).c_str();
(in spirit, could be other commands and expressions of course).Temporary objects are destroyed after their enclosing full expression has been evaluated, or at least the standard allows them to be. That means that what you would like to allocate to c1 may, or may not, still be in memory where it can be assigned to c1. The compiler may alert you to this issue, and the issue may or may not arise depending on what exactly you assign and other circumstances (I am not compiler writer), which would also explain why you get this error message only sometimes.
So in your shoes, I'd scan my code for similar expressions and clean them up.
When the debugger breaks, head up the call stack to the first bit of your code (if there is any - hopefully there is!). Ideally it's as simple as something in your code calling a library function incorrectly, and the library is catching the error with an assert and alerting you to that. (I don't think anyone will be able to tell what's wrong from the library code, we need to see your code.)
Otherwise, you're in for some tricky debugging: you're doing something wrong with the library that is asserting (looks like MFC) so go back and review all your MFC code and make sure everything is correct and according to the documentation.
This looks suspiciously like an error I had this morning. Is this happening in OnIdle()?
I know this is a very old post, but hoping that someone may get a little help from my answer.
I also faced a similar issue recently because of my simple mistake, then I came across this post and got a hint from "pac"'s post.
What I found is that if I use DeleteDC() to release DC returned from GetWindowDC() or GetDC() I will get the above assertion in MFC frame once CPaintDC object instance goes out of scope.
CDC * pDC = GetWindowDC();
...
ReleaseDC(pDC);
You have to use DeleteDC() only in conjunction with CreateDC() API.
CDC * pDC = new CDC();
pDC->CreateDC();
....
pDC->DeleteDC();
We had this problem when some of our project dlls were linking MFC as static library and some as shared library (check "Use of MFC" in Project settings)
Related
I've seen similar questions but none satisfies my scenario.
I am fixing a GDI Objects leak on a C++ Windows Form Application.
This is the Exception it throws:
A generic error occurred in GDI+. at System.Drawing.Bitmap.GetHicon()
This is the GetHicon call at the line where the crash happens:
this->notifyIcon1->Icon=Icon->FromHandle(((Bitmap^)imgsApp->Images[0])->GetHicon());
After doing some reading here, and on https://learn.microsoft.com/en-us/dotnet/api/system.drawing.icon.fromhandle?view=net-5.0, I see I need to call DestroyIcon() in order to release the Icon Handle (not sure if the wording is correct here), but I am having trouble doing this not being familiar with Windows Form.
Try this:
IntPtr iconHandle = ((Bitmap^)imgsApp->Images[0])->GetHicon();
Icon ^newIcon = Icon::FromHandle(iconHandle);
this->notifyIcon1->Icon = (Icon^) newIcon->Clone();
newIcon->Dispose();
DestroyIcon((HICON)iconHandle.ToPointer());
Per Icon.FromHandle: should I Dispose it, or call DestroyIcon?:
Conclusion: After Icon.FromHandle, the field ownHandle is false, and thus Dispose / FromHandle won't call DestroyIcon
Therefore: if you create an Icon using Icon.FromHandle you'll have to Dispose() the Icon as well as call DestroyIcon, just as the remarks section says
This question was asked in similar ways multiple times, for example at stackoverflow or forum.qt.io or qtcentre.org. The problem is that this error message is so vague that one solution cannot be applied to another scenario. Most of the threads are dead in the middle of the discussion though :-(
So the complete error message that I get in my Qt application is:
can't find linker symbol for virtual table for "OneOfMyClasses" value
found "QString::shared_null" instead
The OneOfMyClasses changes depending on various things, the QString::shared_null stays the same for all errors that I get. Here is a screenshot of my logging console:
Why is the font color pink, so who is printing this message?
Why do I only see this message when I set a breakpoint and step through my code? This message does not appear when simply running the application.
The point where it happens is in this function in the source line right before the current position (yellow arrow):
So according to the message I stepped into m_pStateWidget->insertNavLabel(...) and the error message is printed somewhere in the constructors inside Qt related to the QString class. So I tried the following, which moves the problem away from this code location:
When doing this I get the same error message a few code lines below with another class name in the message, note that the QString::shared_null stays the same.
It appears to me that I have some sort of corrupted memory.
How should I start investigating this issue? I'm afraid to change the code because this might hide the problem as described above.
What's up with the QString::shared_null? I have found that others often see the same in their error messages.
Thank you for any hint or help! :-)
Edit: It's becoming really interesting now. I have stepped into every single function just right before the message is printed and I ended up with these error messages:
at this location:
When I navigate through the call stack in QtCreator the error is printed again and again everytime I select another function in the stack.
Does this mean that the debugger is printing the message and that it is simply too stupid to resolve some sort of vtable stuff for me or does this mean that I have serious trouble going on?
Cause:
Somewhere in your code , you might have overrun the actual memory
Example 1 :
int elmArray[10];
for(int i = 0; i < 20; ++i)
{
elmArray[i] = 0;
}
In the above case, actual array size is 10 but we are assigning values to the index beyond 10.
Example 2:
char* cpyString;
strcpy(cpyString , "TEST");
These scenarios might end up in writing the values into other objects. Mostly could corrupt the virtual table.This gives the above warning.
Fix:
As you know, just correct the code as below.
Example :
int elmArray[10];
for(int i = 0; i < 10; ++i)
{
elmArray[i] = 0;
}
char cpyString[10];
strcpy(cpyString , "TEST");
In your case seems like, you are assigning the QTString::shared_null to some uninitialized string.
There are various threads on different websites where the
can not find linker symbol for virtual table
problem is discussed. Few explain why the problem exists, although some solutions are given to specific examples. Having experienced difficulty with this, I would like to share what I have learned.
First this error message only appeared for Linux builds, it did not show up for Windows builds.
In my case the problem was caused by a second call into a non-reentrant method from the same thread. Once I found the problem, it was easy to fix by using a static busy flag, and simply returning when busy was called a second time. In a nutshell that was the problem and solution. But how did I get into this mess?
Well the non-rentrant method was actually a Qt slot. Since I knew there was a possibility of the second call (actually an emit) being made from the first, the connect was set up with Qt::QueuedConnection. However, I later put up a splash screen QSplashScreen while the function was processing. Little did I realize that QSplashScreen::repaint() called QApplication::processEvents() which dispatched the second offending emit.
So I could have fixed the problem by removing the QSplashScreen and using a QLabel. However, while either works nicely in Windows, neither actually works in Linux, they put up a semi-transparent window and don't paint the contents (even repaint() and or processEvents() doesn't do it). So that is probably a Qt Linux bug, which is another story.
Having a problem here with creating a child window with c++ and win32 api.
If i check the getLastError function its returning "87" but i dont know what that means.
For what i know my code does not contain errors, can someone take a look at my code and help me figure out whats wrong with it.
(This is in the WinProc WM_CREATE section.)
HWND hChildWindow = CreateWindowEx(WS_EX_CLIENTEDGE,0,NULL,WS_OVERLAPPEDWINDOW|WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,hwnd,0,GetModuleHandle(0),NULL);
if(!hChildWindow)
{
char text[256];
int errormsg = (int)GetLastError();
sprintf(text,"Error# %i",errormsg);
MessageBox(0,text,"Error",MB_OK|MB_ICONEXCLAMATION);
return false;
}
87 = Invalid Parameter - be aware that you can use FormatMessage to get a string message from an error code.
The 2nd parameter to CreateWindowEx is a window class (either string or ATOM). Obviously NULL is not a valid value.
P.S.
For what i know my code does not
contain errors...
Beware of such a loud phrases. When something doesn't work everything should be checked carefully. Otherwise you may just accuse something/someone without any good for solving the problem. Check everything vs standard/documentation/specifications/etc. before you make any judgement.
A quick look through the System Error Codes reference indicates ERROR_INVALID_PARAMETER. You're most likely passing in an invalid combination of styles/flags to your window.
This is an SDL problem, however I have the strong feeling that the problem I came across is not related to SDL, but more to C++ / pointers in general.
To make a long story short, this code doesn't work (edited to show what I really did):
player->picture = IMG_Load("player");
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I see nothing on the screen. However, when I do it like this, it works:
SDL_Surface* picture = IMG_Load("player.png");
player->picture = picture;
SDL_BlitSurface(player->picture, NULL, screen, &pictureLocation);
I can see the little guy just fine.
The real problem is that I cannot instantiate Player::picture directly. Even when I try
picture = IMG_Load("player.png")
in player.cpp, I end up with a nullpointer.
I am so stupid. Turns out like I forgot the file extension ".png" every time I tried to store the surface in Player::picture, and conveniently remembered to add it every time I stired it in an SDL_Surface declared in main.cpp.
I had the feeling I was overlooking something really simple here, but this is just embarassing. What's a fitting punishment for this?
What data type is player->picture? What type does IMG_Load return? It's really hard to come up with a scenario where saving an expression in a temporary variable changes the result, unless a type conversion is involved.
And I wouldn't call this pointer instantiation. You're instantiating an instance of some picture type and storing a pointer to it.
This is why you should always check to see what IMG_Load() returns...
SDL_Surface* picture = IMG_Load("player.png");
if (picture == NULL) {
// there was obviously some sort of error.
// what does SDL_GetError() say?
}
Some SDL functions return -1 if there is an error. Just check the documentation and make sure you're checking your function returns. These steps make debugging a lot easier.
My MFC application using the "ESRI MapObjects LT2" ActiveX plugin throws an ASSERT at me when closing it.
The error occurs in cmdtarg.cpp:
CCmdTarget::~CCmdTarget()
{
#ifndef _AFX_NO_OLE_SUPPORT
if (m_xDispatch.m_vtbl != 0)
((COleDispatchImpl*)&m_xDispatch)->Disconnect();
ASSERT(m_dwRef <= 1); //<--- Fails because m_dwRef is 3
#endif
m_pModuleState = NULL;
}
I built the (native C++) application with VC9.
When I compile the application with VC6, it behaves nicely.
What could be the reason for this?
That looks like a reference count. Could this "target" be referenced by something else, something that's not releasing it?
You can trace the Addref and Release calls defining _ATL_DEBUG_INTERFACES
from http://msdn.microsoft.com/en-us/library/sycfy8ec(VS.80).aspx
_ATL_DEBUG_INTERFACES
Define this macro before including any ATL header files to trace all AddRef and Release calls on your components' interfaces to the output window.
Using _ATL_DEBUG_INTERFACES did not yield any additional output...
I defined it on the first line of stdafx.h, directly after #pragma once so I guess this is early enough.
Maybe the reason is how I am using the ActiveX control:
I'm not calling AddRef() or Release() by myself.
The MapObjects Installer comes with sample code with lots of wrapper classes which must have been generated by VC6 or something earlier.
I tried to generate wrapper classes myself with VC9 but there occured errors which I wasn't able to fix.
I use the control by letting one of my windows have a member of type CMap1 (derived from CWnd), which is one of those generated wrapper classes. In CMyWnd::OnCreate() I also call CMap1::Create() and that's it, I'm finished: I can add a layer and the control displays a world map.
I have pretty much no idea what the reference-count stuff is about as I have not added or released any references. At least not knowingly...
The control is pretty old: The .OCX file has the year 2000 in its version information.
It's also not officially supported anymore but I don't have any substitue.
The following solved it for me:
In the window that contains the control, add an OnDestroy() handler:
void CMyWnd::OnDestroy()
{
// Apparently we have to disconnect the (ActiveX) Map control manually
// with this undocumented method.
COleControlSite* pSite = GetOleControlSite(MY_DIALOG_CONTROL_ID);
if(NULL != pSite)
{
pSite->ExternalDisconnect();
}
CWnd::OnDestroy();
}