Bug 162129 - *** glibc detected *** free(): invalid next size (fast): 0x0000000000502150 *** Aborted
*** glibc detected *** free(): invalid next size (fast): 0x0000000000502150 *...
Status: CLOSED NOTABUG
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: glibc (Show other bugs)
4.0
x86_64 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2005-06-30 02:39 EDT by sangameshwar Allipuram
Modified: 2007-11-30 17:07 EST (History)
0 users

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2005-06-30 03:54:34 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description sangameshwar Allipuram 2005-06-30 02:39:29 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.2) Gecko/20040301

Description of problem:
The sample program written in C++ fails with this following error.

*** glibc detected *** free(): invalid next size (fast): 0x0000000000502150 ***

I am using x86_64 opteron machine with RHEL 4.0. I debugged with gdb in which
which i found there is no problem in the program code which i am providing down.

This bug is occurring at line pointed "->" in the program below. When i replaced
all the lines in this sample program pointing with ">", with c style "malloc" and string functions, this program works fine. And also works fine when i set
MALLOC_CHECK_=0.

I am providing the part of gdb output with back trace in the additional information section.

Thanks alot in advance for help.

-------------------------------- replicate.cc ----------------------------
#include <iostream>
#include <string>
                                                                                                                                               
using namespace std;
                                                                                                                                               
int main(int argc, char *argv[])
{
std::string c_line("ppp -L/home/sangam/xxx/XXXX/lib -D__DDDD -D__XXXXXXX a.c -I/home/sangam/xxx/XXXX/include -L/home/sangam/xxx/XXXX/lib/xxxx -lxxXxxx -lXXxxxxxxXX ");
    int count_blanks = 9;
    int pos1,pos2;
    int i = 0;
    char **args;
  > std::string this_opt;
    args = new char *[count_blanks];
    pos1 = c_line.find_first_of(' ', 0);
    for (int i = 0; i < count_blanks - 1; i ++) {
        std::string::size_type pos2 = c_line.find_first_of(' ', pos1 + 1);
 ->     this_opt = c_line.substr(pos1 + 1, pos2 - (pos1 + 1));
  >     this_opt[pos2 - pos1] = '\0';
  >     args[i] = new char [this_opt.size() + 1];
  >     strcpy(args[i], this_opt.c_str());
        pos1 = pos2;
    }
    args[count_blanks - 1] = 0;
                                                                                                                                               
    while (args[i] != NULL)
    cout <<args[i++]<<endl;
}

-------------------------- End of replicate.cc ------------------------------

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
$g++ replicate.cc -g -o replicate
$ ./replicate
*** glibc detected *** free(): invalid next size (fast): 0x0000000000502150 ***
Aborted

  

Actual Results:  *** glibc detected *** free(): invalid next size (fast): 0x0000000000502150 ***
Aborted

Expected Results:  $./replicate
$-L/home/sangam/xxx/XXXX/lib
-D__DDDD
-D__XXXXXXX
a.c
-I/home/sangam/xxx/XXXX/include
-L/home/sangam/xxx/XXXX/lib/xxxx
-lxxXxxx
-lXXxxxxxxXX

Additional info:

Part of gdb output with back trace.
------------------------------------

