I'm using GLFW and am getting confused by the logic of using libraries. According to my understanding of functions, when a function is called, the code within is executed and any memory allocated by said function is deallocated at the end of it. Although when calling glfwInit() for example, this allows for the subsequent use of other GLFW functions. My intuition is that this function call would have no effect on the code after it, so how is this happening?
Related
In Ubuntu 14.04, I have a C++ API as a shared library which I am opening using dlopen, and then creating pointers to functions using dlsym. One of these functions CloseAPI releases the API from memory. Here is the syntax:
void* APIhandle = dlopen("Kinova.API.USBCommandLayerUbuntu.so", RTLD_NOW|RTLD_GLOBAL);
int (*CloseAPI) = (int (*)()) dlsym(APIhandle,"CloseAPI");
If I ensure that during my code, the CloseAPI function is always called before the main function returns, then everything seems fine, and I can run the program again the next time. However, if I Ctrl-C and interrupt the program before it has had time to call CloseAPI, then on the next time I run the program, I get a return error whenever I call any of the API functions. I have no documentation saying what this error is, but my intuition is that there is some sort of lock on the library from the previous run of the program. The only thing that allows me to run the program again, is to restart my machine. Logging in and out does not work.
So, my questions are:
1) If my library is a shared library, why am I getting this error when I would have thought a shared library can be loaded by more than one program simultaneously?
2) How can I resolve this issue if I am going to be expecting Ctrl-C to be happening often, without being able to call CloseAPI?
So, if you do use this api correctly then it requires you to do proper clean up after use (which is not really user friendly).
First of all, if you really need to use Ctrl-C, allow program to end properly on this signal: Is destructor called if SIGINT or SIGSTP issued?
Then use a technique with a stack object containing a resource pointer (to a CloseAPI function in this case). Then make sure this object will call CloseAPI in his destructor (you may want to check if CloseAPI wasn't called before). See more in "Effective C++, Chapter 3: Resource Management".
That it, even if you don't call CloseAPI, pointer container will do it for you.
p.s. you should considering doing it even if you're not going to use Ctrl-C. Imagine exception occurred and your program has to be stopped: then you should be sure you don't leave OS in an undefined state.
I am working with a program where my code calls a third party library which uses boost and shared_pointers to create a large and complex structure. This structure is created in a method that I call and at the end of the method I know that the program is finished.
For a large sample that I am handling the code to handle the processing takes 30 minutes and the boost code called automatically at exit takes many hours. Exiting the program without releasing the memory and spending all that time would be a perfectly acceptable outcome.
I tried
vector *iddListV = new vector(); // this WILL leak memory
with all the relevant structures added to the vector but this does not help.
I also tried calling exit(0); before reaching the end of the subroutine. This also causes the boost code to spend many hours trying to release pointers.
How to I get a C++ program (Microsoft C++ on Windows if that matters) to abruptly exit without calling the boost destructors.
My constraints are I can call any function before the boost structure are allocated but cannot modify the code once it starts running.
_Exit quits without calling any destructors.
If you're unconcerned about portability, you can call TerminateProcess(). But remember to take care that you are absolutely sure that your program is in a state which is ready to terminate. For example, if you terminate before I/O has had a chance to flush, then your file data and network streams may become invalid.
It is possible, in a portable manner, to do:
#include <exception>
...
std::terminate();
However, there's a big gotcha, in that, at least on linux, this may cause a core dump. (I'm really not sure what the behavior is on Windows).
It should be noted, that the behavior is implementation defined as far as whether or not destructors are called. Siting §15.5.1 P2:
In the situation where the search for a handler (15.3) encounters the
outermost block of a function with a noexcept-specification that does
not allow the exception (15.4), it is implementation-defined whether
the stack is unwound, unwound partially, or not unwound at all before
std::terminate() is called.
Additionally in §18.8.3.4 P1:
Remarks: Called by the implementation when exception handling must be
abandoned for any of several reasons (15.5.1), in effect immediately
after evaluating the throw-expression (18.8.3.1). May also be called
directly by the program.
C++11 also defines the function std::quick_exit(int status) that can be used in a similar manner (presumably without a coredump). This function is available from <cstdlib>.
The problem I've encountered is generated by the probable misuse of threading within a simplistic FreeGLUT C++ application.
Since exiting the glutMainLoop() cannot be done elegantly, I rely on glutLeaveMainLoop() to do some of the work, but this one doesn't really give the control back to the program's main function. I have a global pointer that will be set in the main function, prior to the GL calls, to an object instance created on the heap. Without using the atexit callback, nobody will call the delete operator on this instance, although I placed such an operation after the glutMainLoop call (now commented because of its futility).
Here's a pseudocode for what I'm doing (I won't post the actual code since it's too long to filter):
CWorld* g_world;
AtExit()
{
delete g_world;
}
void main()
{
atexit(AtExit);
// create an instance of an object that creates a thread in its constructor
// via the new operator and joins this thread in its destructor
// calling the delete operator on that pointer to the thread instance
CWidget thisObjectCreatesATinyThread;
g_world = new CWorld();
...
glutMainLoop();
// delete g_world;
}
Note that in the main function, I also included a widget instance that does some work via a thread created in its constructor. This thread is joined in its destructor, then the memory is deallocated via a delete.
The wrong behaviour: without setting the atexit callback, I get a resource leak, since the destructor of the CWorld object won't get called. If I set this callback, then the delete operator gets called twice for some reason, even though the AtExit function is called only once.
What is the place to look for the source of this odd behaviour?
Even if I disable the CWidget instantiation, I still get the peculiar behaviuor.
I assume you're not using the original GLUT library (since it's ancient) but rather FreeGLUT, which is the most wide-spread GLUT implementation. In order to have glutMainLoop() return, you would do:
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
before calling glutMainLoop(). This will cause it to return if there are no more active top-level windows left when you call glutLeaveMainLoop(). If you don't care about still active windows, instead do:
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
You probably have to include <GL/freeglut.h> instead of <GL/glut.h> in order to get the definitions.
I have an application that does not use the standard libraries. Instead, it uses stubs to call LoadLibrary/GetProcAddress, then calls functions via the resultant function pointers.
Using the above method my application is calling DoDragDrop in ole32.dll. The call is returning E_UNEXPECTED, which apparently means 'catastophic failure'.
What I want to ask is does anyone know of a way to discover what is happening inside the call to DoDragDrop? Specifically, can I discover what function or variable it is looking for but cannot find? (I am guessing that it wants access to some function or variable that is not loaded at the point I call DoDragDrop, and if I can explicitly load it the call will succeed.) Obviously I can't step into the call - attempting to just runs the function and steps to the line in my code following the DoDragDrop call.
:)
(I'm using VS2005 in XP.)
I recall having something like this occur when I had forgotten to call OleInitialize(Ex) / CoInitialize(Ex) for the thread making the call. Note the apartment must be STA.
I am creating a C++ Win32 dll with some global data. There is a std::map defined globally and there are exported functions in the dll that write data into the map (after acquiring a write lock, ofcourse).
My problem is, when I call the write function from inside the dll DllMain, it works without any problems. But when I load the dll from another program and call the function that writes data into the global map, it gives me this error:
WindowsError: exception: access violation reading 0x00000008
Is there something that can be done about this? The same function when called from DllMain has access to the global data in the dll, but when called from a different process, it doesn't have access to the global data. Please advice.
I am using the TDM-MinGW gcc 4.4.0 Compiler.
EDIT:
Ok, I've figured out what the problem is, and thanks for the help guys, but the problem was not with a constructor issue or inability to have maps in global space, but an issue in the boost::python that I'm using. I had tested it, but since I was calling the dll from within python or maybe something, the urllib2 module wasn't getting loaded into the dll. Now I have to see how to fix it.
Looks like the constructor of std::map did not run yet when your code was called. Lifetime of global non-PODs in a Win32 DLL is pretty tricky, and I'm not certain as to how MinGW specifically handles it. But it may be that the way you're compiling the DLL, you've set your own function (DllMain?) as an entry point, and thus overrode the CRT initialization routine that calls constructors.
A read error at such a low memory address generally means that you are trying to access a NULL pointer somewhere. Can you show your actual code?
You have to use shared memory, because the different processes have separate address spaces.
I think you won't get std::map running. I would recommend using MapViewOfFile, CreateFileMapping, OpenFileMapping, ... and plain old data. Ask Google / MSDN.