What happens if pthread_key_delete is called on a key after a failed pthread_key_create? - pthreads

Suppose the following code:
pthread_key_t key;
pthread_key_create(&key, NULL); /* failure here */
pthread_key_delete(key);
If pthread_key_create fails, is the call to pthread_key_delete considered undefined behavior? How about if pthread_key_create is commented out?
The pthread_key_delete section of the POSIX standard states:
The pthread_key_delete() function shall delete a thread-specific data key previously returned by pthread_key_create().
Since pthread_key_delete expects a thread-specific data key previously returned by pthread_key_create, I'm afraid calling pthread_key_delete on a key that was not returned by pthread_key_create can lead to undefined behavior.

Yes, it is implicitly undefined behavior, to the extent that the standard you link doesn't define what happens in that use case.
The SUSv7, however, is explicit in its discussion of pthread_key_delete, saying plainly in its CHANGE HISTORY for Issue 7 that:
The [EINVAL] error for a key value not obtained from pthread_key_create() or a key deleted with pthread_key_delete() is removed; this condition results in undefined behavior.

By looking at the source code of pthread_key_create and pthread_key_delete
it seems that pthread_key_create is returning a memory location and filling in other fields of "key" structure, which is opaque like everything else in posix.
pthread_key_delete expects the key structure fields to be populated/set with valid data to search for the memory location. So it seems calling pthread_key_delete after a failed pthread_key_create causes undefined behavior. Here is one more link that seems to support by opinion.
How does pthread_key_t and the method pthread_key_create work?
I hope this helps.

Related

Proper way to return error from within a mutateAndGetPayload

I am doing a number of business logic checks within the mutateAndGetPayload function of a relay mutation using the graphql-relay library. For any of these checks that fail I have an else clause that will throw an error, ig throw('You do not have permission to delete this resource');, however, when that happens, I get the error Cannot set property 'clientMutationId' of undefined returned to the frontend instead of the error I'm trying to return. It seems that I'm seeing this error because I'm not returning something this mutation cares about (or a promise that resolves to one), so I'm a little stumped ... what's the proper way to throw/return errors back to the client here?
One way is to use the GraphQLError Type
Working in NodeJS on the back end we have used the following library:
https://github.com/graphql/graphql-js/tree/master/src/error
However, what we have ended up using is a library that provides more flexibility:
https://github.com/kadirahq/graphql-errors
Either of these would be the best place to start.

In py2neo, how do I know if a push() worked?

I'm updating a node and pushing it:
remote_graph.push(node)
push() seems to return nothing. How can I tell if the push works? In my test code, I ought to be violating a unique constraint in Neo4J.
How can I tell using py2neo? I expected an exception.
When I enter the equivalent cypher into the Neo4J web tool, I get the following exception:
Node 322184 already exists with label VERSION and property "version"=[1.436818928448956E9]
which is what I expected.
Edit -
What I expected to get back was an indicator of whether the operation worked or not. I think push() accepts an array of nodes, so an array of results would be sensible. I don't know what the indicator would have within it since I don't know what is available. An array of strings would be fine, with each string being a failure reason, or "OK".
Generally speaking, the design of this API is: if it returns OK, you can assume everything has worked as expected, if an error is raised, that error will contain details of what went wrong. Therefore, absence of error should usually be interpreted as a signal of success.
That said, if you believe that your push has failed and no error has been raised, there is a bug in py2neo. For debugging, you can check the state of the database after your push by using the browser and then if you're able to recreate this scenario in a standalone piece of code, please raise an issue on GitHub and I will be happy to fix it.

What is a "NullReferenceError" in ASP.NET MVC?

I keep getting "NullReferenceError" in my output, could someone kindly explain what exactly this statement means.
Somewhere in your code, you are trying to access a member of a reference type, but the variable actually is null. Without code and a stacktrace it's impossible to say what exactly happens. It might be because some parameter is expecting a value but isn't supplied one.
If it helps, a decent description of NullReferenceException -- why/when they occur, and how to prevent them -- at http://www.dotnetperls.com/nullreferenceexception

What/Where is the value of E_CLR_ALREADY_STARTED?

The docs for ICLRRuntimeHost::SetHostControl claim that it can return E_CLR_ALREADY_STARTED. I have been unable to find a definition for this value. Ideally, I'd like to know what the appropriate header to include is (it does not appear to be in corerror.h) but if someone can provide me with the canonical value too I can live with that.
Thanks
I can't seem to find it either and I'm usually pretty good at finding missing or misspelled constants. You could try calling the method after initializing the CLR and if it does in fact return the HRESULT that it's documented to return, you could just trace it. But it definitely seems like a documentation bug.

How to track down access violation "at address 00000000"

