Is it safe to call dlclose(NULL)? - linux

I experience a crash when I pass a null pointer to dlclose.
Should I check for null before calling dlclose?
POSIX tells nothing about this:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/dlclose.html
Is it undefined behaviour or a bug in dlclose implementation?

This is tricky. POSIX states that
if handle does not refer to an open object, dlclose() returns a non-zero value
from which you could infer that it should detect, for an arbitrary pointer, whether that pointer refers to an open object. The Linux/Glibc version apparently does no such check, so you'll want to check for NULL yourself.
[Aside, the Linux manpage isn't very helpful either. It's quite implicit about libdl functions' behavior, deferring to POSIX without very clearly claiming conformance.]

It also says nothing about being accepting a NULL and not crashing. We can assume from your test that it doesn't do an explicit NULL check, and it does need to use the pointer somehow to perform the closing action … so there you have it.

Following the malloc/free convention (1), it is a bug. If it follows the fopen/fclose convention (2) it is not. So if there is a bug, it is in the standard because it lacks convention for dealing with zombies.
Convention (1) works well with C++11 move semantics
Convention (2) leaves more responsibility to the caller. In particular, a dtor must explicitly check for null if a move operation has been done.
I think this is something that should be revised for an upcoming POSIX revision in order to avoid confusion.
Update
I found from this answer https://stackoverflow.com/a/6277781/877329, and then reading man pthread_join that you can call pthread_join with an invalid tid, supporting the malloc/free convension. Another issue I have found with the dynamic loader interface is that it does not use the standard error handling system, but has its own dlerrorfunction.

Related

Analyzing a crash from a rust-generated C library

I needed to call Rust code from my Go code. Then I used C as my interface. I did this:
I've created a Rust library that takes a CStr as a parameter, and returns a new processed string back as CStr.
This code is statically compiled to a static C library my_lib.a.
Then, this library is statically linked with my Go code, that then calls the library API using CGo (Go's representation to C String, just like Rusts's Cstr).
The final Go binary is sitting inside a docker container in my kubernetes. Now, my problem is that is some cases where the library's API is called, my pod (container) is crashing. Due to the nature of using CStr and his friends, I must use unsafe scopes in some places, and I highly suspect a segfault that is caused by one of the ptrs used in my code, but I have no way of communicating the error back to the Go code that could be then printed OR alternatively get some sort of a core dump from Rust/C so I can point out the problematic code. The pod just crashes with no info whatsoever, at least to my knowledge..
So my question is, how can I:
Recover from panic/crashes that happen inside an unsafe code? or maybe wrap it with a recoverable safe scope?
Override the SIG handlers so I can at least "catch" the errors and not crash? So I can debug it.
Perhaps communicate a signal interruption that was caused in my c-lib that was generated off Rust back to the caller?
I realize that once Rust is compiled to a c-library, it is a matter of C, but I have no idea how to tackle this one.
Thanks!
I've created a Rust library that takes a CStr as a parameter, and returns a new processed string back as CStr.
Neither operation seems OK:
the CStr documentation specifically notes that CStr is not repr(C)
CStr is a borrowed string, a "new processed string" would have to be owned (so a CString, which also isn't repr(C)).
Due to the nature of using CStr and his friends, I must use unsafe scopes in some places, and I highly suspect a segfault that is caused by one of the ptrs used in my code, but I have no way of communicating the error back to the Go code that could be then printed OR alternatively get some sort of a core dump from Rust/C so I can point out the problematic code. [...] Recover from panic/crashes that happen inside an unsafe code? or maybe wrap it with a recoverable safe scope?
If you're segfaulting there's no panic or crash which Rust can catch or manipulate in any way. A segfault means the OS itself makes your program go away. However you should have a core dump the usual way, this might be a configuration issue with your container thing.
Override the SIG handlers so I can at least "catch" the errors and not crash? So I can debug it.
You can certainly try to handle SIGSEGV, but after a SIGSEGV I'd expect the program state to be completely hosed, this is not an innocuous signal.

can pthread_mutexattr_setrobust apply to pthread_rwlock_t?

the robustness of mutex is very important to my program since it can handle the case when a process died without releasing the mutex.
But according to the document, pthread_mutexattr_setrobust only apply to pthread_mutex_t, instead of pthread_rwlock_t, is there any approach to set the robustness of pthread_rwlock_t? Or its implementation is robust by default?
according to the document, pthread_mutexattr_setrobust only apply to pthread_mutex_t
More precisely, pthread_mutexattr_setrobust() sets a property of a pthread_mutexattr_t object, and these are used (only) for configuring objects of type pthread_mutex_t. This happens at initialization of the mutex via pthread_mutex_init().
The corresponding initialization function for read/write locks is pthread_rwlock_init(), and its documentation shows that the corresponding attribute object type, accepted by that function, is pthread_rwlockattr_t. Implementations may provide whatever properties they like as extensions, but the only one specified for this type by the current version of POSIX is pshared. Thus no, there is no (portable) robustness option for pthreads read/write locks.

C++11 thread safe singleton using lambda and call_once: main function (g++, clang++, Ubuntu 14.04)

All!
I am new to C++11 and many of its features.
I am looking for a C++11 (non boost) implementation of a thread safe singleton, using lambda and call_once (Sorry... I have no rights to include the call_once tag in the post).
I have investigated quite a lot (I am using g++ (4.8, 5.x, 6.2), clang++3.8, Ubuntu 14.04, trying to avoid using boost), and I have found the following links:
http://www.nuonsoft.com/blog/2012/10/21/implementing-a-thread-safe-singleton-with-c11/comment-page-1/
http://silviuardelean.ro/2012/06/05/few-singleton-approaches/ (which seems to be very similar to the previous one, but it is more complete, and provides at the end its own implementation).
But: I am facing these problems with the mentioned implementations: Or I am writing a wrong implementation of main function (probable), or there are mistakes in the posted codes (less probable), but I am receiving different compiling / linking errors (or both things at the same time, of course...).
Similar happens with following code, which seems to compile according to comments (but this one does not use lambda, neither call_once):
How to ensure std::call_once really is only called once (In this case, it compiles fine, but throws the following error in runtime):
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
Aborted (core dumped)
So, could you help me, please, with the correct way to call the getInstance() in the main function, to get one (and only one object) and then, how to call other functions that I might include in the Singleton? (Something like: Singleton::getInstance()->myFx(x, y, z);?
(Note: I have also found several references in StackOverflow, which are resolved as "thread safe", but there are similar implementations in other StackOverflow posts and other Internet places which are not considered "thread safe"; here are a few example of both (these do not use lambda) ):
Thread-safe singleton in C++11
c++ singleton implementation STL thread safe
Thread safe singleton in C++
Thread safe singleton implementation in C++
Thread safe lazy construction of a singleton in C++
Finally, I will appreciate very much if you can suggest to me the best books to study about these subjects. Thanks in advance!!
I just ran across this issue. In my case, I needed to add -lpthread to my compilation options.
Implementing a singleton with a static variable as e. g. suggested by Thread safe singleton implementation in C++ is thread safe with C++11. With C++11 the initialization of static variables is defined to happen on
exactly one thread, and no other threads will proceed until that initialization is complete. (I can also backup that with problems we recently had on an embedded platform when we used call_once to implement a singleton and it worked after we returned to the "classic" singleton implementation with the static variable.)
ISO/IEC 14882:2011 defines in §3.6.2 e. g. that
Static initialization shall be performed before any dynamic initialization takes place.
and as part of §6.7:
The zero-initialization (8.5) of all block-scope variables with static
storage duration (3.7.1) or thread storage duration (3.7.2) is
performed before any other initialization takes place.
(See also this answer)
A very good book I can recommend is "C++ Concurrency in Action" by A. Williams. (As part of Chapter 3 call_once and the Singleton pattern is discussed - that is why I know that the "classic Singleton" is thread safe since C++11.)

Is synchronization needed inside FinalConstruct()/FinalRelease()?

In my free-threaded in-proc COM object using ATL I want to add a member variable that will be set only in FinalConstruct() and read only in FinalRelease(). No other code will ever manipulate that member variable.
I doubt whether I need synchronization when accessing that member variable. I carefully read ATL sources and looks like those methods are always called no more than once and therefore from one thread only.
Is that correct assumption? Can I omit synchronization?
Yes, the assumption is correct. Think of it as an extension of the C++ constructor and destructor. In theory, you could call a method on a COM object from a different thread, while FinalRelease() is executing. Although, that is undefined behaviour, and not an expected occurrence. You shouldn't try to protect yourself from it, just as you wouldn't try to protect yourself from other threads in a destructor. If you have to protect yourself in the destructor, the design is generally broken (it would indicate that you do not have a proper termination protocol between your threads).
The only way FinalRelease() could be called from another thread, is when the client code does not have a valid reference count to your object, or if some other parts of your code is releasing twice. This is a hard error, and will probably end up in a crash anyway, totally unrelated to any synchronization errors you might have. The ATL code for managing object reference count is thread safe, and will not leave any race conditions open.
As for FinalConstruct(), a reference to the object is not returned to any client before FinalConstruct() has finished with a successful return code.

Is this a safe version of double-checked locking?

Slightly modified version of canonical broken double-checked locking from Wikipedia:
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
// Create new Helper instance and store reference on
// stack so other threads can't see it.
Helper myHelper = new Helper();
// Atomically publish this instance.
atomicSet(helper, myHelper);
}
}
}
return helper;
}
}
Does simply making the publishing of the newly created Helper instance atomic make this double checked locking idiom safe, assuming that the underlying atomic ops library works properly? I realize that in Java, one could just use volatile, but even though the example is in pseudo-Java, this is supposed to be a language-agnostic question.
See also:
Double checked locking Article
It entirely depends on the exact memory model of your platform/language.
My rule of thumb: just don't do it. Lock-free (or reduced lock, in this case) programming is hard and shouldn't be attempted unless you're a threading ninja. You should only even contemplate it when you've got profiling proof that you really need it, and in that case you get the absolute best and most recent book on threading for that particular platform and see if it can help you.
I don't think you can answer the question in a language-agnostic fashion without getting away from code completely. It all depends on how synchronized and atomicSet work in your pseudocode.
The answer is language dependent - it comes down to the guarantees provided by atomicSet().
If the construction of myHelper can be spread out after the atomicSet() then it doesn't matter how the variable is assigned to the shared state.
i.e.
// Create new Helper instance and store reference on
// stack so other threads can't see it.
Helper myHelper = new Helper(); // ALLOCATE MEMORY HERE BUT DON'T INITIALISE
// Atomically publish this instance.
atomicSet(helper, myHelper); // ATOMICALLY POINT UNINITIALISED MEMORY from helper
// other thread gets run at this time and tries to use helper object
// AT THE PROGRAMS LEISURE INITIALISE Helper object.
If this is allowed by the language then the double checking will not work.
Using volatile would not prevent a multiple instantiations - however using the synchronize will prevent multiple instances being created. However with your code it is possible that helper is returned before it has been setup (thread 'A' instantiates it, but before it is setup thread 'B' comes along, helper is non-null and so returns it straight away. To fix that problem, remove the first if (helper == null).
Most likely it is broken, because the problem of a partially constructed object is not addressed.
To all the people worried about a partially constructed object:
As far as I understand, the problem of partially constructed objects is only a problem within constructors. In other words, within a constructor, if an object references itself (including it's subclass) or it's members, then there are possible issues with partial construction. Otherwise, when a constructor returns, the class is fully constructed.
I think you are confusing partial construction with the different problem of how the compiler optimizes the writes. The compiler can choose to A) allocate the memory for the new Helper object, B) write the address to myHelper (the local stack variable), and then C) invoke any constructor initialization. Anytime after point B and before point C, accessing myHelper would be a problem.
It is this compiler optimization of the writes, not partial construction that the cited papers are concerned with. In the original single-check lock solution, optimized writes can allow multiple threads to see the member variable between points B and C. This implementation avoids the write optimization issue by using a local stack variable.
The main scope of the cited papers is to describe the various problems with the double-check lock solution. However, unless the atomicSet method is also synchronizing against the Foo class, this solution is not a double-check lock solution. It is using multiple locks.
I would say this all comes down to the implementation of the atomic assignment function. The function needs to be truly atomic, it needs to guarantee that processor local memory caches are synchronized, and it needs to do all this at a lower cost than simply always synchronizing the getHelper method.
Based on the cited paper, in Java, it is unlikely to meet all these requirements. Also, something that should be very clear from the paper is that Java's memory model changes frequently. It adapts as better understanding of caching, garbage collection, etc. evolve, as well as adapting to changes in the underlying real processor architecture that the VM runs on.
As a rule of thumb, if you optimize your Java code in a way that depends on the underlying implementation, as opposed to the API, you run the risk of having broken code in the next release of the JVM. (Although, sometimes you will have no choice.)
dsimcha:
If your atomicSet method is real, then I would try sending your question to Doug Lea (along with your atomicSet implementation). I have a feeling he's the kind of guy that would answer. I'm guessing that for Java he will tell you that it's cheaper to always synchronize and to look to optimize somewhere else.

Resources