failed accessing COM method after successful cocreateinstance - c++

after successful coInitialize and cocreateinstance (COM server registration is perfect).. When i access a method in class it returns the error:
"First-chance exception in XYZ.exe (OLEAUT32.DLL): 0xC0000005: Access Violation".
By step by step debugging i found it gives this error while calling
// make the call
SCODE sc = m_lpDispatch->Invoke(dwDispID, IID_NULL, 0, wFlags, &dispparams, pvarResult, &excepInfo, &nArgErr);
in OLEDIST2.CPP file.
please help

thanks for your time.
the problem is solved at my end.
Problem lies in importing the type library (tlb) of the COM server in to my client application. Because of which, object gets a corrupted pointer. when a member function is called it gives ACCESS VOILATION error.
I actually imported the typelibrary in my Visual C++ application using "CLASS WIZARD" as mentioned # MSDN link:
http://msdn.microsoft.com/en-us/library/aa279228(VS.60).aspx
Which actually caused the above problem.
Later I found by importing typelibrary using simple #import "xyz.tlb"
it generates two files .tlh and .tli files which also contains all the classes and member function definitions.
When i used these files in my project it worked.
Sorry for bothering you......
thanks and regards
sandeep r.

Right now I can think of following checks:
Just check if you have a chance to
debug and see the value of
m_lpDispatch. Whether the value is
proper?( not NULL)
Just check whether accidentally
CoUninitialize() has been called ?
Just check whether COM object is
properly reference counted ?

Based on your code, the only thing that immediately jumps out is that m_lpDispatch could be NULL or an invalid pointer. Nothing else in that line should lead to an access violation as it doesn't actually access any memory.
If you can confirm that m_lpDispatch is indeed a valid variable it's possible it's a method being called by Invoke that's causing the problem. If so then you might want to turn on first chance exception handling for access violations in Visual Studio.
Go to: Debug -> Exceptions -> Win32 Exceptions
Check "Access Violation"
Then run your scenario under the debugger. It will cause visual studio to break at the point of the access violation. That should make it a bit more obvious where the actual problem is.

Related

Handle possible not existing function in a version of com

I have a question for com handling.
I'm using a third party dll which I include through #import, using named_guids as argument. I don't know if I should use another argument or not for proper importing..?
The problem is that there are different versions of the dll. One particular function that I'm using is added in the last version of the dll. So, if a costumer have an older version there is an exception - access violation executing location (some address). I understand that the error is telling me that the function can't be found, but how to catch this exception?
I tried with try-catch(_com_error) - nothing, try-catch(std::exception) - nothing, even try-catch(...) - still nothing.
Can I catch this kind of exception and log the exception and tell the costumer that there is a problem with the dll?
I'm not working with LoadLibrary and GetProcAddress.
The developer of the third party DLL violated a core principle of COM: Interfaces are immutable. This implies that once published, an interface may not change whatsoever. You are seeing the effect of what happens when this rule isn't followed: your call to the non-existent method results in an access violation.
If the COM interface derives from IDispatch, then you have an easy way to check, whether a method exists or not: Use GetIDsOfNames to get the DISPID of the method. If it doesn't exist, the function will return with a DISP_E_UNKNOWNNAME error:
DISPID dispID;
BSTR methodName = SysAllocString(L"MyMethod");
// Check hr return value
HRESULT hr = piDisp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
SysFreeString(methodName);

Is it possible to check if error code has been retrived using GetLastError

