undefined references to __cxa_atexit
undefined references to __cxa_atexit
I'm writing my kernel in C++. I'm trying to enable global/static constructors and destructors. I figured out how to use the .ctors and .dtors sections to call the constructors and destructors. The problem is that the code the compiler (gcc v3.2) generates to interface directly with the constructors and destructors of the global objects also calls the function __cxa_atexit. From what I've seen doing an Internet search for it, it looks like this function isn't needed and you can (supposedly) get rid of the reference to it somehow, but I don't know how. And, despite my searching, I'm still not sure exactly what it's supposed to do. So does anybody know if it's needed, what it's there for, if you can get rid of it and, assuming you can, how?
RE:undefined references to __cxa_atexit
I can only guess here, but it seems like it must register the destructor to run in case the program exits, similar to C's atexit(). You probably want to write your own equivalent function so that destructors still work on exit.
RE:undefined references to __cxa_atexit
Okay, so what I get from what you said and doing a little more research is that the prototype of __cxa_atexit is:
int __cxa_atexit(void (*func) (void *), void *arg, void *d);
And it's a way of telling my kernel at runtime that I need to call 'func' of shared object 'd' with the argument 'arg' before shutting down the kernel, in addition to any functions listed in the .dtors section of the file. So if I don't properly implement this function, then some important destructors and/or other functions may not be called. And it seems logical to me, that the functions should be called in reverse of the order in which they were registered(e.g. if A.~a() was registered before B.~b() than B.~b() should be called before A.~a(), because object B may depend in some way on object A). Is all of this correct?
int __cxa_atexit(void (*func) (void *), void *arg, void *d);
And it's a way of telling my kernel at runtime that I need to call 'func' of shared object 'd' with the argument 'arg' before shutting down the kernel, in addition to any functions listed in the .dtors section of the file. So if I don't properly implement this function, then some important destructors and/or other functions may not be called. And it seems logical to me, that the functions should be called in reverse of the order in which they were registered(e.g. if A.~a() was registered before B.~b() than B.~b() should be called before A.~a(), because object B may depend in some way on object A). Is all of this correct?
RE:undefined references to __cxa_atexit
Uhm... sort of... I think what was meant, is that __cxa_atexit is constructed, at compile time, by the compiler, and includes calls to all the destructors.
In other words, it accepts no parameters, and probably returns nothing either. It's merely a container function to put all your clean up code in (ie, all your destructors should be called in here).
btw: destructors don't take arguments, do I don't understand your prototype above.
Simply put, if you define:
void __cxa_atexit(void) {
}
You'll probably eliminate this compiler error.
Cheers,
Jeff
In other words, it accepts no parameters, and probably returns nothing either. It's merely a container function to put all your clean up code in (ie, all your destructors should be called in here).
btw: destructors don't take arguments, do I don't understand your prototype above.
Simply put, if you define:
void __cxa_atexit(void) {
}
You'll probably eliminate this compiler error.
Cheers,
Jeff
RE:undefined references to __cxa_atexit
Uh... have you done any research into this? Yes, you can eliminate any linker error by simply defining the symbol, but sometimes symbols are there for a reason. After researching it, I'm sure that this one is. Also, destructors take ONE argument, namely a pointer to the object being destroyed. You don't see it in your C++ code, but it's there. But even if they didn't, there are other types of cleanup functions, which may take arguments. As for the prototype, I got it from http://www.linuxbase.org/spec/refspecs/ ... texit.html
In searching for information, I have found that it is a fairly common belief that atexit (and __cxa_atexit) should call the destructors itself, but based on the description of it at the above URL, rexlunae's comment and from dissasembling the __static_initialization_and_destruction function (which is the compiler generated function that calls __cxa_exit) I can clearly see that this isn't the case. I appreciate your attempt at helping me, though. I just wanted to know if anyone who knows much about the subject can verify everything I said in my last post or add more insight.
In searching for information, I have found that it is a fairly common belief that atexit (and __cxa_atexit) should call the destructors itself, but based on the description of it at the above URL, rexlunae's comment and from dissasembling the __static_initialization_and_destruction function (which is the compiler generated function that calls __cxa_exit) I can clearly see that this isn't the case. I appreciate your attempt at helping me, though. I just wanted to know if anyone who knows much about the subject can verify everything I said in my last post or add more insight.
RE:undefined references to __cxa_atexit
I would be a little bit surprised if __cxa_atexit is created by the compiler (for one thing, xSadar probably would have seen it and not asked this question), it probably uses the POSIX atexit() function to register destructors. In C, atexit() builds a list of functions that should be called when exit() is called (_exit() bypasses this). I can only assume that this function, because of the similar name, would work the same way.
Pardon the speculation, but I can guess pretty well how this works. Every constructor for an object with a destructor defined makes a call to __cxa_atexit(), passing the address of the destructor as a parameter. Then, if the program exit()s, the destructors are called. It is not created at compile time, it is part of the standard C++ libraries. Once again, I am speculating, I generally use plain C, not C++, but I am pretty sure this is how it would have to work.
Pardon the speculation, but I can guess pretty well how this works. Every constructor for an object with a destructor defined makes a call to __cxa_atexit(), passing the address of the destructor as a parameter. Then, if the program exit()s, the destructors are called. It is not created at compile time, it is part of the standard C++ libraries. Once again, I am speculating, I generally use plain C, not C++, but I am pretty sure this is how it would have to work.
RE:undefined references to __cxa_atexit
Thanks for the help. Based on what I've seen, it looks like __cxa_atexit is supposed to do virtually the same thing as atexit. So it looks like you're right. There are at least some minor differences though. If I had known that atexit was a POSIX function, I probably could have figured out more sooner. But now I was able to verify a few things that I was guessing were true. I just wish I could get a full description of __cxa_atexit. Is there any way to get the C and C++ standards for free (or for very little)?
Okay, I've found everything I need.
I guess I should read more carefully. I remembered that __cxa_atexit() was similar to atexit, but forgot this: "__cxa_atexit() has the same specification as atexit()"
- http://www.linuxbase.org/spec/refspecs/ ... texit.html
Only the prototype is different, and I understand those differences, and now that I know that atexit is POSIX standard I know that I can just type "man atexit" anytime I want its specification.
- http://www.linuxbase.org/spec/refspecs/ ... texit.html
Only the prototype is different, and I understand those differences, and now that I know that atexit is POSIX standard I know that I can just type "man atexit" anytime I want its specification.
RE:undefined references to __cxa_atexit
"Is there any way to get the C and C++ standards for free (or for very little)?"
I wish there was, but the only way to get it for free isn't legal.
I wish there was, but the only way to get it for free isn't legal.