Is there a way to reliable force SDL_Init() to fail for use in a test case?
I think you can force it fail by not including the SDL dynamically linked library (SDL.dll).
Related
I would like to be able to control from inside my library if it is allowed to be loaded or not without using exceptions, meaning for some cases i would like dlopen("mylib.so") to return NULL and only if all conditions are right it will succeed.
Many have asked about the motivation, inside my library i use dlopen several times and i want to make sure all needed components have been loaded before my library can be loaded.
Take in mind i have to use standard solutions, meaning i can't use external plugins or do things like rewriting dlopen.
This is probably some XY problem. We cannot guess your motivation and goals (and these are what really matters). What you want to do is not possible on Linux.
But read carefully and several times the dlopen(3) man page. You'll notice that since "mylib.so" has no / it is handled specifically by using the LD_LIBRARY_PATH environment variable. That is why I generally use an absolute file path for dlopen. See e.g. realpath(3), glob(3), wordexp(3). Notice that there is no documented way to make the dlopen fail outside of the documented failure cases, that is:
On success, dlopen() and dlmopen() return a non-NULL handle for the
loaded library. On error (file could not be found, was not readable,
had the wrong format, or caused errors during loading), these
functions return NULL.
Then you can use dlerror(3) to understand the error cause.
So you could play wild tricks with that LD_LIBRARY_PATH but you should not. You might be weird (actually crazy) enough to e.g. use putenv(3) on that, or add into that path a directory inside some FUSE filesystem managed by your program, or do some LD_PRELOAD trick. But you really should not do such insane tricks.
So be reasonable: solve your actual need in some other ways. Expect dlopen to behave as documented (so to usually succeed), and don't call it if you don't want to. When coding, it is important to use your common sense.
Be aware of rpath (it could be explicitly set at link time), and read carefully Program Library HowTo and Drepper's How To Write Shared Libraries. Read also the C++ dlopen minihowto and be aware of name mangling.
Notice that in practice dlopen is part of your C standard library on Linux, and that libc and ld-linux.so(8) is generally some free software (e.g. GNU glibc or musl-libc). So if you are not happy with the system's dlopen, you could in principle change it (but I don't recommend doing that, since libc is the cornerstone of every Linux system).
You could consider (probably not a good idea) to use some ELF parsing library (like libelf, libbfd, ...) or some ELF analyzing program (like readelf(1) or objdump(1) ...) on that shared object before your dlopen (but a malicious process or user might still alter the shared library after the analysis but before dlopen). You could study the elf(5) format yourself and do such a parsing by hand (probably even more bad idea).
If you are writing that mylib.so library (on Linux, and perhaps some other similar OSes; but this behaviour is non-standard since non-specified in POSIX dlopen), you could be interested by function attributes like __attribute__((constructor)) & __attribute__((visibility)) (see also this and that). If you want to "reject" being dlopen-ed (when some conditions are met) from your mylib.so you could consider having some constructor function testing these conditions and calling exit when they fail. If your mylib.so is a plugin loaded from some other program that you could improve, you might simply seek some initialization function with dlsym, call it after the dlopen, and fail the main program if that initialization function failed. BTW, throwing some C++ exception from such a constructor function (or some obsolete _init one) is unwise, because the dlopen machinery might consume internal resources that won't be released in that case.
At last, in theory, you could re-implement dlopen yourself (above open(2), mmap(2) etc... and care about the relocations in ELF explicitly). That could take a few years (and is processor specific). Study the appropriate x86 ABI.
You probably can achieve your (unstated) goal by just using the usual dlopen, and do some test before it, and perhaps some test (using dlsym) after it. Most programs using plugins are doing that.
Perhaps you might have every exported function of mylib.so do appropriate checks when running. Maybe you could have some static boolean flag set by some function with __attribute__((constructor)) (so it would be called once at dlopen time) and have other public functions check that flag.
In a recent edit you explain at last:
inside my library i use dlopen several times and i want to make sure all needed components have been loaded before my library can be loaded.
There is no need to play with dlopen or its constructors (and you probably don't need to use dlopen inside your library; and if you do that, you need to explain why, how, and where). You just link mylib.so with all the required shared libraries it uses (see this). If they are not loadable or accessible at dlopen time the entire dlopen of mylib.so fails (intuitively, on Linux, dynamic loading is somehow "recursive").
BTW, if you indeed call dlopen inside your mylib.so, that dlopen happens after mylib.so has been dlopen-ed (unless you call dlopen from some constructor function of mylib.so, which is weird but should be ok and makes a different question).
As far as I remember, no, you can't, at least in a normal way. If the library exists at given path, it will be loaded. The dlopen it is not designed to do any "business checks" for you at your discretion. At most, it will abide any filesystem permissions/etc and return error if process has no access to the file, and that's it.
If you have full control on the code that will load your library, then wrap it like Atterson suggested and use dlopen2 and it's done.
If you don't have full control, then dlopen2 would still not prevent anyone from using the original dlopen and bypass the checks. You could try to make it more smart, for example, make your dlopen2 do something detectable so then the library can deny working if it was opened by dlopen instead of dlopen2, but then.. someone could fake up that "something detectable", then use dlopen, done. Then it boils down to making that "something detectable" hard to reproduce by attackers.
Simply, it was not intended to do these things. It's meant to load the library if the OS allows (~filesystem permissions, etc).
For any other "access checks" like "do you have license? no? then go away" you have to implement it inside the library. Let them load it via dlopen, then make the library check the permissions for example, at each call to its functions. Do use exceptions, or just do-nothing and return NULLs. Or even better, you probably could use initialization function (see https://stackoverflow.com/a/1602459/717732 + http://tldp.org/HOWTO/Program-Library-HOWTO/miscellaneous.html#INIT-AND-CLEANUP) and do the check once when the lib gets loaded. Note that this functions take and return void so there's still no way to make the dlopen fail, but at least the library can have its moment to disable its functions.
You could always wrap it into a function
void *dlopen2(const char *filename, int flags){
if(/*your conditions*/)
return void *dlopen(filename, flags);
return (void *) NULL;
}
The correct way to deal with this kind of scenarios, is to make use of seccomp and limit what the dlopen call is allowed to do.
http://man7.org/linux/man-pages/man3/seccomp_rule_add.3.html
Naturally such configuration requires root access.
Do i need to use valgrind on each program file with which ".so" is made.. or is there any we can run valgrind directly on ".so" library. please provide steps for later.
Not directly. Library does not have an entry point where to start executing it, and valgrind only checks code that is actually executing.
Still, if you want to test a library with valgrind, there is a simple way. Just write a test program, which uses the library in the way that tests the parts and features of library you want tested. Then valgrind that.
It is probably better to write several small test programs to test different features and use patterns, instead if one big one which tries to test everything in one execution (easier to isolate any problem valgrind finds, faster to run).
Valgrind watches upon code that being executed. Shared library is never executed unless some program uses them. If some code never executed, valgrind will never notice it.
I have read the documentation and I understand that it is possible to use the BOOST_ASIO_DISABLE_IOCP preprocessor definition to be able to call cancel() on a socket in Windows XP. The Boost library will then use a select-based solution instead and everything should work fine.
If this statements are true, what are the drawbacks of the select-based approach? Why we shouldn't always define BOOST_ASIO_DISABLE_IOCP?
EDIT 1
I have compiled the DLL with BOOST_ASIO_DISABLE_IOCP defined without problems. Unfortunately, after the integration with the final application, I'm getting memory access errors. Is there any additional configuration I am missing?
IOCP should provide much better perfomance.
By the way, do you really have to use cancel? Note that after you cancel i/o operations on a socket, you have no idea what the actual state of you data flow is, so you'll need a sophisticated way to get synchronized with your peer. Thus, usually the right way to go is to close the socket.
Unfortunately, after the integration with the final application, I'm
getting memmroy access errors.
Perhaps, you've got several modules that use Boost.Asio headers, but haven't defined BOOST_ASIO_DISABLE_IOCP for all of them, causing ODR violation?
I believe task I am trying to accomplish is fairly easy, but I have still managed to run into a problem, thus some help is appreciated.
I have got a base class (in a header and a source file), which I am subclassing two times as part of my program, lets call it WorkerBase. One of subclasses WorkerA is fairly trivial, whilst the other, WorkerB, depends on third-party libraries that depend on the hardware which program is running on. If hardware is unsuitable or those libraries are missing, using that subclass results in a fail. In this case, I would like to use WorkerA.
So, basically, how do I detect library loading failure? Now main program just wouldn't start if library is missing.
I am using Qt and the program is going to be Windows-only. Thank you.
I think, the simplest solution would be to move Woker's to plugins.
You can load plugin with QPluginLoader dynamically during run-time.
Then, while WorkerB would be statically linked to 3rd party lib, if required dependencies for WorkerB would not be satisfied, WorkerB plugin will simply fail to load, you would catch that with QPluginLoader and load WorkerA plugin instead.
The other way is to reinvent the wheel your own plugin system using QLibrary (and QPluginLoader as a reference realization).
Possibly that helps
http://developer.qt.nokia.com/doc/qt-4.8/qlibrary.html
bool QLibrary::load ()
Loads the library and returns true if the library was loaded successfully; otherwise returns false. Since resolve() always calls this function before resolving any symbols it is not necessary to call it explicitly. In some situations you might want the library loaded in advance, in which case you would use this function.
I'm giving a try at OpenCL, and in order to put this in production I'd like to be able to bind dynamically to OpenCL.DLL (when under Windows), in order to handle 'gracefully' the case where no OpenCL is installed on the host computer.
Is there any available library (or code snippet) that takes care of this dynamic binding in C or C++, much like GLEW does for OpenGL ? I'd like to avoid the hassle to do it myself.
Thanks,
Here you go:
http://clcc.sourceforge.net/clew_8h.html
Since you're dealing with Win32, the easiest solution is delay loading. If you delay-load OpenCL, and the compiler-added stub fails to find it, it will call __pfnDliFailureHook2(dliFailLoadLib). You can handle the error there; if you don't provide a handler you'll get the default behavior (program aborts). In either case the program will not have a static dependency on OpenCL.
QtOpenCL http://labs.qt.nokia.com/2010/04/07/using-opencl-with-qt/