If you have a large system that automatically shows a nice window explaining a caught exception it would be nice to be able to present the error code along with the message (for further investigation). But since some functions calls are to failing windows functions, which set an error code, and some are local failing functions that don't set the error code I wonder if there is a way to check if the last set error code has been "retrieved" already.
Let's say we have a piece of code
if (!CopyFile(("c:\foobar.txt", "d:\foobar.txt",FALSE))
{
throw FooBarException("bla bla bla");
}
Here it would be possible to automatically add the error code to the error message since CopyFile is a function that sets the error code on failure. Now, we could add the error code "manually" within the if statement and append it to the error string passed when creating the exception. But to not have to change thousands of places in existing code we could have the constructor of the FooBarException automatically fetch and append the error code. But this also raises the issue in question.
What if some code that doesn't set the error code causes a FooBarException to be raised. Then the constructor would GetLastError but get an error code that might not be connected to the current exception at all.
But if the constructor of FooBarException could call some LastErrorRetrived (or something similar) and get true if the error code has already been retrieved before it ould ignore appending the error code and assume it's connected to an earlier error.
Now I understand this can go haywire if one does not actually "retrieve" the error code after every windows function that can fail and set the error code. But let's assume this is done.
Short answer: No.
The value returned by GetLastError is simply a global (per-thread) object without any logic attached. It can be accessed through GetLastError, SetLastError and the mysterious RestoreLastError.
I'm afraid I have to break the news: Retrofitting error handling into a system that wasn't prepared for it is tedious.
There is really very little you can do outside of implementing several exception classes (for Win32 error codes, COM HRESULTs, etc.) and changing each and every invocation.
GetLastError() just gets thread's last-error code value and that's all. So, I believe there is no way to know was it called once or a few times. Moreover, I don't really think you need to.
The best solution here is to create WinAPIException class derived from some base class (for example, std::exception ). In constructor WinAPIException should call GetLastError() before any other WinAPI call. It guarantees that the error value isn't change.
if( !CopyFile("c:\foobar.txt", "d:\foobar.txt",FALSE) )
throw WinAPIException("Houston, we have a WINAPI problem");
If you check result after non-WinAPI function call - just use other exception class (derived from the same base class):
if( std::cin.get() < 0 )
throw std::runtime_error("Houston, we have runtime problem");
Thus, you can use single try...catch statement to catch both exceptions:
try {
...
} catch( std::exception &e ) {
...
}

LoadLibrary cannot find ntoskrnl

I am writing a small app which calls KeBugCheck and crashes the system but LoadLibrary is unable to find ntoskrnl.exe (I get 126 as return value when calling GetLastError)
Here is my code:
void* fnc;
HMODULE bcLib;
bcLib = LoadLibrary((LPCWSTR)"ntoskrnl.exe");
fnc = (void*) GetProcAddress(bcLib, (LPCSTR)"KeBugCheck");
int(*KeBugCheck)(ULONG);
KeBugCheck = (int(*)(ULONG))fnc;
KeBugCheck(0x000000E2);
Also, in the debug window, I see this error:
First-chance exception at 0x00000000 in app.exe: 0xC0000005:
Access violation executing location 0x00000000.
Any help will be very much appriciated
KeBugCheck is a kernel function. That means you can't call it from user-mode code, like the application you're trying to write.
There is also no user-mode wrapper provided for this function because user-mode code is not supposed to be able to bring down the entire system.
You will have to write your own kernel-mode driver to do this. To get started, download the Windows Driver Development Kit (DDK). And in that case, there will be no need for the whole LoadLibrary and GetProcAddress dance, since the function declaration is in the public Ntddk.h header and will be linked in automatically from the Ntoskrnl.lib file.
As for the problem you're having here, with LoadLibrary returning ERROR_MOD_NOT_FOUND, that is unrelated. The code you have is wrong, quite obvious from the explicit cast to LPCWSTR that you're having to perform in order to shut the compiler up.
You're compiling a Unicode application, so the call to LoadLibrary is automatically resolved to LoadLibraryW, which accepts a wide (Unicode) string with the type LPCWSTR. You're trying to pass it a narrow string literal, which generates a type mismatch error. Except that you've inserted the cast, which effectively tells the compiler to shut up because you know better than it. Except that you don't. You should listen to the compiler; it can save you from a lot of bugs.
The fix is simple: remove all the superfluous casts from your code and use a wide string literal instead. (The GetProcAddress function, however, is unique: it always requires a narrow string, regardless of whether or not you're compiling for Unicode.)
HMODULE bcLib = LoadLibrary(L"ntoskrnl.exe");
void* fnc = (void*)GetProcAddress(bcLib, "KeBugCheck");
Of course, once you fix this, you'll want to see the first part of my answer.
Try using the ntdll.dll NtRaiseHardError function. ntdll functions are the closest that you can get in user-mode to kernel-mode functions and NtRaiseHardError eventually calls KeBugCheck in the kernel.

SEH exception with code 0xc0000005 thrown in the test body

I am writing a test using GoogleTest for the following class and I am getting the above error.
class Base
{
// Other Functions;
CSig objSig[50];
}
The Class CSig is as follows:
class CSig
{
//... constructor, destructor(empty) and some functions
CMod *objMod;
CDemod *objDemod;
}
CSig :: CSig
{
bIsInitialised = false;
for (int i=0; i<MAX_NUM; i++)
{
PStrokePrev[i] = 0.0;
}
}
However, when I discard CSig objSig[50], the tests run fine.
What can I do to solve this issue? Also, I need to have CSig objSig[50] in the Base class.
A SEH (Structured Exception Handling) exception is not a C++-exception that can be handled using c++-language constructs (try-catch) but it is raised from windows itself and points to some fundamental flaw. SEH-exceptions are very annoying because they do not cause normal stack unwinding which can lead to unclosed files or not-unlocked mutexes that should normally cleared by the destructors of the owning object.
I have encountered SEH-exceptions when accessing memory that does not belong to the current process so I recommend looking at memory-related instructions in the constructor and destructor of CSig.
You can read about SEH, for instance, here
The way I just found the problem was that in Visual Studio I went to Debug->Exceptions, and checked everything in the first column. Then run/debug your unit tests, and it will throw an exception on the line that the problem is at. That's where you need to debug/fix it.
I ran into this very problem using GoogleTest with Visual Studio 2010. Our setup involves creating a library for the GoogleTest Frameworks, which is then linked against our individual Unit Tests. I recently updated the Frameworks support and recompiled it from scratch. After doing this, I encountered the exception described above.
After a bit of digging, I discovered that the 'Struct Member Alignment' setting was the culprit:
Project properties > Configuration Properties > C/C++ > Code Generation > Struct Member Alignment
While the Frameworks project had the setting set to 'default', the corresponding Unit Test project had it configured to "1 Byte /Zp1". Once I changed them to have the same alignment, the problem went away.
For me it appeared to be a null reference error. Some method was called on a nullptr and for reasons unclear to me it didn’t fail immediately but just started executing. The SEH error presumably occurred as soon as unallocated memory was accessed. So check for null pointers!
I am having a similar issue and its pertaining to un-initialized variables and running the test in release build. I had a char * un-initialized after which initialized to NULL seems to have fixed the issue.
If you are using Visual Studio 2013, check the Thrown box for Win32 exceptions (specifically access violation) in Debug>Exceptions. This will let you debug which line has the issue. This might be useful since the debugger will not break if your program normally raises other exceptions.
destroying null pointer can be a reason. I found out through Visual Studio > Exception > Select All. Then run local windows debugger, it stopped at line where exception occurred.
Ran into this problem using msvc in qt. SEH was thrown almost randomly, for no apparent reasons. (read: didn't have any time left to look into it)
After NOT finding the right solution and the tests seemed to work for non-windows users, I switched to MinGW which ran the tests normally.
I was trying to delete a memory address which was already deleted. This was the problem in my case so i suggest to look for null pointers.

How to debug "This application has requested the Runtime to terminate it in an unusual way." when I can't even step in the code?

I have a C++ program that is giving this error as soon as the process starts - apparently before any user code executes. It only happens when inlining is enabled. Even with debug symbols built in, I can't step in the code. As soon as I press F10 in Visual Studio I get the error and the program stops. I checked all exceptions/checks in "Debug/Exceptions" but still don't get a break.
Normally I would expect something like this to be due to a missing runtime dependency but I'm quite positive that's not the case here (verified with Dependency Walker).
edit: I used Steve Townsend's recommendation of CDB and now I'm able to step through the pre-user-code parts of the program. The final stack trace is:
Child-SP RetAddr Call Site
00000000`0008e308 00000000`7541601a ntdll!ZwTerminateProcess+0xa
00000000`0008e310 00000000`7540cf87 wow64!Wow64EmulateAtlThunk+0x86ba
00000000`0008e340 00000000`7539276d wow64!Wow64SystemServiceEx+0xd7
00000000`0008ec00 00000000`7540d07e wow64cpu!TurboDispatchJumpAddressEnd+0x24
00000000`0008ecc0 00000000`7540c549 wow64!Wow64SystemServiceEx+0x1ce
00000000`0008ed10 00000000`7776ae27 wow64!Wow64LdrpInitialize+0x429
00000000`0008f260 00000000`777672f8 ntdll!LdrGetKnownDllSectionHandle+0x1a7
00000000`0008f760 00000000`77752ace ntdll!RtlInitCodePageTable+0xe8
00000000`0008f7d0 00000000`00000000 ntdll!LdrInitializeThunk+0xe
You could try setting up Process Dumper and configure it for your EXE to create a dump on any process exit. Then start the process from the command line to rule out any artifacts of the IDE.
This ought to give you a dump for post-mortem debugging, and maybe a callstack fromm the exiting thread that could be useful.
It probably has to do with the order that your globals are being initialized. In C++, the order between modules is unspecified. So if a global's initializer depends on a global in another module already being initialized, you're in trouble.
It's possible to put a break point in the CRT initialization code that runs before calling main (or wmain, or WinMain, or whatever you're using). You can step through that code and see what's causing the problem.
Another possible cause is a DllMain function is returning an error or throwing an exception during DLL_PROCESS_ATTACH.