Re: tracing malloc/free call

2015-01-16 Thread Marco Atzeri

On 1/15/2015 10:34 AM, Corinna Vinschen wrote:

Hi Marco,

On Jan 14 23:30, Marco Atzeri wrote:

Debugging a program I am trying to catch where this call is happening

17 1499678 [main] ncview 1484 free: (0x6000D7961), called by 0x180115A0B

unfortunately the 0x180115A0B address is not real caller address


No, the return address is the address of the _sigbe function defined in
the gendef script...


[cut]


Bottom line, you should be able to fetch the original return address by
printing the value at

   *(void*)_my_tls->stackptr

which points to the uppermost entry on the stack.


Hi Corinna,

in reality I found it is "*(_my_tls.stackptr-1)"

-  malloc_printf ("(%p), called by %p", p, __builtin_return_address (0));
+  malloc_printf ("(%p), called by %p", p, *(_my_tls.stackptr-1));

Attached patch that allows tracking of original caller,
for the 4 memory allocation calls.

Tested on 64 bit.

 $ grep 0x6000D6AA1 ncview.strace4
   20 1605112 [main] ncview 4408 free: (0x6000D6AA1), called by 0x10040E744


 $ addr2line.exe -a 0x10040E744 -e /usr/bin/ncview.exe
0x00010040e744
/usr/src/debug/ncview-2.1.4-2/src/file_netcdf.c:271


Regards
Marco







--- src_new/winsup/cygwin/malloc_wrapper.cc 2014-06-26 23:52:46.537847400 
+0200
+++ src/winsup/cygwin/malloc_wrapper.cc 2015-01-16 14:41:15.766384600 +0100
@@ -17,6 +17,7 @@
 #include "dtable.h"
 #include "perprocess.h"
 #include "miscfuncs.h"
+#include "cygtls.h"
 #include "cygmalloc.h"
 #ifndef MALLOC_DEBUG
 #include 
@@ -38,7 +39,7 @@
 extern "C" void
 free (void *p)
 {
-  malloc_printf ("(%p), called by %p", p, __builtin_return_address (0));
+  malloc_printf ("(%p), called by %p", p, *(_my_tls.stackptr-1));
   if (!use_internal)
 user_data->free (p);
   else
@@ -61,7 +62,7 @@
   res = dlmalloc (size);
   __malloc_unlock ();
 }
-  malloc_printf ("(%ld) = %p, called by %p", size, res, 
__builtin_return_address (0));
+  malloc_printf ("(%ld) = %p, called by %p", size, res, *(_my_tls.stackptr-1));
   return res;
 }
 
@@ -77,7 +78,7 @@
   res = dlrealloc (p, size);
   __malloc_unlock ();
 }
-  malloc_printf ("(%p, %ld) = %p, called by %p", p, size, res, 
__builtin_return_address (0));
+  malloc_printf ("(%p, %ld) = %p, called by %p", p, size, res, 
*(_my_tls.stackptr-1));
   return res;
 }
 
@@ -104,7 +105,7 @@
   res = dlcalloc (nmemb, size);
   __malloc_unlock ();
 }
-  malloc_printf ("(%ld, %ld) = %p, called by %p", nmemb, size, res, 
__builtin_return_address (0));
+  malloc_printf ("(%ld, %ld) = %p, called by %p", nmemb, size, res, 
*(_my_tls.stackptr-1));
   return res;
 }
 


Re: tracing malloc/free call

2015-01-16 Thread Corinna Vinschen
Hi Marco,

On Jan 16 15:23, Marco Atzeri wrote:
> On 1/15/2015 10:34 AM, Corinna Vinschen wrote:
> >Bottom line, you should be able to fetch the original return address by
> >printing the value at
> >
> >   *(void*)_my_tls->stackptr
> >
> >which points to the uppermost entry on the stack.
> 
> Hi Corinna,
> 
> in reality I found it is "*(_my_tls.stackptr-1)"

Oh, right!  Sorry about that.  I missed to take the behavior of xadd
into account.

> -  malloc_printf ("(%p), called by %p", p, __builtin_return_address (0));
> +  malloc_printf ("(%p), called by %p", p, *(_my_tls.stackptr-1));
> 
> Attached patch that allows tracking of original caller,
> for the 4 memory allocation calls.
> 
> Tested on 64 bit.
> 
>  $ grep 0x6000D6AA1 ncview.strace4
>20 1605112 [main] ncview 4408 free: (0x6000D6AA1), called by 0x10040E744
> 
> 
>  $ addr2line.exe -a 0x10040E744 -e /usr/bin/ncview.exe
> 0x00010040e744
> /usr/src/debug/ncview-2.1.4-2/src/file_netcdf.c:271

Thanks for the patch, but it won't work nicely either this way.  The
problem is that, in theory, the code has to differ between internal and
external callers.  Internal callers (that is, Cygwin functions itself)
don't hop into the function via _sigfe/_sigbe.  Thus the output for
internal callers of malloc/free is now wrong with your patch.

The solution for this problem would be a test which checks if the return
address is the _sigbe function and if so, returns *(_my_tls.stackptr-1),
otherwise __builtin_return_address(0).  However, the symbol _sigbe is
not exported since, so far, it was only used inside _sigfe.  This needs
a bit of tweaking.  I'll have a look.

Btw., when sending a patch, a matching ChangeLog entry would be quite
helpful :}


Thanks,
Corinna


-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpJFB4pS4ZB1.pgp
Description: PGP signature


