S
Simple Simon
[posted separately to comp.unix.programmer and
Can't figure out why this code generates a SIGSEGV in
fillGlobalBuffer() (below).
globalBuffer is allocated in caller.c, then its address is passed to
a pointer of the same type inside of callee.c, and that local pointer
is used as the reference written to from within callee.c.
It doesn't appear to actually write anything there, and when I try to
read it back I get empty data (from the original calloc() call) and
then a segfault.
I increment the offset into globalBuffer to write successive bits of
data (in this case, timestamps but it's just for illustration).
I am apparently making a fundamental error with the C language and
can't actually assign and use a pointer this way, but I'm not
clear as to why.
Or, I actually can do this but I'm going about it the wrong way.
I get a zeros from the printf() call in fillGlobalBuffer() before it
crashes.
References to, or other info describing, what I'm being stupid about
would be greatly appreciated.
===== Environ
Linux, GCC.
%uname -a
Linux tmdev 2.4.20-4GB #1 Tue May 24 16:14:53 UTC 2005 i686 unknown
unknown GNU/Linux
%gcc --version
gcc (GCC) 3.3 20030226 (prerelease) (SuSE Linux)
Copyright (C) 2002 Free Software Foundation, Inc.
%ld --version
GNU ld version 2.13.90.0.18 20030121 (SuSE Linux)
Copyright 2002 Free Software Foundation, Inc.
%/lib/libc.so.6
GNU C Library stable release version 2.3.2, by Roland McGrath et al.
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.3 20030226 (prerelease) (SuSE Linux).
Compiled on a Linux 2.4.20 system on 2003-03-13.
Can't figure out why this generates a SIGSEGV in fillGlobalBuffer()
(below).
globalBuffer is allocated in caller.c, then its address is passed to
a pointer of the same type inside of callee.c, and that local pointer
is used as the reference written to.
I increment the offset into globalBuffer to write successive bits of
data (in this case, timestamps but it's just for illustration).
I apparently can't assign and use a pointer this way, but I'm not
clear as to why. Or, I can do this but I'm going about it the wrong
way.
I get a zeros from the printf() call in fillGlobalBuffer() before it
crashes.
References to, or other info describing, what I'm being stupid about
would be greatly appreciated.
===== Compile
% gcc -g -Wall -o test caller.c callee.c -I.
===== Code
/* caller.c
*/
#include "callee.h"
unsigned char * globalBuffer ;
int
main(void)
{
int i, bytes_written ;
struct timeval tv ;
if ( (globalBuffer=calloc(1, GLOBAL_BUFSIZE)) == NULL )
{
fprintf(stderr,"calloc() failed on globalBuffer\n" );
exit(-1);
}
setGlobalBuffer( globalBuffer, GLOBAL_BUFSIZE ) ;
bytes_written = 0 ;
for ( i = 0 ; i < GLOBAL_BUFSIZE ; )
{
gettimeofday( &tv, NULL ) ;
fillGlobalBuffer(&tv, sizeof(struct timeval), &bytes_written);
i += bytes_written ;
}
// verify globalBuffer contents
for ( i = 0 ; i < GLOBAL_BUFSIZE ; i += sizeof(struct timeval) )
{
struct timeval * tv ;
tv = (struct timeval *)(globalBuffer+i) ;
// HERE
printf("Index=%d, timeval=%lu.%lu\n",i,tv->tv_sec,tv->tv_usec);
}
return 0 ;
}
/* callee.h
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#define GLOBAL_BUFSIZE 1024
void
setGlobalBuffer( unsigned char * gb, int gbmax ) ;
int
fillGlobalBuffer( void * data, int datalen, int * written ) ;
/* callee.c
*/
#include "callee.h"
unsigned char * bigBuf ;
int bbIndex ;
int bbMax ;
void
setGlobalBuffer( unsigned char * gb, int gbmax )
{
bigBuf = gb ;
bbIndex = 0 ;
bbMax = gbmax ;
}
int
fillGlobalBuffer( void * data, int datalen, int * written )
{
struct timeval * tv ;
if ( bbIndex + datalen > bbMax )
return -1 ;
memcpy( bigBuf+bbIndex, data, datalen ) ;
tv = (struct timeval *)bigBuf+bbIndex ;
printf("fGB(): wrote %lu.%lu to bigBuf\n",tv->tv_sec,tv->tv_usec);
bbIndex += datalen ;
*written = datalen ;
return 0 ;
}
===== Output
% ./test
fGB(): wrote 1142826382.680840 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.4833 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
Segmentation fault (core dumped)
Can't figure out why this code generates a SIGSEGV in
fillGlobalBuffer() (below).
globalBuffer is allocated in caller.c, then its address is passed to
a pointer of the same type inside of callee.c, and that local pointer
is used as the reference written to from within callee.c.
It doesn't appear to actually write anything there, and when I try to
read it back I get empty data (from the original calloc() call) and
then a segfault.
I increment the offset into globalBuffer to write successive bits of
data (in this case, timestamps but it's just for illustration).
I am apparently making a fundamental error with the C language and
can't actually assign and use a pointer this way, but I'm not
clear as to why.
Or, I actually can do this but I'm going about it the wrong way.
I get a zeros from the printf() call in fillGlobalBuffer() before it
crashes.
References to, or other info describing, what I'm being stupid about
would be greatly appreciated.
===== Environ
Linux, GCC.
%uname -a
Linux tmdev 2.4.20-4GB #1 Tue May 24 16:14:53 UTC 2005 i686 unknown
unknown GNU/Linux
%gcc --version
gcc (GCC) 3.3 20030226 (prerelease) (SuSE Linux)
Copyright (C) 2002 Free Software Foundation, Inc.
%ld --version
GNU ld version 2.13.90.0.18 20030121 (SuSE Linux)
Copyright 2002 Free Software Foundation, Inc.
%/lib/libc.so.6
GNU C Library stable release version 2.3.2, by Roland McGrath et al.
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 3.3 20030226 (prerelease) (SuSE Linux).
Compiled on a Linux 2.4.20 system on 2003-03-13.
Can't figure out why this generates a SIGSEGV in fillGlobalBuffer()
(below).
globalBuffer is allocated in caller.c, then its address is passed to
a pointer of the same type inside of callee.c, and that local pointer
is used as the reference written to.
I increment the offset into globalBuffer to write successive bits of
data (in this case, timestamps but it's just for illustration).
I apparently can't assign and use a pointer this way, but I'm not
clear as to why. Or, I can do this but I'm going about it the wrong
way.
I get a zeros from the printf() call in fillGlobalBuffer() before it
crashes.
References to, or other info describing, what I'm being stupid about
would be greatly appreciated.
===== Compile
% gcc -g -Wall -o test caller.c callee.c -I.
===== Code
/* caller.c
*/
#include "callee.h"
unsigned char * globalBuffer ;
int
main(void)
{
int i, bytes_written ;
struct timeval tv ;
if ( (globalBuffer=calloc(1, GLOBAL_BUFSIZE)) == NULL )
{
fprintf(stderr,"calloc() failed on globalBuffer\n" );
exit(-1);
}
setGlobalBuffer( globalBuffer, GLOBAL_BUFSIZE ) ;
bytes_written = 0 ;
for ( i = 0 ; i < GLOBAL_BUFSIZE ; )
{
gettimeofday( &tv, NULL ) ;
fillGlobalBuffer(&tv, sizeof(struct timeval), &bytes_written);
i += bytes_written ;
}
// verify globalBuffer contents
for ( i = 0 ; i < GLOBAL_BUFSIZE ; i += sizeof(struct timeval) )
{
struct timeval * tv ;
tv = (struct timeval *)(globalBuffer+i) ;
// HERE
printf("Index=%d, timeval=%lu.%lu\n",i,tv->tv_sec,tv->tv_usec);
}
return 0 ;
}
/* callee.h
*/
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <string.h>
#define GLOBAL_BUFSIZE 1024
void
setGlobalBuffer( unsigned char * gb, int gbmax ) ;
int
fillGlobalBuffer( void * data, int datalen, int * written ) ;
/* callee.c
*/
#include "callee.h"
unsigned char * bigBuf ;
int bbIndex ;
int bbMax ;
void
setGlobalBuffer( unsigned char * gb, int gbmax )
{
bigBuf = gb ;
bbIndex = 0 ;
bbMax = gbmax ;
}
int
fillGlobalBuffer( void * data, int datalen, int * written )
{
struct timeval * tv ;
if ( bbIndex + datalen > bbMax )
return -1 ;
memcpy( bigBuf+bbIndex, data, datalen ) ;
tv = (struct timeval *)bigBuf+bbIndex ;
printf("fGB(): wrote %lu.%lu to bigBuf\n",tv->tv_sec,tv->tv_usec);
bbIndex += datalen ;
*written = datalen ;
return 0 ;
}
===== Output
% ./test
fGB(): wrote 1142826382.680840 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.4833 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
fGB(): wrote 0.0 to bigBuf
Segmentation fault (core dumped)