[PATCH 2/2] aarch64: Add workaround for GDB bug handling string literals
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Thu Jul 2 19:13:34 GMT 2026
On 02/07/26 09:59, Adhemerval Zanella Netto wrote:
>
>
> On 02/07/26 05:10, Yury Khrustalev wrote:
>> On Wed, Jul 01, 2026 at 01:25:14PM -0300, Adhemerval Zanella Netto wrote:
>>>
>>> On 01/07/26 12:53, Yury Khrustalev wrote:
>>>> On Wed, Jul 01, 2026 at 12:25:59PM -0300, Adhemerval Zanella Netto wrote:
>>>>>>
>>>>>> ...
>>>>>>
>>>>>> OK, I see. Well, resolvers should be as simple as possible, so I'd
>>>>>> rather do the check in the arch-specific way if it makes it smaller.
>>>>>>
>>>>>> However, a resolver can be correctly called from other places. For
>>>>>> example, many binary instrumentation frameworks substitute dynamic
>>>>>> loader and try to implement everything that a usual dynamic loader
>>>>>> would do. With Wilco's approach, these use cases will work provided
>>>>>> that the arguments for the resolver are compliant with the ABI, but
>>>>>> a check based on the return address will fail rendering many valid
>>>>>> use cases incorrect.
>>>>>
>>>>> But for ifunc resolver entered with ambiguous register state, we cannot satisfy
>>>>> both:
>>>>>
>>>>> * Caller wants the resolver to behave like the function call (i.e - malloc
>>>>> do the allocation).
>>>>
>>>> I don't think we should even discuss this.
>>>>
>>>>> * Caller wants the resolver to return the resolved address.
>>>>
>>>> If caller wants something else from an ifunc resolver, it is an error
>>>> and we should abort.
>>>>
>>>>>
>>>>> The on-entry state doesn't reliably encode intent across targets and ABI
>>>>> versions. On aarch64 you could test arg1 & _IFUNC_ARG_HWCAP, but:
>>>>>
>>>>> 1. that only separates new-ABI resolver call from everything else, it doesn't
>>>>> rescue legacy case-2 callers (or any other ifunc that uses more 2 argument).
>>>>
>>>> Yep, as Wilco suggested we can use
>>>>
>>>> (arg0 & ~_IFUNC_ARG_HWCAP) == GLRO (dl_hwcap)
>>> It still has a hole, any resolver(n) where (n~_IFUNC_ARG_HWCAP) == dl_hwcap
>>> passes the check. It might not a problem for malloc, but maybe for
>>> environments that manipulate hwcap (valgrind, etc.) that calls other ifunc
>>> besides malloc we might hit it eventually.
>>>
>>> Maybe the arg0 maybe be added as a complementary arch-specific check after
>>> the _dl_rtld_map bounds check. The bound check still has the advantage of
>>> being platform-neutral and generic enough to not require any extra arch
>>> handling if some maintainer wants to enable malloc ifunc.
>>
>> Adhemerval, I already explained that bounds check will render some use
>> cases not working. Here is another example to demonstrate this problem.
>>
>> GDB can call 'malloc' in different ways, e.g.
>>
>> a) internally to facilitate expression evaluation (this is where we're
>> having a problem right now, and this is what Florian's patch fixes)
>>
>> b) when 'malloc' is called as part of the expression.
>>
>> Observe:
>>
>> (gdb) br main
>> (gdb) r
>> Breakpoint 1, main (...) at ...
>> (gdb) call printf("%s\n", "hello")
>> hello
>> $1 = 6
>> (gdb) p malloc(23)
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x0000ffff0828f010 in ?? ()
>> The program being debugged was signaled while in a function called from GDB.
>>
>> This is with Florian's patch. Once again, this is not the only problem
>> you have to solve. I suppose your suggestion above in this thread may
>> work, however, like I already said, allowing resolvers to be only called
>> from libc itself will make other runtimes stop working.
>>
>> I think we've wasted enough time on try to find a "bug-compatible"
>> implementation. I don't think we should be doing this at all. Bugs
>> should be fixed. Complying software should not be the victim of bugs
>> in other tools.
>
> I think we are talking past each other since we have multiple divergent
> ideas on how to approach this issue.
>
> My point is *if* we decide to push a workaround in glibc to handle direct
> malloc calls in gdb, I think we should do some as below. With this patch
> applied:
>
> $ gdb -q -batch -ex "b main" -ex "run" -ex "p malloc(23)" --args malloc/tst-valloc-mcheck --direct
> Breakpoint 1 at 0x24c0: file ../support/test-driver.c, line 112.
> warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
>
> Breakpoint 1, main (argc=2, argv=0xffffffffede8) at ../support/test-driver.c:112
> 112 {
> malloc called in wrong context
> [Inferior 1 (process 530903) exited with code 0177]
> The program being debugged exited while in a function called from GDB.
> Evaluation of the expression containing the function
> (__libc_malloc_redirect_ifunc) will be abandoned.
So I tried to implement this check and I had my assumptions wrong [1]: the
ifunc resolution can also be called from libc (dlsym), there is the
extra complication of static dlopen and dlmopen, and there also the
valgrind case (elf/tst-valgrind-smoke regress).
This heuristic cannot tell between "bad" issuing (gdb evaluating a call) from
"good" (valgrind resolving for redirection), since valgrind dynamic translation
regenerates ld.so/libc.so and thus with a different mappings.
So I agree that we should focus on fixing gdb instead of adding extra hacks
on glibc. I am not sure about reverting changes, it would be safer for this release.
>
> So no crypt SIGSEGV triggered, platform agnostic, and with a clear indication
> that this is not supported. The gdb will need to proper call the function
> through the GOT, which then will either trigger the lazy resolution (and thus
> make ld.so call the ifunc resolver) or issue the resolved implementation directly
> - thus mimic what the process itself is expected to do.
>
> But I am not really proposing we go for this route, and I tend to agree that
> fixing gdb and other tools is a better alternative.
>
> As far as I understand there is no easy way solely in the malloc ifunc
> resolver context to make it bug compatible (which is not something I am *not*
> advocating by the way) *and* make malloc 'work'. We need to pick a poison:
> provide malloc as ifunc and disable this usercase by these tools; or work
> toward fixing the tools to proper handle it.
[1] https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/azanella/ifunc-malloc-reject
More information about the Libc-alpha
mailing list