当前位置: 动力学知识库 > 问答 > 编程问答 >

c - How to handle " *** glibc detected *** ./a: double free or corruption (top): " error for file handling function?

问题描述:

I haven't used Dynamic Memory Allocation, and not freeing memory anywhere. It's even giving a double free error. Can any one please help me out?

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <sys/types.h>

#include <sys/inotify.h>

#include <limits.h>

#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/

#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/

#define EVENT_SIZE ( sizeof (struct inotify_event) ) /*size of one event*/

#define BUF_LEN ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/

#define SIZE 20000

int main( int argc, char **argv )

{

int length, i = 0, wd;

int fd;

char buffer[BUF_LEN];

time_t timer;

char buffer2[25];

char *s=NULL;

struct tm* tm_info;

FILE *fk;

//char buffer[EVENT_BUF_LEN];

char str1[] = "File has been updated at time :";

time(&timer);

tm_info = localtime(&timer);

strftime(buffer2, 25, "%Y:%m:%d %H:%M:%S", tm_info);

fk = fopen( "/home/technoworld/Desktop/file.txt" , "w" );

/* Initialize Inotify*/

fd = inotify_init();

if ( fd < 0 ) {

perror( "Couldn't initialize inotify");

}

/* add watch to starting directory */

wd = inotify_add_watch(fd, argv[1], IN_MODIFY );

if (wd == -1)

{

printf("Couldn't add listen to %s\n",argv[1]);

}

else

{

printf("Listening: %s\n",argv[1]);

}

/* do it forever*/

while(1)

{

i = 0;

length = read( fd, buffer, BUF_LEN );

if ( length < 0 ) {

perror( "read" );

}

while ( i < length ) {

struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];

if ( event->len ) {

if ( event->mask & IN_MODIFY) {

if (event->mask & IN_ISDIR)

printf( "The directory %s was modified.\n", event->name );

else

{

printf( "The file %s was modified at %s \n", event->name, buffer2 );

fprintf(fk,"%s %s %c",str1, buffer2, '\n');

}

}

i += EVENT_SIZE + event->len;

}

}

fcloseall(fk);

}

/* Clean up*/

inotify_rm_watch( fd, wd );

close( fd );

return 0;

}

I am trying to listen the change in file and writing the change in log file with time stamp.

Error:

Listening: /home/technoworld/Desktop/tmp/

The file .goutputstream-L3JTXW was modified at 2013:05:24 22:06:21

The file .goutputstream-IRR4XW was modified at 2013:05:24 22:06:21

*** glibc detected *** ./a: double free or corruption (fasttop): 0x09438008 ***

======= Backtrace: =========

/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb7624ee2]

./a[0x80488bb]

/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb75c84d3]

./a[0x80485c1]

======= Memory map: ========

08048000-08049000 r-xp 00000000 07:00 558766 /home/technoworld/Desktop/a

08049000-0804a000 r--p 00000000 07:00 558766 /home/technoworld/Desktop/a

0804a000-0804b000 rw-p 00001000 07:00 558766 /home/technoworld/Desktop/a

09438000-09459000 rw-p 00000000 00:00 0 [heap]

b7578000-b7594000 r-xp 00000000 07:00 394123 /lib/i386-linux-gnu/libgcc_s.so.1

b7594000-b7595000 r--p 0001b000 07:00 394123 /lib/i386-linux-gnu/libgcc_s.so.1

b7595000-b7596000 rw-p 0001c000 07:00 394123 /lib/i386-linux-gnu/libgcc_s.so.1

b75ae000-b75af000 rw-p 00000000 00:00 0

b75af000-b7752000 r-xp 00000000 07:00 394098 /lib/i386-linux-gnu/libc-2.15.so

b7752000-b7753000 ---p 001a3000 07:00 394098 /lib/i386-linux-gnu/libc-2.15.so

b7753000-b7755000 r--p 001a3000 07:00 394098 /lib/i386-linux-gnu/libc-2.15.so

b7755000-b7756000 rw-p 001a5000 07:00 394098 /lib/i386-linux-gnu/libc-2.15.so

