AddRef on IUnknown(IXRApplication) crashing - com

I am debugging a larger issue but I have narrowed down to a specific scenario.
Firstly:
XamlRuntimeInitialize();
IXRApplication* pApp;
res=GetXRApplicationInstance(&pApp);
This works fine, Then:
IUnknown* pUnk;
res=pApp->QueryInterface(IID_IUnknown, (void**)&pUnk);
This executes and even returns S_OK however the address returned in pUnk is not the same as pApp(exactly 4bytes less), unexpected but technically not an issue
After That:
UINT cnt=pUnk->AddRef();
This executes and returns 0 but from this point on if I try to call pUnk->Release or pUnk->QueryInterface it crashes. If I call pUnk->Release before pUnk-AddRef it runs but again after pUnk->AddRef any call crashes. It seems as though the AddRef is actually destroying the object. The crash appears to be a null reference exception.
EDIT:
So after learning how to debug on a WEC7 Emulator I have found what looks like the issue. The assembly for AddRef() on the IUnknown looks like this
xor eax, eax
retn 0x0C
Thats all, so every call into AddRef() corrupts the stack. Its interesting because sometimes it would work, and other times not but it turns out it had more to do with the stack i.e. Stack allocated variables.
I have no idea how to work this now. I am trying to avoid a native wrapper because of portability issues, but I dont think there is any way get around this with managed code alone.
On another note what the heck was Microsoft thinking. Doesn't this violate there own rules of COM. I am having a hard time understanding how they could release code that corrupts the stack like that.

Related

