First of all: the title of this post does not match the actual question I have.
But I am also supplying the answer to the original problem (NullRefExcp on bool), so other users will find it's solution here by the chosen title.
I have a class, similar to the following:
ref class CTest
{
bool m_bInit;
void func()
{
if (!m_bInit)
return;
...
}
...
}
Today I had the problem that func crashed with a NullReferenceException at some point although it had been executed successfully many times before.
The exception occured in the line if (!m_bInit)!
I know, you all are saying now, that this is impossible. But it actually was this line. The reason was following:
I have two different variables, both named oTest, but at different places. One of them was initialized: oTest = gcnew CTest. Calling func on this oTest worked well. The first call of func on the other oTest failed with the exception from above. The curious thing is, that the crash seems to happen at the query on m_bInit, also the stacktrace of the exception tells so. But this was just the first place where a member of the not initialized object (it was still nullptr) was called.
Therefore, the advice for other users with the same problem: Check the stack backwards to find a function call on an object that is nullptr/null.
My question now is:
Why does the execution not fail on the first call of a function of oTest which is nullptr?
Why is the function entered and executed until the first access to a member?
Actually, in my case 3 functions were entered and a couple of variables were created on the stack and on the heap...
This code:
void func()
{
if (!m_bInit)
return;
...
}
could actually be written as:
void func()
{
if (!this->m_bInit)
return;
...
}
Hopefully now you can see where the problem comes from.
A member function call is just a regular function call that includes the this parameter implicitly (it's passed along with the other parameters).
The C++/CLI compiler won't perform a nullptr check when calling non-virtual functions - it emits a call MSIL opcode.
This is not actually the case in C#, since the C# compiler will emit the callvirt MSIL opcode even for non-virtual functions. This opcode forces the JIT to perform a null check on the target instance. The only ways you could get this error in C# is by calling the function via reflection or by generating your own IL that uses the call opcode.
Related
I am building a method "by hand" in ByteBuddy. The method I'm building has one parameter of type ProductType. Let's say it looks like this:
public ProductType frob(ProductType product) {
// stuff that I'm implementing and asking about goes here
}
Inside that method I am building the equivalent of:
product.foo(); // more on this below; foo() has a void return type, which may be important
return product; // FixedValue.argument(0)
This works fine when I build an Implementation like this:
MethodCall.invoke(fooMethodDescription) // invoke foo()...
.onArgument(0) // ...on product...
.andThen(FixedValue.argument(0)); // ...and then return product
(I hope I've typed that right.)
If, however, I build an Implementation like this:
InvokeDynamic.bootstrap(...) // look up foo()'s MethodHandle via my bootstrap method...
.invoke("foo", TypeDescription.VOID) // ...invoke the method handle with a return type of void...
.withArgument(0) // ..."on" the first and only argument (product) and "with" no other arguments...
.andThen(FixedValue.argument(0)); // ...and then return product
…with, of course, the proper InvokeDynamic recipe, the resulting class cannot be verified because of an Operand stack underflow error (Attempt to pop empty stack).
I have a similar InvokeDynamic recipe used many places elsewhere so I know that my problem is not with the InvokeDynamic usage. Rather, it seems to be with the composing? maybe? Is it possible that MethodCall and InvokeDynamic behave differently, even though both are Implementations? Maybe InvokeDynamic doesn't push something on the operand stack (maybe just in the case of void returns?) whereas MethodCall does? Is there something I'm missing in the andThen() usage?
Using ByteBuddy 1.11.2.
As you pointed out correctly, this is a bug in Byte Buddy that is now fixed. Thanks for that. It will be released with version 1.11.3.
I am trying to achieve the following :
I have two methods -
1. public Mono method1
2. public Mono method2
public Mono<Boolean> test(){
method1.map(status -> {
if(status.isActive){
throw Exception;
}
}).switchIfEmpty(method2).thenReturn(true);
}
Can you help with :
Issue is, control goes to method1, only if method1.subscribe() is used. I am unable to return value or throw exception based on Status field returned from method1.
When method1.map() or method1.filter(), control does not even goto method1
When method1 returns Mono.empty() then control is not going to switchIfEmpty(method2)
Your test method just returns a Publisher. You wont be able to achieve anything with it unless a consumer subscribes to it. This might give you a hint why things might not be working for you as expected.
Also, you haven't even clarified in the question if you're are even calling/subscribing to it or not.
We have some legacy software code, which uses COM. I've noticed that at one place, we perform a queryInterface on an IInspectable pointer, but dont bother calling release.
For ex:
void foo(IInspectable* myInterface)
{
ComPtr<OBJTYPE> pObj;
auto hr = myInterface->QueryInterface(__uuidof(SomeType),&pObj);
if (hr != S_OK)
{
return hr;
}
//some code that uses pObj
}
I added Release to the above code like below :
auto hr = myInterface->QueryInterface(__uuidof(SomeType),&pObj);
if (hr != S_OK)
{
return hr;
}
myInterface->Release(); //<-- Is this the correct way to release ?
//some code that uses pObj;
But I see that the above code crashes at times in the above function during release. Is there something wrong in the way I'm releasing the interface ? I can confirm that myInterface is not being used anywhere else in the function after the Release statement.
Apologies for not being able to copy/paste the actual code, but the above code summarizes pretty much the suspect code that I'm debugging. Basically what I want to know is, in the above scenario, do I need to call Release() ? And is this is the right place/way to call Release() ? Do I need to add any other safety checks in place ?
In the first foo function you should NOT call myInterface->Release(). Every call to Release should be paired with an adding of a reference. In that function you don't do myInterface->AddRef, so if you add myInterface->Release then your function will decrement the reference count by one, which does not seem like correct behaviour.
Conceptually, you should call AddRef on entry to the function and Release on exit of the function. Even though the reference count is "intrusive" in COM, the recommended coding style is to treat each interface pointer like it has its own reference count.
This is normally wrapped up in smart pointer classes. But when working with a function that receives a raw "in" interface pointer, this Add and Release can be "optimized" by just omitting both of those calls in the function, and treating the pointer like an observer pointer.
The call to QueryInterface will implicitly do pObj->AddRef() but this is nothing to do with myInterface. When you are finished with pObj a pObj->Release() should occur -- but this is managed by the ComPtr wrapper, you shouldn't add an explicit call.
We have a plugin system that calls functions in dlls (user-generated plugins) by dlopening/LoadLibrarying the dll/so/dylib and then dlsyming/GetProcAddressing the function, and then storing that result in a function pointer.
Unfortunately, due to some bad example code being copy-pasted, some of these dlls in the wild do not have the correct function signature, and do not contain a return statement.
A dll might contain this:
extern "C" void Foo() { stuffWithNoReturn(); } // copy-paste from bad code
or it might contain this:
extern "C" int Foo() { doStuff(); return 1; } // good code
The application that loads the dll relies on the return value, but there are a nontrivial number of dlls out there that don't have the return statement. I am trying to detect this situation, and warn the user about the problem with his plugin.
This naive code should explain what I'm trying to do:
typedef int (*Foo_f)(void);
Foo_f func = (Foo_f)getFromDll(); // does dlsym or GetProcAddress depending on platform
int canary = 0x42424242;
canary = (*func)();
if (canary == 0x42424242)
printf("You idiot, this is the wrong signature!!!\n");
else
real_return_value = canary;
This unfortunately does not work, canary contains a random value after calling a dll that has the known defect. I naively assumed calling a function with no return statement would leave the canary intact, but it doesn't.
My next idea was to write a little bit of inline assembler to call the function, and check the eax register upon return, but Visual Studio 2015 doesn't allow __asm() in x64 code anymore.
I know there is no standards-conform solution to this, as casting the function pointer to the wrong type is of course undefined behavior. But if someone has a solution that works at least on 64bit Windows with Visual C++, or a solution that works with clang on MacOS, I would be most delighted.
#Lorinczy Zsigmond is right in that the contents of the register are undefined if the function does something but returns nothing.
We found however that in practice, the plugins that return nothing also have almost always empty functions that compile to a retn 0x0 and leaves the return register untouched. We can detect this case by spraying the rax register with a known value (0xdeadbeef) and checking for that.
When implementing a COM interface I always assign to the out parameters on success but should I do so also on error?
HRESULT CDemo::Div(/*[in]*/ LONG a, /*[in]*/LONG b, /*[out,retval]*/ LONG* pRet)
{
if (pRet == NULL)
return E_POINTER;
if (b == 0)
{
*pRet = 0; // is this redundant?
return E_INVALIDARG;
}
*pRet = a/b;
return S_OK;
}
At one time I was bit on the nose by not initializing an out parameter and assuming that if I initialized the variable it will remain that value if I don't change it inside the method. However I used this method from .NET and since the marshaller sees that this is an [out] parameter it discarded the initial value I placed on the call site and put in garbage after the function returned (it was fun debugging that, not).
Is assigning to an out param even on failure overcompensation or should I really do it?
Edit: Even though formally one should not access out params if the function failed I often see (and sometimes write) code like this (using the example from sharptooth's post):
ISmth *pSmth = NULL;
pObj->GetSmth(&pSmth); // HRES is ignored
if (pSmth) // Assumes that if GetSmth failed then pSmth is still NULL
{
pSmth->Foo();
pSmth->Release();
}
This works fine in un-marshalled code (same thread apartment) but if a marshaller is involved is it smart enough to only set the return value if the function succeeded?
While the other answers are not wrong, they miss a very important point -- a COM server that intends to return a failure HRESULT MUST set all [out] parameters to NULL. This is not merely a matter of good style, it is required by COM and not adhering to it can cause random crashes when there is marshaling involved.
That said, the *pRet = 0; in the original code is not redundant but correct and required.
The rule is that the calling party is not allowed to do anything with the out parameters value if the call fails. The server therefore should not provide valid values and should not pass ownership of any resources to the out parameters.
For example if you have
HRESULT GetSmth( [out] ISmth** );
method then it's expected that the server calls AddRef() on the ISmth** variable prior to returning. It must not call AddRef() if it is going to return a failure code because the client is not allowed to use the returned out parameter value and therefore will not call Release() and you'll get a memory leak.
I'm not sure I 100% agree with sharptooth. I certainly agree that for a failed COM call you cannot and must not assign any resource ownership to any out parameters. This includes memory allocation or AddRef'ing a COM object.
However I see nothing wrong (and in fact encourage) setting purely out parameters to empty values as long is does not transfer any resource ownership. For instance there is nothing technically illegal about your code setting pRet to point to 0. This transfers no resource ownership over to pRet and is merely a helper to some caller who did not properly check for success of the call.