[gambit-list] Tracking Down a Segfault
Joel J. Adamson <adamsonj@email.unc.edu>
adamsonj at email.unc.edu
Thu Sep 4 22:54:10 EDT 2008
Thanks so much for the tips; I have some follow-up questions:
>>>>> "MM" == Mikael More <mikael.more at gmail.com> writes:
MM> - Throwing exceptions with no handler/catcher may sigsegv your
MM> app.
Good to know, I was unaware of this.
MM> - You should presuppose that ___argXX variables inside
MM> Scheme-to-C calls are trashed after C-to-Scheme calls. I.e.: If
MM> you have declared a c-define or c-lambda that takes parameters,
MM> these will appear as ___arg0, ___arg1 etc. in the C code of the
MM> c-define / c-lambda. These will have correct contents all until
MM> you invoke Scheme functions from the C code. not afterwards.
Okay, take the following functions, that may be the source of the
problem:
/* C function for transferring vectors */
int f64vector_length (___SCMOBJ);
double f64vector_ref (___SCMOBJ, int);
double * scm_vector_to_C (___SCMOBJ f64vec)
{
/* initialize the length of the vector */
int len = f64vector_length (f64vec);
/* initializes the new vector */
double * newCvec = malloc (len*sizeof (double));
/* declare a counter */
int i;
/* iterate over the length of the vector copying each object into
the new vector */
for (i = 0; i<len; i++)
{
/* could be re-written using pointer arithmetic */
newCvec[i] = f64vector_ref (f64vec, i);
}
return newCvec;
}
and then the corresponding "c-define"s:
;; Scheme function for getting data out of f64vectors
(c-define (proc1 f64vec i)
(scheme-object int)
double
"f64vector_ref" ""
(f64vector-ref f64vec i))
(c-define (proc2 f64vec)
(scheme-object)
int
"f64vector_length" ""
(f64vector-length f64vec))
MM> So back them up to the stack if you do.
Forgive my ignorance of C, but how do I do that? (where the heck is
this stack that everyone speaks of?)
Now, I also noticed this passage in the C-interface chapter of the
manual:
,----
| Within the C code the variables `___arg1', `___arg2', etc. can be
| referenced to access the converted arguments. Similarly, the result to
| be returned from the call should be assigned to the variable `___result'
| except when the result is of type `struct', `union', `type', `pointer',
| `nonnull-pointer', `function' or `nonnull-function' in which case a
| pointer must be assigned to the variable `___result_voidstar' which is
| of type `void*'. For results of type `pointer', `nonnull-pointer',
| `function' and `nonnull-function', the value assigned to the variable
| `___result_voidstar' must be the pointer or function cast to `void*'.
`----
However, I have functions like this:
(define make-gsl-matrix
(c-lambda (int int scheme-object)
gsl-matrix*
"gsl_matrix * ___matrix = gsl_matrix_alloc (___arg1, ___arg2);
___matrix->data = scm_vector_to_C (___arg3);
___matrix->size1 = ___arg1;
___matrix->size2 = ___arg2;
___result_voidstar = ___matrix;"))
It seems that this is seriously wrong, according to the paragraph above:
the last line should be
___result_voidstar = (void*)___matrix;
and the return type should be void* and not gsl-matrix*, defined as
follows:
(c-define-type gsl-matrix*
(pointer "gsl_matrix"
gsl-matrix*))
But then the question becomes how do I access the result I need? I
would much rather have a function that returns a matrix as a result
(functional style) rather than having it imperatively modify an existing
variable, a la C.
Thanks for your help!
Joel
--
Joel J. Adamson
University of North Carolina at Chapel Hill
CB #3280, Coker Hall
Chapel Hill, NC 27599-3280
Before you reply to this email, please read
http://www.unc.edu/~adamsonj/email-howto.html
More information about the Gambit-list
mailing list