Gdb for debugging double free, not detected valgrind (?)

About once every three times I run my program, malloc reports a double error; eg.

myprogram(703,0xb06d9000) malloc: *** error for object 0x17dd0240: double free
*** set a breakpoint in malloc_error_break to debug

I have run the same code through valgrind more than a dozen times, but it never reports double free.

I ran the code through gdb with a breakpoint at malloc_error_break and (when an error occurs), the error is always reported in the standard C ++ library function. I isolated the parent function and injected it into the test unit, but there were no errors.

I think that the parent function / standard C ++ library is not to blame, it just frees what it allocates, and some other function in the parent program is freed.

I tried to see which object was freed twice, but my gdb skills were not able to find the first object that was freed. Please help me find which object caused the first free and, in addition, any help why my program generates this error. Thank.

Parent function comes down to:

int i;
double px, py;
int start, finish;
std::string comment;
std::vector<double> x, y;

std::fstream myfile;
myfile.open("filename.txt", std::ios_base::in);

// Read header

std::getline(myfile, comment);

// Read data

while(!myfile.eof())
{
  myfile >> comment >> start >> comment >> finish;

  for(i = 0; i <= finish-start; i++)
  {
    myfile >> px >> py;  // double free here

    x.push_back(px);
    y.push_back(py);
  }
}

EDIT: My data file looks something like this:

Comment: My Data
start 33 end 36
10.2 139.0076
9.22616 141.584
8.62802 141.083
8.87098 141.813
start 33 end 35
300.354 405
301.698 404.029
303.369 403.953
start 33 end 35
336.201 148.07
334.616 147.243
334.735 146.09

Backtrace from gdb

(gdb) backtrace
#0  0x93c2d4a9 in malloc_error_break ()
#1  0x93c28497 in szone_error ()
#2  0x93b52503 in szone_free ()
#3  0x93b5236d in free ()
#4  0x93b51f24 in localeconv_l ()
#5  0x93c18163 in strtod_l$UNIX2003 ()
#6  0x93c192e0 in strtod$UNIX2003 ()
#7  0x919b76e8 in std::__convert_to_v<double> ()
#8  0x919983cf in std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::do_get ()
#9  0x91991671 in std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::get ()
#10 0x9198d2dc in std::istream::operator>> ()

To repeat, I need help to find which object was first released, I'm not really interested in refactoring my code for this function, which I think is not causing a problem; if you don’t find something catastrophic in him.

EDIT: Changed example code.

+3
source share
5 answers

, Mac OSX ( : -)

, .

, MallocStackLoggingNoCompact .

:

$ cat t.c
int main()
{
  char *p = strdup("hello");
  free(p);
  free(p);
  return 0;
}

$ gdb ./a.out
GNU gdb 6.3.50-20050815 (Apple version gdb-967) (Tue Jul 14 02:11:58 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries ... done

(gdb) set env MallocStackLoggingNoCompact 1
(gdb) b malloc_error_break
Breakpoint 1 at 0x13f44a9
(gdb) r
Starting program: /Users/emp-russian/a.out 
bash(22634) malloc: recording malloc stacks to disk using standard recorder
bash(22634) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly
bash(22634) malloc: process 22536 no longer exists, stack logs deleted from /tmp/stack-logs.22536.a.out.8D3VZO
bash(22634) malloc: stack logs being written into /tmp/stack-logs.22634.bash.kjFTGa
arch(22634) malloc: recording malloc stacks to disk using standard recorder
arch(22634) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly
arch(22634) malloc: stack logs deleted from /tmp/stack-logs.22634.bash.kjFTGa
arch(22634) malloc: stack logs being written into /tmp/stack-logs.22634.arch.8L8iLX
Reading symbols for shared libraries ++. done
Breakpoint 1 at 0x909b54a9
a.out(22634) malloc: recording malloc stacks to disk using standard recorder
a.out(22634) malloc: stack logging compaction turned off; size of log files on disk can increase rapidly
a.out(22634) malloc: stack logs deleted from /tmp/stack-logs.22634.arch.8L8iLX
a.out(22634) malloc: stack logs being written into /tmp/stack-logs.22634.a.out.s1qQRw
a.out(22634) malloc: *** error for object 0x100080: double free
*** set a breakpoint in malloc_error_break to debug

Breakpoint 1, 0x909b54a9 in malloc_error_break ()
(gdb) shell ls -l /tmp/stack-logs.22634.a.out.s1qQRw
total 16
-rw-------  1 emp-russian  wheel   96 Sep 12 09:42 stack-logs.index
-rw-------  1 emp-russian  wheel  208 Sep 12 09:42 stack-logs.stacks

(gdb) shell malloc_history 22634 0x100080

, :

Call [2] [arg=24]: thread_a0103720 |_dyld_start | dyldbootstrap::start(mach_header const*, int, char const**, long) | dyld::_main(mach_header const*, unsigned long, int, char const**, char const**, char const**) | dyld::initializeMainExecutable() | ImageLoader::runInitializers(ImageLoader::LinkContext const&) | ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) | ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) | ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) | ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) | libSystem_initializer | __keymgr_initializer | _dyld_register_func_for_add_image | dyld::registerAddCallback(void (*)(mach_header const*, long)) | dwarf2_unwind_dyld_add_image_hook | calloc | _malloc_initialize | malloc_set_zone_name | malloc_zone_malloc | __disk_stack_logging_log_stack | reap_orphaned_log_files | opendir$INODE64$UNIX2003 | __opendir2$INODE64$UNIX2003 | telldir$INODE64$UNIX2003 | malloc | malloc_zone_malloc 
Call [4] [arg=0]: thread_a0103720 |_dyld_start | dyldbootstrap::start(mach_header const*, int, char const**, long) | dyld::_main(mach_header const*, unsigned long, int, char const**, char const**, char const**) | dyld::initializeMainExecutable() | ImageLoader::runInitializers(ImageLoader::LinkContext const&) | ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) | ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) | ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int) | ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) | libSystem_initializer | __keymgr_initializer | _dyld_register_func_for_add_image | dyld::registerAddCallback(void (*)(mach_header const*, long)) | dwarf2_unwind_dyld_add_image_hook | calloc | _malloc_initialize | malloc_set_zone_name | malloc_zone_malloc | __disk_stack_logging_log_stack | reap_orphaned_log_files | closedir$UNIX2003 | _reclaim_telldir | free | malloc_zone_free

:

Call [2] [arg=6]: thread_a0103720 |0x1 | start | main | strdup | malloc | malloc_zone_malloc 
Call [4] [arg=0]: thread_a0103720 |0x1 | start | main | free | malloc_zone_free 
Call [4] [arg=0]: thread_a0103720 |0x1 | start | main | free | malloc_zone_free 
+4

" ", MacOS. ( ) , , , , ().

, , - , , gdb . .

gdb:

# malloc_error_break.gdb
break malloc_error_break
run         # Add program arguments here
backtrace

gdb, , :

gdb -x malloc_error_break.gdb --batch my_program

, " " backtrace, gdb ( -batch).

, (,!) gdb.

+2

:

myfile >> comment

":", ": ". , myfile , "my", , , .

, "" start ( ). , :

myfile >> comment >> start >> comment >> finish;

, start finish .

() start finish . , , , , ... , , .

, , " " , 10 000 .

+1

gdb, cont , ( bt); , , ( , , g++ -g, ).

EDIT: , , , , NULL-ed. , , "= NULL", ..:

delete myPointer;
myPointer = NULL;

; , ()/delete ( , , ).

btw, your code snippet does not contain dynamically allocated memory (except for std :: string, which dynamically allocate memory dynamically).

0
source

Have you learned what the meaning of the beginning and the end is and does the file have enough content to fill the vectors x and y?

A better approach would be to refactor the loop logic - you have to break the moment you click on the EOF file. At this stage you have left his faith.

0
source

Source: https://habr.com/ru/post/1764360/


All Articles