I know how to create a .map file to track down access violation errors when the error message includes an actual address.
But what if the error message says
Access violation at address 00000000. Read of address 00000000.
Where do I start looking for the cause of this problem... ?
The accepted answer does not tell the entire story.
Yes, whenever you see zeros, a NULL pointer is involved. That is because NULL is by definition zero. So calling zero NULL may not be saying much.
What is interesting about the message you get is the fact that NULL is mentioned twice. In fact, the message you report looks a little bit like the messages Windows-brand operating systems show the user.
The message says the address NULL tried to read NULL. So what does that mean? Specifically, how does an address read itself?
We typically think of the instructions at an address reading and writing from memory at certain addresses. Knowing that allows us to parse the error message. The message is trying to articulate that the instruction at address NULL tried to read NULL.
Of course, there is no instruction at address NULL, that is why we think of NULL as special in our code. But every instruction can be thought of as commencing with the attempt to read itself. If the CPUs EIP register is at address NULL, then the CPU will attempt to read the opcode for an instruction from address 0x00000000 (NULL). This attempt to read NULL will fail, and generate the message you have received.
In the debugger, notice that EIP equals 0x00000000 when you receive this message. This confirms the description I have given you.
The question then becomes, "why does my program attempt to execute the NULL address." There are three possibilities which spring to mind:
You have attempt to make a function call via a function pointer which you have declared, assigned to NULL, never initialized otherwise, and are dereferencing.
Similarly, you may be calling an "abstract" C++ method which has a NULL entry in the object's vtable. These are created in your code with the syntax virtual function_name()=0.
In your code, a stack buffer has been overflowed while writing zeros. The zeros have been written beyond the end of the stack buffer, over the preserved return address. When the function later executes its ret instruction, the value 0x00000000 (NULL) is loaded from the overwritten memory spot. This type of error, stack overflow, is the eponym of our forum.
Since you mention that you are calling a third-party library, I will point out that it may be a situation of the library expecting you to provide a non-NULL function pointer as input to some API. These are sometimes known as "call back" functions.
You will have to use the debugger to narrow down the cause of your problem further, but the above possiblities should help you solve the riddle.
An access violation at anywhere near adress '00000000' indicates a null pointer access. You're using something before it's ever been created, most likely, or after it's been FreeAndNil()'d.
A lot of times this is caused by accessing a component in the wrong place during form creation, or by having your main form try and access something in a datamodule that hasn't been created yet.
MadExcept makes it pretty easy to track these things down, and is free for non-commercial use. (Actually, a commercial use license is pretty inexpensive as well, and well worth the money.)
You start looking near that code that you know ran, and you stop looking when you reach the code you know didn't run.
What you're looking for is probably some place where your program calls a function through a function pointer, but that pointer is null.
It's also possible you have stack corruption. You might have overwritten a function's return address with zero, and the exception occurs at the end of the function. Check for possible buffer overflows, and if you are calling any DLL functions, make sure you used the right calling convention and parameter count.
This isn't an ordinary case of using a null pointer, like an unassigned object reference or PChar. In those cases, you'll have a non-zero "at address x" value. Since the instruction occurred at address zero, you know the CPU's instruction pointer was not pointing at any valid instruction. That's why the debugger can't show you which line of code caused the problem — there is no line of code. You need to find it by finding the code that lead up to the place where the CPU jumped to the invalid address.
The call stack might still be intact, which should at least get you pretty close to your goal. If you have stack corruption, though, you might not be able to trust the call stack.
If you get 'Access violation at address 00000000.', you are calling a function pointer that hasn't been assigned - possibly an event handler or a callback function.
for example
type
TTest = class(TForm);
protected
procedure DoCustomEvent;
public
property OnCustomEvent : TNotifyEvent read FOnCustomEvent write FOnCustomEvent;
end;
procedure TTest.DoCustomEvent;
begin
FOnCustomEvent(Self);
end;
Instead of
procedure TTest.DoCustomEvent;
begin
if Assigned(FOnCustomEvent) then // need to check event handler is assigned!
FOnCustomEvent(Self);
end;
If the error is in a third party component, and you can track the offending code down, use an empty event handler to prevent the AV.
When I've stumbled upon this problem I usually start looking at the places where I FreeAndNil() or just xxx := NIL; variables and the code after that.
When nothing else has helped I've added a Log() function to output messages from various suspect places during execution, and then later looked at that log to trace where in the code the access violation comes.
There are ofcourse many more elegant solutions available for tracing these violations, but if you do not have them at your disposal the old-fashioned trial & error method works fine.
It's probably because you are directly or indirectly through a library call accessing a NULL pointer. In this particular case, it looks like you've jumped to a NULL address, which is a b bit hairier.
In my experience, the easiest way to track these down are to run it with a debugger, and dump a stack trace.
Alternatively, you can do it "by hand" and add lots of logging until you can track down exactly which function (and possibly LOC) this violation occurred in.
Take a look at Stack Tracer, which might help you improve your debugging.
Use MadExcept. Or JclDebug.
I will second madExcept and similar tools, like Eurekalog, but I think you can come a good way with FastMM also. With full debugmode enabled, it should give you some clues of whats wrong.
Anyway, even though Delphi uses FastMM as default, it's worth getting the full FastMM for it's additional control over logging.
Here is a real quick temporary fix, at least until you reboot again but it will get rid of a persistent access. I had installed a program that works fine but for some reason, there is a point that did not install correctly in the right file. So when it cannot access the file, it pops up the access denied but instead of just one, it keeps trying to start it up so even searching for the location to stop it permanently, it will continue to pop up more and more and more every 3 seconds. To stop that from happening at least temporarily, do the following...
Ctl+Alt+Del
Open your Task Manager
Note down the name of the program that's requesting access (you may see it in your application's tab)
Click on your Processes tab
Scroll through until you find the Process matching the program name and click on it
Click End Process
That will prevent the window from persistently popping up, at least until you reboot. I know that does not solve the problem but like anything, there is a process of elimination and this step here will at least make it a little less annoying.

Resources