This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/2226] New: Memory leak in fputws
- From: "markxjohnson at earthlink dot net" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: 27 Jan 2006 18:37:55 -0000
- Subject: [Bug libc/2226] New: Memory leak in fputws
- Reply-to: sourceware-bugzilla at sourceware dot org
When using fputws to write to a stream, 12K of memory is leaked for each stream.
I am using the delivered glibc-2.3.5-10 with g++ 4.0.0.
I am attaching 2 programs. The first just shows one call to fopen, fputws,
fflush and fclose. After the call to fopen, the process is consuming 180KB of
virtual memory, after the call to fputws this increases to 196KB and after the
close it drops to 188KB. The program can also be run to use fputs instead of
fputws and in this case, after the call to fopen, the process is consuming
180KB, after the call to fputs this is still 180KB and after the fclose, it
drops to 176KB.
The program can also be invoked so that the stream is set to non-buffering and
then fputws and fputs behave the same.
The second program basically does the same operation 10000 times and prints the
memory usage after the first open and after 10000 loops. For fputws, after the
first fopen, the consumption is 180KB and after 10000 loops it is 120,176KB (or
~12KB per loop). For fputs or non buffered fputws, the final consumption is
still only 176KB.
It looks like the buffer allocated by fputws is being partially leaked.
Program 1
---------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wchar.h>
int main(int argc, char ** argv)
{
char buff[128];
wchar_t w_err[10];
char c_err[10];
for (int i = 0; i <9;i++)
{
w_err[i]=L'A';
c_err[i]='A';
}
if ( argc < 2 || ( argv[1][0] != 'C' && argv[1][0] != 'W' ) )
{
fprintf(stderr,"Usage: a.out C|W [N]\n");
fprintf(stderr,"Pass an arg of W for fputws or C for fputs\n");
fprintf(stderr,"Pass an optional N for a non-buffered stream\n");
exit(1);
}
int no_buffer = 0;
if ( argc == 3 )
{
if ( argv[2][0] == 'N' )
no_buffer = 1;
else
{
fprintf(stderr,"Usage: a.out C|W [N]\n");
fprintf(stderr,"Pass an arg of W for fputws or C for
fputs\n");
fprintf(stderr,"Pass an optional N for a non-buffered
stream\n");
exit(1);
}
}
w_err[9]=0;
c_err[9]=0;
sprintf(buff,"grep VmData /proc/%d/status", getpid());
fprintf(stderr,"Original Size\n");
system ( buff );
FILE * f = fopen("./x.txt", "a");
fprintf(stderr,"After open\n");
system ( buff );
if ( no_buffer )
setvbuf(f, NULL, _IONBF, 0 );
if (argv[1][0] == 'C' )
{
fputs( c_err, f );
fprintf(stderr,"After fputs\n");
system ( buff );
}
else
{
fputws( w_err, f );
fprintf(stderr,"After fputws\n");
system ( buff );
}
fflush( f );
fclose( f );
fprintf(stderr,"After close\n");
system ( buff );
return 0;
}
Program 2
---------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wchar.h>
int main(int argc, char ** argv)
{
char buff[128];
wchar_t w_err[10];
char c_err[10];
for (int i = 0; i <9;i++)
{
w_err[i]=L'A';
c_err[i]='A';
}
if ( argc < 2 || ( argv[1][0] != 'C' && argv[1][0] != 'W' ) )
{
fprintf(stderr,"Usage: a.out C|W [N]\n");
fprintf(stderr,"Pass an arg of W for fputws or C for fputs\n");
fprintf(stderr,"Pass an optional N for a non-buffered stream\n");
exit(1);
}
int no_buffer = 0;
if ( argc == 3 )
{
if ( argv[2][0] == 'N' )
no_buffer = 1;
else
{
fprintf(stderr,"Usage: a.out C|W [N]\n");
fprintf(stderr,"Pass an arg of W for fputws or C for
fputs\n");
fprintf(stderr,"Pass an optional N for a non-buffered
stream\n");
exit(1);
}
}
w_err[9]=0;
c_err[9]=0;
sprintf(buff,"grep VmData /proc/%d/status", getpid());
fprintf(stderr,"Original Size\n");
system ( buff );
int j;
for ( j = 0;j < 10000; j++)
{
FILE * f = fopen("./x.txt", "a");
if ( j == 0 )
{
fprintf(stderr,"After first open\n");
system ( buff );
}
if ( no_buffer )
setvbuf(f, NULL, _IONBF, 0 );
if (argv[1][0] == 'C' )
fputs( c_err, f );
else
fputws( w_err, f );
fflush( f );
fclose( f );
}
fprintf(stderr,"After %d loops\n", j);
system ( buff );
return 0;
}
--
Summary: Memory leak in fputws
Product: glibc
Version: 2.3.5
Status: NEW
Severity: critical
Priority: P2
Component: libc
AssignedTo: drepper at redhat dot com
ReportedBy: markxjohnson at earthlink dot net
CC: glibc-bugs at sources dot redhat dot com
GCC host triplet: Fedora Core 4/2.6.11-1.1369_FC4SMP
http://sourceware.org/bugzilla/show_bug.cgi?id=2226
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.