diff mbox series

glibc: Apply patch for easy analysis of malloc issue

Message ID CAK0fB4M6pXPL9D1aL8TcpFGZDvjqoJrv93N_hDO26XHkVAkwAw@mail.gmail.com
State Rejected
Headers show
Series glibc: Apply patch for easy analysis of malloc issue | expand

Commit Message

Akash Hadke Jan. 20, 2021, 3:42 p.m. UTC
The function __malloc_tcache_walk added in this patch provides
information of entire heap memory chunk in the core file.

This patch provides the address and value of the memory chunk illegally
written, which can help to understand and debug the issue.

Used below CPP code for testing purpose.

============================================================================
typedef std::size_t Item;
const std::size_t nItemsWanted = 64 / sizeof (Item);
Item *const paItems1 = new Item [nItemsWanted];
{
    std::fill (paItems1, paItems1 + nItemsWanted, Item
(0x8899AABBCCDDEEFF));
}
delete [] paItems1;
paItems1 [0] = 0x00214E414D544142;
Item *const paItems3 = new Item [nItemsWanted];
Item *const paItems4 = new Item [nItemsWanted];
============================================================================

This code fails and produce coredump below is the log of backtrace

Without proposed patch:
(gdb) bt
#0 0x00007ff12b8f8407 in _GI__libc_malloc (bytes=64) at
/usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:3068
#1 0x00007ff12c261b48 in operator new(unsigned long) () from
/usr/lib/libstdc++.so.6
#2 0x000055c2db586645 in main () at
/usr/src/debug/qtbase/5.6.2+gitAUTOINC+b4ada3f0d8-r0/Example-of-Buggy-Program-v2.cpp:22

(gdb) x/8gx e
Value can't be converted to integer.

With proposed patch:
(gdb) bt
#0 __malloc_tcache_walk (ptcache=0x55b28b3d0010, tc_idx=tc_idx@entry=3,
e=e@entry=0x55b28b3e1e70)
at /usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:2949
#1 0x00007f90e5abc53a in tcache_get (tc_idx=3) at
/usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:2984
#2 _GI__libc_malloc (bytes=64) at
/usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:3096
#3 0x00007f90e6425b48 in operator new(unsigned long) () from
/usr/lib/libstdc++.so.6
#4 0x000055b28a44263b in main () at
/usr/src/debug/qtbase/5.6.2+gitAUTOINC+b4ada3f0d8-r0/Example-of-Buggy-Program-v2.cpp:21

(gdb) x/8gx e
0x55b28b3e1e70: 0x00214e414d544142  0x000055b28b3d0010
0x55b28b3e1e80: 0x8899aabbccddeeff     0x8899aabbccddeeff
0x55b28b3e1e90: 0x8899aabbccddeeff     0x8899aabbccddeeff
0x55b28b3e1ea0: 0x8899aabbccddeeff     0x8899aabbccddeeff

ChangeLog:

2021-01-20 Akash Hadke <hadkeakash4@gmail.com>

