Issue with Skipped malloc Breakpoints in GDB When Using finish and continue

Puspaul Halder via Gdb <[email protected]>
Newsgroups gmane.comp.gdb.devel
Message-ID <CADXRgKajnNy1sJ58=z_=kbOjtucd9SrQif9boccmO+uX0_rKcA@mail.gmail.com>
Hey Team,

I have a simple requirement:

   - Track the total memory allocated (malloc) and freed (free).
   - Capture backtraces of all malloc and free calls (for now, logging can
   be ignored).

*Current Approach*

   1.

   *For malloc*:
   - I need every malloc call to complete execution.
      - After completion, I retrieve $rax and use malloc_usable_size($rax)
      to determine the actual allocated memory.
   2.

   *For free*:
   - This is simpler since malloc_usable_size($rdi) gives the size being
      freed.

Manually continuing execution from the GDB prompt works fine. However, my
debugging case involves *thousands* of malloc and free calls, so I want
this to run *automatically* without user intervention.
*The Issue*

   - When I add continue inside hookpost-myfinish, I observe *skipped
   malloc breakpoints*.
   - As a result, malloc_count, free_count, total_malloced, and total_freed
   become incorrect.
   - I suspect this happens when *consecutive malloc calls* occur:
      - finish from malloc returns execution to main(), and another continue
      causes the *next malloc entry breakpoint to be skipped*.

*Reproduction Steps*

   1. *Using gdb_commands.txt* → Works correctly (manual continuation
   required).
   2. *Using gdb_commands_continue.txt* → Causes alternate malloc calls to
   be skipped, leading to incorrect tracking.

This seems to be due to how continue interacts with finish, but I’m unsure
of the best way to *ensure every malloc and free call is properly accounted
for* without skipping breakpoints.
*Request*

Could someone help me understand why continue is skipping alternate malloc
calls and suggest a reliable way to handle this?

I've attached:

   - code.c → Sample test code.
   - gdb_commands.txt → Correct execution (manual continuation).
   - gdb_commands_continue.txt → Shows skipped malloc calls with continue.

Would appreciate any insights or alternative approaches!


Thanking You,

Puspaul Halder
gdb_commands.txt (text/plain, 870 B)
set unwindonsignal off
set $mc = 0 
set $fc = 0
set $mallocsize = 0
set $in_malloc = 0
set $total_malloced = 0
set $total_freed = 0
b memory_test.c:8
b malloc
b free
disable 2 3

commands 1
    silent
    enable 2 3
    continue
end

commands 2
  set $mc = $mc + 1
  set $mallocsize = $rdi
  printf "Asked to malloc %d bytes\n", $mallocsize
  set $in_malloc = 1
  myfinish
end

commands 3
  set $fc = $fc + 1
  if ($rdi)
    set $total_freed = $total_freed + (size_t)malloc_usable_size($rdi)
    printf "Freed %d bytes \n ", (size_t)malloc_usable_size($rdi)
  end
  continue
end


define myfinish
    finish
end


define hookpost-myfinish
    set $total_malloced = $total_malloced + (size_t)malloc_usable_size($rax)
    printf "Actually malloced %d bytes and total malloced till now is %d \n", (size_t)malloc_usable_size($rax), $total_malloced
    set $in_malloc = 0
end
code.c (application/octet-stream, 1.9 KB)
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>  // Required for malloc_usable_size

int main() {
    printf("Starting memory allocation test...\n");

    // Allocate memory blocks of different sizes
    void *ptr1 = malloc(32);
    printf("ptr1 allocated at address: %p\n", ptr1);
 
    free(ptr1);
    printf("ptr1 freed");
    void *ptr2 = malloc(64);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);
    printf("ptr2 allocated at address: %p\n", ptr2);

    void *ptr3 = malloc(128);
    printf("ptr3 allocated at address: %p\n", ptr3);

    free(ptr2);
    free(ptr3);

    void *ptr4 = malloc(128);
    printf("ptr4 allocated at address: %p\n", ptr4);

    void *ptr5 = malloc(128);
    printf("ptr5 allocated at address: %p\n", ptr5);

    void *ptr6 = malloc(256);
    printf("ptr6 allocated at address: %p\n", ptr6);
    void *ptr7 = malloc(256);
    void *ptr8 = malloc(256);
    void *ptr9 = malloc(256);
    void *ptr10 = malloc(256);
    void *ptr11 = malloc(256);
    void *ptr12 = malloc(256);
    void *ptr13 = malloc(256);
    void *ptr14 = malloc(256);
    void *ptr15 = malloc(256);
    void *ptr16 = malloc(256);

    free(ptr5);
    free(ptr4);
    free(ptr6);
    free(ptr7);
    free(ptr8);
    free(ptr9);
    free(ptr10);
    free(ptr11);
    free(ptr12);
    free(ptr13);
    free(ptr14);
    free(ptr15);
    free(ptr16);
    


    printf("Memory allocation test completed.\n");
    return 0;
}
gdb_commands_continue.txt (text/plain, 870 B)
set unwindonsignal off
set $mc = 0 
set $fc = 0
set $mallocsize = 0
set $in_malloc = 0
set $total_malloced = 0
set $total_freed = 0
b memory_test.c:8
b malloc
b free
disable 2 3

commands 1
    silent
    enable 2 3
    continue
end

commands 2
  set $mc = $mc + 1
  set $mallocsize = $rdi
  printf "Asked to malloc %d bytes\n", $mallocsize
  set $in_malloc = 1
  myfinish
end

commands 3
  set $fc = $fc + 1
  if ($rdi)
    set $total_freed = $total_freed + (size_t)malloc_usable_size($rdi)
    printf "Freed %d bytes \n ", (size_t)malloc_usable_size($rdi)
  end
  continue
end


define myfinish
    finish
end


define hookpost-myfinish
    set $total_malloced = $total_malloced + (size_t)malloc_usable_size($rax)
    printf "Actually malloced %d bytes and total malloced till now is %d \n", (size_t)malloc_usable_size($rax), $total_malloced
    set $in_malloc = 0
end
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.