LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-08-2010, 01:46 AM   #1
bartonski
Member
 
Registered: Jul 2006
Location: Louisville, KY
Distribution: Fedora 12, Slackware, Debian, Ubuntu Karmic, FreeBSD 7.1
Posts: 443
Blog Entries: 1

Rep: Reputation: 48
*** glibc detected *** free(): invalid next size (fast): 0x0804a1a8 ***


I've written the following code:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *get_input_line( char *input_line, int *input_line_size, FILE *f ) {
    long startpos = ftell( f );
            fprintf(stderr,"line: %d\tstartpos       : [%ld]\n", __LINE__ , startpos );
    char *retstr = input_line;
    char *newstr = NULL;
        fprintf(stderr,"line: %d\tfile_pos in f  : [%ld]\n", __LINE__, ftell( f ) );    
    input_line = fgets( input_line, *input_line_size, f );
            fprintf(stderr,"line: %d\tinput_line line len : %d last char:[%c]\n", __LINE__ , strlen(input_line), input_line[ strlen(input_line) - 1] );

        fprintf(stderr,"line: %d\tfile_pos in f  : [%ld]\n", __LINE__, ftell( f ) );    
    while(input_line[ strlen(input_line) - 1] != '\n' || input_line == newstr){
        *input_line_size *= 2;
        fprintf(stderr,"line: %d\tinput_line_size: [%d]\n", __LINE__, *input_line_size );    

        newstr = malloc( *input_line_size * sizeof(char) );
        fprintf(stderr,"line: %d\tsize of newstr : [%ld]\n", __LINE__, *input_line_size * sizeof(char) );    
        fseek( f, startpos, SEEK_SET );
        fprintf(stderr,"line: %d\tfile_pos in f  : [%ld]\n", __LINE__, ftell( f ) );    

        newstr = fgets( newstr, *input_line_size, f );
        fprintf(stderr,"line: %d\tnewstr         : [%lx]\n", __LINE__, newstr );    
        fprintf(stderr,"line: %d\tnewstr         : [%s]\n", __LINE__, newstr );    

        if( 0 != strcmp(input_line, newstr) ){
            char *freeme = NULL;
            fprintf(stderr,"line: %d\tinput_line:\t[%lx]\n", __LINE__, input_line );    
            fprintf(stderr,"line: %d\tinput_line:\t[%s]\n", __LINE__, input_line );    
            freeme=input_line;
            fprintf(stderr,"line: %d\tfreeme    :\t[%lx]\n", __LINE__, freeme );    
            fprintf(stderr,"line: %d\tfreeme    :\t[%s]\n", __LINE__, freeme );    

            input_line = newstr;
            fprintf(stderr,"line: %d\tinput_line:\t[%s]\n", __LINE__, input_line );    

            free( freeme );
        }
    }
    /* fprintf(stderr,"get_input_line\n");    
    fprintf(stderr,"%s\n", input_line );    
    fprintf(stderr,"%d\n", *input_line_size );
    fprintf(stderr,"end get_input_line\n");    */

    fprintf(stderr,"%d\tinput_line:\t[%s]\n", __LINE__, input_line );    
    fprintf(stderr,"===================================\n", __LINE__, input_line );    
    return input_line;
}

int main( int argc, char *argv[] ) {
    FILE *input;
    char *compare_line;
    int input_line_size = 2;
    char *input_line = malloc( input_line_size * sizeof(char) );
    /*debug*/
    strncpy( input_line, "X", strlen( "X" ) );
    /*debug*/
    if( argc > 1 ) {
        if ( 0 == (input = fopen( argv[1],"r" ) ) ) {
            fprintf(stderr, "Could not open '%s'\n", argv[1] );
            return 1;
        } 
        fprintf(stderr,"argc is %d. Expecting argc > 1\n", argc );
        fprintf(stderr,"input %ld.\n", input );
    } else {
        fprintf(stderr,"argc is %d. Expecting 1.\n", argc );
        input = stdin;
    }
    /* get_input_line( input_line, &input_line_size, input ); */
    /* start body */
    while( input_line = get_input_line( input_line, &input_line_size, input ) ){
        printf( "%s", input_line );
    }
    /* end body */

    if( input != stdin ) {
        fclose( input );
    }
    return 0;
}
when I run the code, I get the following:

Code:
$ lc lc.c
.
.
.
===================================

line: 7    startpos       : [60]
line: 10    file_pos in f  : [60]
line: 12    input_line line len : 63 last char:[F]
line: 14    file_pos in f  : [123]
line: 17    input_line_size: [128]
line: 20    size of newstr : [128]
line: 22    file_pos in f  : [60]
line: 25    newstr         : [804a218]
line: 26    newstr         : [char *get_input_line( char *input_line, int *input_line_size, FILE *f ) {
]
line: 30    input_line:    [804a1a8]
line: 31    input_line:    [char *get_input_line( char *input_line, int *input_line_size, F]
line: 33    freeme    :    [804a1a8]
line: 34    freeme    :    [char *get_input_line( char *input_line, int *input_line_size, F]
line: 37    input_line:    [char *get_input_line( char *input_line, int *input_line_size, FILE *f ) {
]
*** glibc detected *** free(): invalid next size (fast): 0x0804a1a8 ***
Aborted
There's only a single call to free() in the code:

Code:
            free( freeme );
I can't tell what's causing the error... freeme seems to be the correct size for the data it contains, and I don't seem to be causing a seg fault...
 
Old 03-08-2010, 02:57 AM   #2
neonsignal
Senior Member
 
Registered: Jan 2005
Location: Melbourne, Australia
Distribution: Debian Bookworm (Fluxbox WM)
Posts: 1,391
Blog Entries: 54

Rep: Reputation: 360Reputation: 360Reputation: 360Reputation: 360
The problem is in get_input_line. When the input line finally gets read in completely, you do not transfer the latest malloced newstr to input_line.

This means that on subsequent calls to get_input_line, the length value does not match (so the fgets writes off the end of the block).

This causes memory corruption, which catches up with you the first time you encounter a line that is longer than the length value of the first line and try to free the block where the write went off the end.

Last edited by neonsignal; 03-08-2010 at 03:07 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
*** glibc detected *** free(): invalid next size hs_linux Programming 1 02-27-2010 01:08 AM
Getting *** glibc detected *** free(): invalid next size (normal): herat.acharya Programming 3 10-23-2009 03:50 AM
grep -Ri <searchterm> * returns glibc detected *** free(): invalid next size (fast) abylin1 Linux - Newbie 3 05-14-2009 04:08 PM
*** glibc detected *** free(): invalid next size (normal): 0x0000000000503e70 *** vbreddy Programming 2 04-10-2006 06:27 PM
*** glibc detected *** free(): invalid next size (normal): 0x0804c050 *** water&sky Linux - Software 1 03-02-2006 08:23 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:48 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration