[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