Quantcast

Replacement function resolution

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Replacement function resolution

Paul Floyd
Hi all

I'm trying to understand how valgrind resolves replacement functions at runtime.

Here's the code that I'm using:

class MyClass
{
    int i;
};

int main()
{
    MyClass* myClass = new MyClass();
    delete myClass;
}

GCC 4.8.2 emits
gnm test64_482 | grep _Z
                 U _ZdlPv
                 U _Znwm


Or demangled

gnm -C test64_482 | grep operator
                 U operator delete(void*)
                 U operator new(unsigned long)

I see that this corresponds to the following in vg_replace_malloc.c:

 FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
 FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );


At runtime

valgrind --trace-malloc=yes ./test64_482
--7974-- _Znwm(4) = 0x7FF760040
--7974-- _ZdlPv(0x7FF760040)

So far so good.

With GCC built from SVN head (but I'd expect the same for any GCC since version 6) this changes a bit. [see also bz 72347]

GCC emits
gnm test64 | grep _Z              
                 U _ZdlPvm
                 U _Znwm

demangled

gnm -C test64 | grep operator
                 U operator delete(void*, unsigned long)
                 U operator new(unsigned long)

valgrind --trace-malloc=yes ./test64
--9374-- malloc(72704) = 0x7FF680040
--9374-- _Znwm(4) = 0x7FF691C80
--9374-- _ZdlPv(0x7FF691C80)
--9374-- free(0x7FF680040)


The extra malloc/free are, I guess, artefacts of the newer libstdc++; I get them even with an empty main().

I don't see how (and I haven't found in the Vagrind code) how the call to ZdlPvm resolves to _ZdlPv. Can anyone tell me where to look in the Valgrind code for this?

A+
Paul

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-developers mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Replacement function resolution

iraisr
2017-02-05 20:31 GMT+01:00  <[hidden email]>:
> Hi all
>
> I'm trying to understand how valgrind resolves replacement functions at runtime.

Hi Paul,
Have a look at pub_tool_redir.h, mechanics and Z-encoding rules are
described there.


> GCC 4.8.2 emits
> gnm test64_482 | grep _Z
>                  U _ZdlPv
>                  U _Znwm
>
>
> Or demangled
>
> gnm -C test64_482 | grep operator
>                  U operator delete(void*)
>                  U operator new(unsigned long)
>
> I see that this corresponds to the following in vg_replace_malloc.c:
>
>  FREE(VG_Z_LIBSTDCXX_SONAME,  _ZdaPv,               __builtin_vec_delete );
>  FREE(SO_SYN_MALLOC,          _ZdaPv,               __builtin_vec_delete );
>
>
> At runtime
>
> valgrind --trace-malloc=yes ./test64_482
> --7974-- _Znwm(4) = 0x7FF760040
> --7974-- _ZdlPv(0x7FF760040)
>
> So far so good.
>
> With GCC built from SVN head (but I'd expect the same for any GCC since version 6) this changes a bit. [see also bz 72347]
>
> GCC emits
> gnm test64 | grep _Z
>                  U _ZdlPvm
>                  U _Znwm
>
> demangled
>
> gnm -C test64 | grep operator
>                  U operator delete(void*, unsigned long)
>                  U operator new(unsigned long)
>
> valgrind --trace-malloc=yes ./test64
> --9374-- malloc(72704) = 0x7FF680040
> --9374-- _Znwm(4) = 0x7FF691C80
> --9374-- _ZdlPv(0x7FF691C80)
> --9374-- free(0x7FF680040)

I think you've already spotted the difference between:
_ZdlPv: operator delete(void*)
[which is replaced by _ZdaPv:  __builtin_vec_delete]
and
_ZdlPvm: operator delete(void*, unsigned long)

So the remaining task becomes finding a replacer for _ZdlPvm and if
there is none, providing one.

I.

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-developers mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Replacement function resolution

Paul Floyd


----- Original Message -----
> 2017-02-05 20:31 GMT+01:00  <[hidden email]>:
> > Hi all
> >
> > I'm trying to understand how valgrind resolves replacement
> > functions at runtime.
>
> Hi Paul,
> Have a look at pub_tool_redir.h, mechanics and Z-encoding rules are
> described there.

Hi Ivo

Thanks for the info. What was confusing me the most was why code that called operator delete(void* ptr, std::size_t) was being detected by an unmodified valgrind as operator delete(void* ptr). Looking at the libstdc++ source this is now obvious:

_GLIBCXX_WEAK_DEFINITION void
operator delete(void* ptr, std::size_t) _GLIBCXX_USE_NOEXCEPT
{
  ::operator delete (ptr);
}

[and libcxx does the same]

So currently this works because the new functions just wrap the old ones.

A+
Paul

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Valgrind-developers mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/valgrind-developers
Loading...