Re: tracing malloc/free call

2015-01-16 Thread Corinna Vinschen
On Jan 16 16:44, Corinna Vinschen wrote:
> Hi Marco,
> 
> On Jan 16 15:23, Marco Atzeri wrote:
> > On 1/15/2015 10:34 AM, Corinna Vinschen wrote:
> > >Bottom line, you should be able to fetch the original return address by
> > >printing the value at
> > >
> > >   *(void*)_my_tls->stackptr
> > >
> > >which points to the uppermost entry on the stack.
> > 
> > Hi Corinna,
> > 
> > in reality I found it is "*(_my_tls.stackptr-1)"
> 
> Oh, right!  Sorry about that.  I missed to take the behavior of xadd
> into account.

Worse, I missed the fact that _my_tls.retaddr() already provides the
correct return address.  Sorry again.


Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpRoKw5SQH0W.pgp
Description: PGP signature


Re: tracing malloc/free call

2015-01-16 Thread Corinna Vinschen
On Jan 16 16:44, Corinna Vinschen wrote:
> On Jan 16 15:23, Marco Atzeri wrote:
> > Attached patch that allows tracking of original caller,
> > for the 4 memory allocation calls.
> 
> Thanks for the patch, but it won't work nicely either this way.  The
> problem is that, in theory, the code has to differ between internal and
> external callers.  Internal callers (that is, Cygwin functions itself)
> don't hop into the function via _sigfe/_sigbe.  Thus the output for
> internal callers of malloc/free is now wrong with your patch.
> 
> The solution for this problem would be a test which checks if the return
> address is the _sigbe function and if so, returns *(_my_tls.stackptr-1),
> otherwise __builtin_return_address(0).  However, the symbol _sigbe is
> not exported since, so far, it was only used inside _sigfe.  This needs
> a bit of tweaking.  I'll have a look.

I applied a patch to print the right caller address.  I created a new
macro caller_return_address() for reuse, should we have a desire to
print the caller address in other parts of the code.

I'm going to create a snapshot with this change.  Please give it
a try.


Thanks,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpy_ZUTk5piS.pgp
Description: PGP signature


Re: tracing malloc/free call

2015-01-16 Thread Marco Atzeri

On 1/16/2015 5:22 PM, Corinna Vinschen wrote:

On Jan 16 16:44, Corinna Vinschen wrote:

On Jan 16 15:23, Marco Atzeri wrote:

Attached patch that allows tracking of original caller,
for the 4 memory allocation calls.


Thanks for the patch, but it won't work nicely either this way.  The
problem is that, in theory, the code has to differ between internal and
external callers.  Internal callers (that is, Cygwin functions itself)
don't hop into the function via _sigfe/_sigbe.  Thus the output for
internal callers of malloc/free is now wrong with your patch.


I missed that point. ;-)
First time I look at these inside details of cygwin


The solution for this problem would be a test which checks if the return
address is the _sigbe function and if so, returns *(_my_tls.stackptr-1),
otherwise __builtin_return_address(0).  However, the symbol _sigbe is
not exported since, so far, it was only used inside _sigfe.  This needs
a bit of tweaking.  I'll have a look.


I applied a patch to print the right caller address.  I created a new
macro caller_return_address() for reuse, should we have a desire to
print the caller address in other parts of the code.

I'm going to create a snapshot with this change.  Please give it
a try.


It works like charm.
Much more easy to find misalignment between
malloc/calloc/realloc and free calls


Thanks,
Corinna



Re: tracing malloc/free call

2015-01-16 Thread Corinna Vinschen
On Jan 16 18:33, Marco Atzeri wrote:
> On 1/16/2015 5:22 PM, Corinna Vinschen wrote:
> >On Jan 16 16:44, Corinna Vinschen wrote:
> >>On Jan 16 15:23, Marco Atzeri wrote:
> >>>Attached patch that allows tracking of original caller,
> >>>for the 4 memory allocation calls.
> >>
> >>Thanks for the patch, but it won't work nicely either this way.  The
> >>problem is that, in theory, the code has to differ between internal and
> >>external callers.  Internal callers (that is, Cygwin functions itself)
> >>don't hop into the function via _sigfe/_sigbe.  Thus the output for
> >>internal callers of malloc/free is now wrong with your patch.
> 
> I missed that point. ;-)
> First time I look at these inside details of cygwin

Hopefully not your last :)  Feel free to ask on the devs list if you
have questions about the code.

> >>The solution for this problem would be a test which checks if the return
> >>address is the _sigbe function and if so, returns *(_my_tls.stackptr-1),
> >>otherwise __builtin_return_address(0).  However, the symbol _sigbe is
> >>not exported since, so far, it was only used inside _sigfe.  This needs
> >>a bit of tweaking.  I'll have a look.
> >
> >I applied a patch to print the right caller address.  I created a new
> >macro caller_return_address() for reuse, should we have a desire to
> >print the caller address in other parts of the code.
> >
> >I'm going to create a snapshot with this change.  Please give it
> >a try.
> 
> It works like charm.
> Much more easy to find misalignment between
> malloc/calloc/realloc and free calls

I'm glad it works for you, too.

Btw., did you see my PM?


Thanks,
Corinna

-- 
Corinna Vinschen  Please, send mails regarding Cygwin to
Cygwin Maintainer cygwin AT cygwin DOT com
Red Hat


pgpE9DKIv0uEK.pgp
Description: PGP signature