If i don`t release WICFactory(IWICImagingFactory*), What happen?

I'm learning DirectX 2D.
When i close my application, i have noticed there is a problem in IWICImagingFactory* type variable.
I use only one IWICImagingFactory* variable in whole program. So i initiate it once when i start program and destroy(release) once when i close my program.
But if i release IWICImagingFactory* variable after call CoUninitialize() function, there is error.
Factorys::~Factorys()
{
SAFE_RELEASE(mpD2DFactory);
SAFE_RELEASE(mpWICFactory);
}
↓ Is is korean, meaning : error throw, access violation, "this->mpWICFactory->" is 0x6EEFC7D8
enter image description here
I noticed "this->mpWICFactory->" has problem when i try to release WICFactory after call CoUninitialize(). So i read about CoUninitialize() in here : "https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-couninitialize"
And i read this part in the link : Closes the COM library on the current thread, unloads all DLLs loaded by the thread.
Quetion 1 : When i call CoUninitialize() function, WICfactory is released automatically?
Quetion 2 : Do i have to release WICFactory before call CoUninitialize() function?
Yes, as you mention in the question, CoUninitialize will unload all dependent loaded libraries (WICFactory being one of them).
So trying to unload an already unloaded library will get you an AV or another Error.
It's not "really necessary" to release WICFactory, since CoUninitialize will also do it (and since you release when program closes anyway, even if you don't call CoUninitialize the Operating System will do it for you).
However, I strongly recommend that you still release your resources (so yes, release WICFactory, then call CoUninitialize ), having code that knows how to do correct cleanup will always be better in the long term (no matter if you use smart pointers or not, that is up to you).

vkAllocateDescriptorSets returns VK_OUT_OF_HOST_MEMORY

I wrote vulkan code on my laptop that worked, and then I got a new laptop and now running it, the program aborts because vkAllocateDescriptorSets() returns VK_OUT_OF_HOST_MEMORY.
I doubt that it is actually out of memory, and I know it can allocate some memory because VkCreateInstance() doesn't fail like in this stack overflow post: Vulkan create instance VK_OUT_OF_HOST_MEMORY.
EDIT: Also, I forgot to mention, vkAllocateDescriptorSets() only returns VK_OUT_OF_HOST_MEMORY the second time I run it.
vkAllocateDescriptorSets allocates descriptors from a pool. So while such allocation could fail due to a lack of host/device memory, there are two other things that could cause failure. There may simply not be enough memory in the pool to allocate the number of descriptors/sets you asked for. Or there could be enough memory, but repeated allocations/deallocations have fragmented the pool such that the allocations cannot be made.
The case of allocating more descriptors/sets than are available should never happen. After all, you know how many descriptors&sets you put into that pool, so you should know exactly when you'll run out. This is an error state that a working application can guarantee it will never encounter. Though the VK_KHR_maintenance1 extension did add support for this circumstance: VK_ERROR_OUT_OF_POOL_MEMORY_KHR.
However, if you've screwed up your pool creation in some way, you will get this possibility. Of course, since there's no error code for it (outside of the extension), the implementation will have to provide a different error code: either host or device memory exhaustion.
But again, this is a programming error on your part, not something you should ever expect to see with working code. In particular, even if you request that extension, do not keep allocating from a pool until it stops giving you memory. That's just bad coding.
For the fragmentation case, they do have an error code: VK_ERROR_FRAGMENTED_POOL. However, the Khronos Group screwed up. See, the first few releases of Vulkan didn't include this error code; it was added later. Which means that implementations from before the adding of this error code (and likely afterwards) had to pick an inappropriate error code to return. Again, either host or device memory.
So you basically have to treat any failure of this function as either fragmentation, programming error (ie: you asked for more stuff than you put into the pool), or something else. In all cases, it's not something you can recover from at runtime.
Since it appeared to work once, odds are good that you probably just allocated more stuff than the pool contains. So you should make sure that you add enough stuff to the pool before allocating from it.
The problem was that I had not allocated enough memory in the pool. I solved it by creating multiple pools. One for each descriptor set.

Local variable being stored over different function calls. weird

I'm bewildered by whats happening. It's more of a trick question I don't know the answer to.
I have the following function inside my main.m of an Objective-C program.
int incrementCounter(){
int counter;
counter+=2;
return counter;
}
and inside my main.m
NSLog(#"Counter: %d",incrementCounter());
NSLog(#"Counter: %d",incrementCounter());
NSLog(#"Counter: %d",incrementCounter());
The weird thing is one mac book(don't know the Xcode version ) when I executed this the output was:
2013-05-28 19:16:27.131 SOQ[4923:707] Counter: 1
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 3
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 5
My questions here:
1. How did counter get initialized to 1? (when i use static it get initialized to zero)
2. How is the value being stored over successive method calls?
3. When I check for the memory location of this variable for different executions of the program it remains the same. How does that happen?
And when I executed the same piece of code in another mac(lion Xcode 4.2.1) it gives the following output:
2013-05-28 19:16:27.131 SOQ[4923:707] Counter: 32769
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 32769
2013-05-28 19:16:27.132 SOQ[4923:707] Counter: 32769
My questions here:
1. How does this behavior change from mac to mac? //I was thinking different compiler versions but it was both using the same(not sure though) . Is there any other way?
2. How did the counter get initialized to 32767? I was thinking garbage value, but isn't the objective-c compiler supposed to initialize primitive like int to zero? And I'm getting the same 32769 over and over again. How?
Maybe I'm missing out on something basic. Any pointers?
How did counter get initialized to 1? (when i use static it get initialized to zero)
How is the value being stored over successive method calls?
When I check for the memory location of this variable for different executions of the program it remains the same. How does that happen?
How does this behavior change from mac to mac? //I was thinking different compiler versions but it was both using the same(not sure though) . Is there any other way? 
How did the counter get initialized to 32767? I was thinking garbage value, but isn't the objective-c compiler supposed to initialize primitive like int to zero? And I'm getting the same 32769 over and over again. How?
The answer to all these questions is: coincidence. You are using an uninitialized value. You can't rely on this value, and you should not use it at all. The compiler probably warns you about it too.
The compiler does not initalize local variables of primitive types. If you use ARC local objects are initialized to nil automatically, but not primitive types.
Primitive instance variables are initialized to 0 and instance variables pointing to objects are initialized to nil.
In your incrementCounter function you are using counter which is an uninitialised variable, so the behaviour is 'undefined' - which means what you're seeing is perfectly valid behaviour (in that any behaviour would be valid since the behaviour is undefined).
So as for what is actually happening (or could potentially be happening, depending on the compiler and runtime implementations):
1-1: It's undefined what the initial value will be, but it might end up always being the same for multiple executions if the object loader behaves in a deterministic way and just happens to leave a certain bit-pattern in that memory prior to beginning execution of your program, or even just by accident.
1-2: When incrementCounter is called some memory on the stack is allocated (the next available chunk, on the top of the stack), then incrementCounter increments and returns it. Then NSLog is called, using the same stack-memory (but perhaps a different size). NSLog happens to not trample on that value (probably because the compiler puts it in a place used for return values and NSLog doesn't have a return value). Then incrementCounter is called again, the same stack-memory is re-used and the value just happens to not have been trampled. Try implementing a second otherIncrementCounter method in exactly the same way to see if they are both sharing the same memory for that return value, also take a look at &counter in both methods, it's probably the same.
1-3: The local address-space that your program uses when it is run as a process is local to that process. A different program writing to the same address won't trample your process's memory. A kernel implementation can map this memory however it likes, for example it could use the same starting-point for the stack address space for all its processes.
2-1 & 2-2: See 1-1 and 1-2 above. Perhaps a different build of the kernel, object loader, OS, etc. In this case perhaps NSLog is doing something with that value, perhaps using it temporarily, to set it to 32767 each time. The implementation of NSLog may have changed or may just be compiled with a different compiler version on that machine - it's in a shared library that's loaded and linked at run-time, not compiled into your executable.
In general it's fairly pointless to wonder about these things, there are too many reasons that things could be working as they are, but it's useful to know how compilers and stacks work so I hope my answers above give you inspiration to learn about that a bit more. However, when programming (and not learning about compilers) simply don't rely on undefined behaviour, turn on lots of warnings and treat them as errors so you don't ever accidentally depend on the implementations of compilers, runtimes, or library implementations.

Strange COM behaviour called from .net

i am working on an application which calls the COM component of a partner's application. Ours is .Net, theirs isn't. I don't know much about COM; I know that the component we're calling is late-bound i.e.
obj As Object = CreateObject("THIRDPARTY.ThirdPartyObject")
We then call a method on this COM object (Option Strict Off in the head of the VB file):
obj.AMethod(ByVal Arg1 As Integer, ByVal Arg2 As Integer, ByVal Arg3 as Boolean)
I am a bit nonplussed that even though this call works, this overload doesn't exist in the COM interop .dll that is created if I instead add a reference to the COM server using Add Reference. The only available call to this method that it says is available is AMethod().
However, this in itself is not what bothers me. What bothers me is that this call works for a while, THEN throws a TargetParameterCountException after a few dozen calls have executed successfully.
I ask thee thus, StackOverflow:
What. The. Hell.
The only thing I can guess at is that the documentation for the COM component states that this method is executed synchronously - so therefore maybe whatever's responsible for throwing that exception is being blocked until some indeterminate point in time? Other than that, I'm completely stumped at this bizarre, and more importantly inconsistent behaviour.
edit #1:
More significant information that I've just remembered - from time to time the call throws an ExecutionEngineException instead. It only took one glance at the documentation to realise that this is VERY BAD. Doing a little bit of digging suggests to me that the late-binding call is causing stack corruption, crashing the entire CLR. Presumably this means that the runtime is shooting down bad calls (with TargetParameterCountException) some of the time and missing them (ExecutionEngineException) others.
edit #2:
Answering David Lively's questions:
The call with zero arguments that's currently in the code has been there for a long time. I haven't been able to get hold of a manual for the third party's COM implementation past two major revisions ago, so it's possible that they've withdrawn that signature from service
There is only one location that this method is called from
This is one desktop app calling another, on the same machine. Nothing fancy
The object is persisted throughout the scope of the user's interaction with the application, so there's never a new one created.
Unfortunately, it seems likely that there is indeed a bug in the implementation, as you suggest. The trouble with this vendor is that, when we report a bug, their response tends to follow the general form: i) deny there's a problem; ii) deny it's their problem; iii) refuse to fix it. These three steps tend to span a frustratingly long period of time.
No, it can't cause stack corruption. IDispatch::Invoke() is used to call the method, the arguments are packaged in an array. The stock implementation of IDispatch certainly would detect the argument mismatch, it uses the type library info to check. But it is conceivable that the COM server author implemented it himself. Imperfectly. It is something a C++ hacker might do, the stock implementation is dreadfully slow. The GC heap getting corrupted is the kind of thing that happens when imperfect code executes.
I haven't played with calling COM objects from VB in quite a while, but I'll take a wild guess:
I would expect an exception to be thrown if you're calling the object with too few or too many arguments, but it appears that's not the case. What is the real signature of the method you're calling?
In some languages and some situations, when you call a method, arguments are placed on the stack. If you place too many arguments, it's possible for the extraneous ones to remain on the stack after the method completes. This should cause lots of other problems, though.
Some possibilities/considerations:
The object is throwing this exception internally. This should be taken up with the author.
You're calling with too many parameters. If, as you said, the overload you're trying to call isn't published in the object's type library, you may actually be calling a different published method with a different signature. I'd REALLY expect a compiler error if this is the case.
Are your later calls taking place in the same part of your code, or is there a different execution branch that might be doing things a bit differently, and causing the error?
Are you running this from a desktop app/script, or a website? If a website, are you receiving a valid, expected response, or does the request hang as if an internal long-running process doesn't complete?
The object may be allocating and not releasing resources, which could cause undefined behavior when those resources are exhausted.
Are you releasing the object between calls, or is it recreated every time?
Also, re: your comments about late binding: the .CreateObject() method of instantiating a COM object is the normal, accepted way to do this. That shouldn't have anything to do with the issue. Based on the exceptions you listed, I'm strongly inclined to believe that there is an internal issue with the object.
Good luck.
OK, basically - false alarm. I've done it wrong - I've copied some code over from somewhere improperly and the thing I'm calling was never supposed to support that overload. What I find interesting is that the component didn't reject that late-bound call out of hand, but did everything it was supposed to do, at least initially.

clever ways of tracking down bugs in Obj-C

I'm having a bug in my Objective C program which causes the machine to crash hip deep in some library methods, and it's all library methods down the stack to main (Which I haven't touched from the one XCode gave me). So, I have a bit of a mystery.
The error I'm getting is:
Program received signal: “EXC_BAD_ACCESS”.
Now, I'm sure that this means that somewhere I'm releasing something too many times, or something like that. This is the objective C version of a seg-fault, right?
My question is: Since it's not happening in my own code, is there some clever way of tracking down what I'm double releasing? or is code inspection the best bet?
thanks.
EXC_BAD_ACCESS essentially means that you're trying to access or use a specific chunk of memory in an unexpected way. For example, if you try to send a message to a memory reference that no longer represents a valid object. It's different from a segmentation fault, but related.
See this related SO question for suggestions on debugging over-released objects. NSZombie will work wonders for you. Once you get your hands on Snow Leopard (you're getting it this Friday, right?) use the Zombies instrument to simplify the process, and use the Xcode static analyzer to help you find such errors at compile time.
Also visit: http://www.cocoadev.com/index.pl?DebuggingTechniques and this Apple Tech Note.