android: crazy-linker: Try to fix WriteLinkMapField() crashes.
This is an attempt to fix the random crashes that happen in the crazy::RDebug::WriteLinkMapField() function on some devices (for more context, see related bug below). It is very hard to understand why these crashes happen, the best candidate hypothesis so far is that both the crazy linker and the system linker try to modify the same area of memory at the same time (the global _r_debug link-map list, see technical note in crazy_linker_rdebug.h for all details). This CL tries to reduce the occurence of such events by better synchronizing modifications performed by the system linker, and the crazy one. This is done by the following steps: - Create a new global mutex, and associated convenience class, used to synchronize modifications to the global _r_debug link map list. See Globals::ScopedLinkMapLocker. Before the CL, only *explicit* modifications to the list were synchronized through the global crazy lock, but this did not protect against other threads from native code that call the wrapped dlopen(), which end up calling the system ::dlopen() which may also modify the list. These explicit modifications would typically happen after the library was loaded, due to the fact that they are applied by a delayed callback running on the UI thread, not the thread that loaded the library. Ironically, this delayed callback scheme was introduced to try to reduce these kind of random crashes. We may consider removing it entirely if this patch doesn't fix the situation. - To solve this, wrap all calls to the system linker through a new convenience class: crazy::SystemLinker. And ensure that each call that may change the global list will properly lock/unlock the link map mutex. - Incidentally, this allows making the global crazy mutex non-recursive. + Initialize the RDebug instance properly when its GetAddress() method is called. Otherwise, it could return a nullptr value in certain cases. This was not an issue in practice, since it was only used to update the DT_DEBUG entry of a crazy-loaded library, which technically isn't used by anything at runtime (e.g. GDB would find the value from the executable image instead, not from one of the shared libraries already in the list). BUG=831403 R=pasko@chromium.org, rmcilroy@chromium.org, agrieve@chromium.org, lizeb@chromium.org Change-Id: I6aa5f622908fc56deb37825ffed4a816ec6e4cc2 Reviewed-on: https://chromium-review.googlesource.com/1059516 Commit-Queue: David Turner <digit@chromium.org> Reviewed-by:agrieve <agrieve@chromium.org> Cr-Commit-Position: refs/heads/master@{#558805}
Showing
Please register or sign in to comment