On Sun Feb 25 19:41:34 2024 +0000, Jacek Caban wrote:
You never call `_dl_debug_state` in this commit. Does it work without it or are you relying on debugger figuring things out when it's called from ntdll? An explicit `_dl_debug_state` call in `wld_start` would seem right to me.
Gdb first looks for `DT_DEBUG` in the dynamic table, expecting to find the address of `_r_debug` there, but it's not set there until we write it ourselves. I couldn't find how to make the linker put `_r_debug` there, so then it falls back to looking for known rendez-vous symbols such as `_dl_debug_state`, and sets a breakpoint into it.
If neither of this succeeds, Gdb bails out early and will never try again. If it does, it will later retry `DT_DEBUG` again, for instance when stopping the execution, and will find our `_r_debug` after we've set it. Then sure, I can probably call `_dl_debug_state` so it gets used.
Note that I have found an issue still: Gdb doesn't seem to put breakpoints in every `_r_debug.r_brk`, only in `_dl_debug_state`. This means that although it is refreshed and you can see it in `info shared` list, debug symbols for entries in ld.so link_map don't get automatically loaded. They are only loaded when `_dl_debug_state` is called, and although we call it for the PE module updates, we then miss the unix .so updates. I don't see any other way to do that reliably for every .so than to hook `dlopen` and call `_dl_debug_state` there, like I was doing before (but we still don't actually need to mirror the link map).