[BZ #27216]

* malloc/malloc.c: Add new function __malloc_tcache_walk.

--

Comments

Carlos O'Donell Jan. 20, 2021, 4:32 p.m. UTC | #1
On 1/20/21 10:42 AM, Akash Hadke via Libc-alpha wrote:
> The function __malloc_tcache_walk added in this patch provides
> information of entire heap memory chunk in the core file.
> 
> This patch provides the address and value of the memory chunk illegally
> written, which can help to understand and debug the issue.

A developer would use valgrind to detect this issue.

Why is valgrind not sufficient for your use case?
Akash Hadke Jan. 21, 2021, 5:38 a.m. UTC | #2
Because valgrind didn't provide entire heap memory chunk and also it
doesn't show illegally written values. Which can be done using given patch.

On Wed, Jan 20, 2021 at 10:02 PM Carlos O'Donell <carlos@redhat.com> wrote:

> On 1/20/21 10:42 AM, Akash Hadke via Libc-alpha wrote:
> > The function __malloc_tcache_walk added in this patch provides
> > information of entire heap memory chunk in the core file.
> >
> > This patch provides the address and value of the memory chunk illegally
> > written, which can help to understand and debug the issue.
>
> A developer would use valgrind to detect this issue.
>
> Why is valgrind not sufficient for your use case?
>
> --
> Cheers,
> Carlos.
>
>
Andreas Schwab Jan. 21, 2021, 8:40 a.m. UTC | #3
On Jan 21 2021, Akash Hadke via Libc-alpha wrote:

> Because valgrind didn't provide entire heap memory chunk and also it
> doesn't show illegally written values.

You can attach a debugger to inspect the failure.

Andreas.
diff mbox series

Patch

glibc: Patch for better Analysis of malloc issue

The function __malloc_tcache_walk added in this patch provides
information of entire heap memory chunk in the core file.

This patch provides address and value of the memory chunk illegally
written, which can help to understand and debug the issue.

Used below CPP code for testing purpose.

============================================================================
typedef std::size_t Item;
const std::size_t nItemsWanted = 64 / sizeof (Item);
Item *const paItems1 = new Item [nItemsWanted];
{
    std::fill (paItems1, paItems1 + nItemsWanted, Item (0x8899AABBCCDDEEFF));
}
delete [] paItems1;
paItems1 [0] = 0x00214E414D544142;
Item *const paItems3 = new Item [nItemsWanted];
Item *const paItems4 = new Item [nItemsWanted];
============================================================================

This code fails and produce coredump below is the log of backtrace

Without proposed patch:
(gdb) bt
#0 0x00007ff12b8f8407 in _GI__libc_malloc (bytes=64) at /usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:3068
#1 0x00007ff12c261b48 in operator new(unsigned long) () from /usr/lib/libstdc++.so.6
#2 0x000055c2db586645 in main () at /usr/src/debug/qtbase/5.6.2+gitAUTOINC+b4ada3f0d8-r0/Example-of-Buggy-Program-v2.cpp:22

(gdb) x/8gx e
Value can't be converted to integer.

With proposed patch:
(gdb) bt
#0 __malloc_tcache_walk (ptcache=0x55b28b3d0010, tc_idx=tc_idx@entry=3, e=e@entry=0x55b28b3e1e70)
at /usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:2949
#1 0x00007f90e5abc53a in tcache_get (tc_idx=3) at /usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:2984
#2 _GI__libc_malloc (bytes=64) at /usr/src/debug/glibc/2.27-r0/git/malloc/malloc.c:3096
#3 0x00007f90e6425b48 in operator new(unsigned long) () from /usr/lib/libstdc++.so.6
#4 0x000055b28a44263b in main () at /usr/src/debug/qtbase/5.6.2+gitAUTOINC+b4ada3f0d8-r0/Example-of-Buggy-Program-v2.cpp:21

(gdb) x/8gx e
0x55b28b3e1e70: 0x00214e414d544142  0x000055b28b3d0010
0x55b28b3e1e80: 0x8899aabbccddeeff     0x8899aabbccddeeff
0x55b28b3e1e90: 0x8899aabbccddeeff     0x8899aabbccddeeff
0x55b28b3e1ea0: 0x8899aabbccddeeff     0x8899aabbccddeeff

Signed-off-by: Bogdan Dragu <Bogdan.Dragu@harman.com>
Signed-off-by: Akash Hadke <hadkeakash4@gmail.com>
Upstream-Status: Pending
---
--- a/malloc/malloc.c	2021-01-19 14:42:22.263863000 +0530
+++ b/malloc/malloc.c	2021-01-19 15:01:42.291811660 +0530
@@ -2924,6 +2924,25 @@ 
 static __thread bool tcache_shutting_down = false;
 static __thread tcache_perthread_struct *tcache = NULL;
 
+__thread size_t __malloc_tcache_t_dummy_count;
+
+const tcache_entry *
+__malloc_tcache_walk
+(const tcache_perthread_struct *ptcache, size_t tc_idx, const tcache_entry *e)
+{
+  const tcache_entry *const p0 = e->next;
+
+  const tcache_entry *      p  = p0;
+  {
+    for (size_t i = 0; p && i < 4; ++i)
+      p = p->next;
+  }
+
+  ++__malloc_tcache_t_dummy_count;
+
+  return p0;
+}
+
 /* Caller must ensure that we know tc_idx is valid and there's room
    for more chunks.  */
 static __always_inline void
@@ -2946,10 +2965,14 @@ 
 static __always_inline void *
 tcache_get (size_t tc_idx)
 {
-  tcache_entry *e = tcache->entries[tc_idx];
   assert (tc_idx < TCACHE_MAX_BINS);
-  assert (tcache->entries[tc_idx] > 0);
-  tcache->entries[tc_idx] = e->next;
+  tcache_entry *const e = tcache->entries[tc_idx];
+
+  tcache_entry *const e_next = (tcache_entry *) __malloc_tcache_walk (tcache, tc_idx, e);
+  assert (e_next == e->next);
+
+  tcache->entries[tc_idx] = e_next;
+
   --(tcache->counts[tc_idx]);
   e->key = NULL;
   return (void *) e;