-
-
Notifications
You must be signed in to change notification settings - Fork 606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
better handle exceptions thrown by dynamic linker #1116
Comments
Or the bug is as simple as trying to execute FINI functions when we did not really execute INIT functions because we failed earlier than that like in the case above. |
In auto ef = std::shared_ptr<object>(new file(*this, f, name),
[=](object *obj) { remove_object(obj); });
// ... some lines snipped
ef->load_needed(loaded_objects);
ef->relocate();
ef->fix_permissions();
_files[name] = ef;
_files[ef->soname()] = ef;
return ef; The intention of the deleter calling |
I this particular crash scenario, it was trying to invoke FINI functions before even any segments got mapped. I wonder if the right solution would be to add flags to the ELF object class to track if segments were loaded and INIT called and then during remove_object()/destruction only call unload_segments() and process fini function if segments were loaded and init functions invoked respectively. |
Hello! I can work on this issue, the desired solution to fix this is adding and using flags in the elf object as described in the above comment correct? If that is implemented the desired exception should be thrown? |
Hi, you are very welcome to work on this issue! I don't know if we need an additional flags or maybe we already have enough fields in class object but missing zero initialization, or perhaps we do have zero-initialization and missing a check for it in |
Thanks, I was able to reproduce this bug and it looks like the page fault occurs when the FINI function for a module that got successfully loaded is called when remove_object() is called for it (after trying and failing to load the broken file/module). Should the FINI functions for modules still get called if the program has failed to finish loading? |
No, the FINI functions should not get called if INIT were not called because the dynamic linker failed to load the object before that point. And we somehow need to be able to track it by examining the state of some member variables of the |
@wkozaczuk while it is true that in general, if exceptions can happen from anywhere, we need to remember exactly what was run and what was not. But perhaps the present problem is simpler... We have the exceptions all coming from the same place, before the object is even loaded, so it should be (? I didn't actually try...) fairly easy to know if we loaded the object or not, and if not, we certainly shouldn't call run_fini_funcs(). |
@nyh you are right that for now we should not overcomplicate this. But I have looked at the |
Yes in this case the fault is occurring when the FINI functions for an already loaded module (mod 2 in the abort output) are called, not the FINI functions for the module that failed to load (mod 4). I'll try implementing tracking when INIT functions are called with a new variable in the elf object like you describe, thanks! |
Sometimes, if for whatever the dynamic linker throws an exception like in this code:
it gets masked with a page fault abort like this:
It could be that in reality, it is a bug in the dynamic linker and possibly we are trying to remove objects that have not been loaded yet or something like this.
In this particular case, the x64 image had aarch64 version of
libgcc_s.so
and really should have aborted with the message about the wrong machine type of the library.The text was updated successfully, but these errors were encountered: