Dear R Gurus,
I would very much appreciate some help with this code snippit
from my RODBC package.
R crashes or exhibits bizarre behaviour when repeatedly fetching
large numbers of rows.
Examples:
> odbcFetchRows(0,max=50000)->xx
> odbcFetchRows(0,max=50000)->xx
> odbcFetchRows(0,max=50000)->xx
> odbcFetchRows(0,max=50000)->xx
> odbcFetchRows(0,max=50000)->xx
3rd arg (table) not of type VECSXP, from R_HashGet
Segmentation fault (core dumped)
> odbcFetchRows(0,max=100000)->xx
> odbcFetchRows(0,max=100000)->xx
Segmentation fault (core dumped)
> odbcFetchRows(0,max=50000)
...
...[49996,] "Some dummy data"
[49997,] "Some dummy data"
[49998,] "Some dummy data"
[49999,] "Some dummy data"
[50000,] "Some dummy data"
$stat
[1] 1
> odbcFetchRows(0,max=50000)
Error in odbcFetchRows(0, max = 50000) : can not set length of
non-vector> odbcFetchRows(0,max=50000)
[49998,] "Some dummy data"
[49999,] "Some dummy data"
[50000,] "Some dummy data"
$stat
[1] 1
> odbcFetchRows(0,max=50000)
Segmentation fault (core dumped)
(This is using a hacked version that does not actually fetch rows
from the database to save time).
Using the C that I distilled out (see below) to remove all
dependencies on sql/odbc I get something even more bizarre:
> odbcFetchRows(0,max=50000)->xx
> odbcFetchRows(0,max=50000)->xx
> odbcFetchRows(0,max=50000)->xx
Segmentation fault (core dumped)
but
> odbcFetchRows(0,max=25000)->xx
> odbcFetchRows(0,max=25000)->xx
> odbcFetchRows(0,max=25000)->xx
> odbcFetchRows(0,max=25000)->xx
Error: corrupted options list
Error: corrupted options list
Error: corrupted options list
Error: corrupted options list
Error: corrupted options list
Error: corrupted options list
Error: corrupted options list
Error: corrupted options list
.....
(endless loop needing killing)
I have stared at this for ages and cannot see the bug? Is it me
or is there a problem in garbage collection or elsewhere?
Thanks in advance for any enlightenment.
Michael
-----------------------------------------------------------------
/* RODBC low level interface : crash function
*
* crash.c
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <Rinternals.h>
#include <Rdefines.h>
#define DBG(x,y) if(debug >= x) printf("%s\n",y)
/*******************************************************************************/
/* Replacement callee for odbcFetchRows to demonstate bug.
*/
/* Independant of sql/odbc
*/
/* Compile with
*/
/* cc -g -Wall -I/usr/local/src/R-1.0.0/include/ -o crash.o -c crash.c
*/
/* gcc -shared -g -Wall -o crash.so crash.o
*/
/* mv crash.so /usr/local/src/R-1.0.0/library/RODBC/libs/RODBC.so
*/
/* then
*/
/* $R -q
*/
/* >library(RODBC)
*/
/* >odbcFetchRows(0,max=50000)
*/
/* and repeat till crashes.
*/
/*
*/
/* Note that the loop will never exit unless max is specified.
*/
/*
*/
/* Designed to work with RODBC-0.6.1a
*/
/* Caller looks like:
*/
/*
*/
/* "odbcFetchRows"<-
*/
/* function(channel,max=0,transposing=F,buffsize=1000,debug=0)
*/
/* {
*/
/*
erg<-.Call("RODBCFetchRows",as.integer(channel),max=as.real(max),
*/
/* transposing=as.logical(transposing),
*/
/* buffsize=as.real(buffsize),debug=as.integer(debug))
*/
/* return(erg)
*/
/* }
*/
/*
*/
/*
*/
/*******************************************************************************/
SEXP RODBCFetchRows(SEXP sock,SEXP max,SEXP tx,SEXP bs,SEXP dbg)
{
SEXP data,t_data,names,ans,stat,dim;
int status=1,
i, /* col counter */
NCOLS,
channel=INTEGER(sock)[0], /* not used here */
debug=INTEGER(dbg)[0],
transposing=(int)LOGICAL(tx)[0]; /*true if transposing, not used here*/
long maximum=(long)REAL(max)[0];
long j=1,k=1, /* row counters*/
buffsize=(long)REAL(bs)[0], /* prealloc if row count NA*/
length,offset,t_offset; /* counts into output buf*/
NCOLS=1;
PROTECT(ans=NEW_LIST(2)); /*create answer [0] = data, [1]=stat */
PROTECT(stat=NEW_INTEGER(1)); /* numeric status vector */
PROTECT(data=NEW_CHARACTER(buffsize));
while(1){
for (i=1; i<= NCOLS; i++){
offset=((i-1)*maximum)+(j-1);
}
DBG(2,"writing to data");
STRING(data)[offset]=COPY_TO_USER_STRING("Some dummy data");
if(offset +NCOLS >= buffsize){
DBG(1,"reallocating space");
length=length(data);
buffsize=length+buffsize;
SET_LENGTH(data,buffsize);
}
j++;
if(maximum && j>maximum)
break;
}
/* transpose it */
DBG(1,"trimming");
SET_LENGTH(data,j*NCOLS); /* trim down buffer*/
INTEGER(stat)[0]=status;
PROTECT(dim=NEW_INTEGER(2));
INTEGER(dim)[1]=NCOLS;
INTEGER(dim)[0]=length(data)/NCOLS;
DBG(2,"writing dim to data");
SET_DIM(data,dim);
DBG(2,"writing to ans 0");
VECTOR(ans)[0]=data;
DBG(2,"writing to ans 1");
VECTOR(ans)[1]=stat;
DBG(3,"protecting names");
PROTECT(names=NEW_CHARACTER(2));
DBG(2,"writing to names 0");
STRING(names)[0]=COPY_TO_USER_STRING("data");
DBG(2,"writing to names 1");
STRING(names)[1]=COPY_TO_USER_STRING("stat");
DBG(2,"writing to ans");
SET_NAMES(ans,names);
UNPROTECT(5);
return ans;
}
/****************************************/
/* Just a dummy to allow library(RODBC) */
/****************************************/
void RODBCInit()
{
}
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To:
r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._