(gdb)
17              std::string::size_type pos2 = c_line.find_first_of(' ', pos1 + 1);
(gdb)
18              this_opt = c_line.substr(pos1 + 1, pos2 - (pos1 + 1));
(gdb)
19              this_opt[pos2 - pos1] = '\0';
(gdb)
20              args[i] = new char [this_opt.size() + 1];
(gdb)
21              strcpy(args[i], this_opt.c_str());
(gdb)
22              pos1 = pos2;
(gdb)
16          for (int i = 0; i < count_blanks - 1; i ++) {
(gdb)
17              std::string::size_type pos2 = c_line.find_first_of(' ', pos1 + 1);
(gdb)
18              this_opt = c_line.substr(pos1 + 1, pos2 - (pos1 + 1));
(gdb)
*** glibc detected *** free(): invalid next size (fast): 0x0000000000502150 ***
 
Program received signal SIGABRT, Aborted.
0x000000366762e37d in raise () from /lib64/tls/libc.so.6
(gdb) bt
#0  0x000000366762e37d in raise () from /lib64/tls/libc.so.6
#1  0x000000366762faae in abort () from /lib64/tls/libc.so.6
#2  0x0000003667662a01 in __libc_message () from /lib64/tls/libc.so.6
#3  0x00000036676685ce in _int_free () from /lib64/tls/libc.so.6
#4  0x0000003667668916 in free () from /lib64/tls/libc.so.6
#5  0x000000366a3adfde in operator delete () from /usr/lib64/libstdc++.so.6
#6  0x000000366a3903a2 in std::string::_Rep::_M_destroy () from /usr/lib64/libstdc++.so.6
#7  0x000000366a3904d5 in std::string::assign () from /usr/lib64/libstdc++.so.6
#8  0x000000366a390509 in std::string::operator= () from /usr/lib64/libstdc++.so.6
#9  0x0000000000400f2b in main (argc=1, argv=0x7fbffff958) at replecate.cc:18
Comment 1 Jakub Jelinek 2005-06-30 03:54:34 EDT
glibc just points a bug in your testcase.
If you used a memory allocation debugger like valgrind or ElectricFence, you'd
see it yourself clearly:
valgrind --tool=memcheck ./a
==31256== Memcheck, a memory error detector for x86-linux.
==31256== Copyright (C) 2002-2004, and GNU GPL'd, by Julian Seward et al.
==31256== Using valgrind-2.2.0, a program supervision framework for x86-linux.
==31256== Copyright (C) 2000-2004, and GNU GPL'd, by Julian Seward et al.
==31256== For more details, rerun with: -v
==31256==
==31256== Invalid write of size 1
==31256==    at 0x8048C5C: main (a.C:19)
==31256==  Address 0x1BB4B1C8 is 0 bytes after a block of size 40 alloc'd
==31256==    at 0x1B904AFB: operator new(unsigned) (vg_replace_malloc.c:133)
==31256==    by 0x1B9A5181: std::string::_Rep::_S_create(unsigned, unsigned,
std::allocator<char> const&) (in /usr/lib/libstdc++.so.6.0.3)
==31256==    by 0x1B9A7296: (within /usr/lib/libstdc++.so.6.0.3)
==31256==    by 0x1B9A749A: std::string::string(std::string const&, unsigned,
unsigned) (in /usr/lib/libstdc++.so.6.0.3)
-L/home/sangam/xxx/XXXX/lib
-D__DDDD
-D__XXXXXXX
a.c
-I/home/sangam/xxx/XXXX/include
-L/home/sangam/xxx/XXXX/lib/xxxx
-lxxXxxx
-lXXxxxxxxXX
==31256==
==31256== ERROR SUMMARY: 8 errors from 1 contexts (suppressed: 19 from 1)
==31256== malloc/free: in use at exit: 176 bytes in 9 blocks.
==31256== malloc/free: 18 allocs, 9 frees, 652 bytes allocated.
==31256== For a detailed leak analysis,  rerun with: --leak-check=yes
==31256== For counts of detected errors, rerun with: -v

The bug is the
this_opt[pos2 - pos1] = '\0';
line.  a) it is unnecessary, it is STL's responsibility to make things terminated
b) is wrong.  You called substr with pos2 - pos1 - 1 length, which means the
string is pos2 - pos1 - 1 bytes long, at
this_opt[pos2 - pos1 - 1]
there is the terminating '\0'.  But by writing to this_opt[pos2 - pos1] you are
writing one past the terminating '\0', and there is absolutely no guarantee that
was allocated for the string.  It was not, so you are clobbering internal
malloc's control structures and glibc subsequently complains.
Comment 2 sangameshwar Allipuram 2005-06-30 05:00:38 EDT
Thanks alot for the help in solving the problem. I dont have valgrind tool.
Thanks again for help.
Comment 3 Jakub Jelinek 2005-06-30 05:45:26 EDT
valgrind-2.2.0-5.EL4 is shipped as part of RHEL4, though for the time being
it only supports 32-bit i?86 binaries/libraries, so you need to build with
-m32 if you want to use valgrind on your program.

Note You need to log in before you can comment on or make changes to this bug.