b7756000-b7759000 rw-p 00000000 00:00 0

b776e000-b7773000 rw-p 00000000 00:00 0

b7773000-b7774000 r-xp 00000000 00:00 0 [vdso]

b7774000-b7794000 r-xp 00000000 07:00 394076 /lib/i386-linux-gnu/ld-2.15.so

b7794000-b7795000 r--p 0001f000 07:00 394076 /lib/i386-linux-gnu/ld-2.15.so

b7795000-b7796000 rw-p 00020000 07:00 394076 /lib/i386-linux-gnu/ld-2.15.so

bfe5d000-bfe7e000 rw-p 00000000 00:00 0 [stack]

Aborted (core dumped)

网友答案:

fcloseall does not take any arguments. (How did this even compile?)

Even if the initial fopen is successful (so that fk is not NULL), after the first trip through the while (1) loop, you will have called fcloseall and thus closed the file. The fprintf to fk is thus printing to a closed file. Since file operations allocate and use memory, and close operations free that memory, you are therefore using freed memory, hence the glibc error.

网友答案:

The problem is there because you are working on a 64 bit system and you are not including time.h and the return type from localtime(&timer) is being interpreted as a 32 bit integer rather than a 64-bit pointer (undeclared types default to int) ... You are losing the information in that implicit declaration.

Litmus test to see if I'm right:

declare the following right under the includes:

#include <limits.h>
struct tm;
struct timep;
struct tm *localtime(const time_t *timep);

the SIGSEG will disappear (although your code is still buggy)

The correct thing to do is to #include <time.h>

网友答案:

I included fclose(fk) after while(1) completes. It does not give any error and works fine on terminal. But in this case it does not write on file.txt.

Code:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <limits.h>
#include <time.h>

#define MAX_EVENTS 1024 /*Max. number of events to process at one go*/
#define LEN_NAME 16 /*Assuming that the length of the filename won't exceed 16 bytes*/
#define EVENT_SIZE  ( sizeof (struct inotify_event) ) /*size of one event*/
#define BUF_LEN     ( MAX_EVENTS * ( EVENT_SIZE + LEN_NAME )) /*buffer to store the data of events*/
#define SIZE 20000
int main( int argc, char **argv ) 
{
  int length, i = 0, wd;
  int fd;
  char buffer[BUF_LEN];


    time_t timer;
    char buffer2[25];
    char *s=NULL;
    struct tm* tm_info;

  FILE *fk;
  //char buffer[EVENT_BUF_LEN];
  char str1[] = "File has been updated at time :";
    time(&timer);
    tm_info = localtime(&timer);
    strftime(buffer2, 25, "%Y:%m:%d %H:%M:%S", tm_info);
   fk = fopen( "/home/technoworld/Desktop/file.txt" , "w" );



  /* Initialize Inotify*/
  fd = inotify_init();
  if ( fd < 0 ) {
    perror( "Couldn't initialize inotify");
  }

  /* add watch to starting directory */
  wd = inotify_add_watch(fd, argv[1], IN_MODIFY ); 

  if (wd == -1)
    {
      printf("Couldn't add listen to %s\n",argv[1]);
    }
  else
    {
      printf("Listening: %s\n",argv[1]);
    }

  /* do it forever*/
  while(1)
    {
      i = 0;
      length = read( fd, buffer, BUF_LEN );  

      if ( length < 0 ) {
        perror( "read" );
      }  

      while ( i < length ) {
        struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
        if ( event->len ) {

          if ( event->mask & IN_MODIFY) {
            if (event->mask & IN_ISDIR)
              printf( "The directory %s was modified.\n", event->name );       
            else
        {
                    printf( "The file %s was modified at %s \n", event->name, buffer2 ); 
                    fprintf(fk,"%s %s %c",str1, buffer2, '\n');
        }
          }

            i += EVENT_SIZE + event->len;
        }
      }

    }
fclose(fk);
  /* Clean up*/
  inotify_rm_watch( fd, wd );
  close( fd );

  return 0;
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: