unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* wrong-type-arg in scm_display_backtrace
@ 2002-12-30  1:31 William Morgan
  2002-12-31 23:42 ` Neil Jerram
  0 siblings, 1 reply; 9+ messages in thread
From: William Morgan @ 2002-12-30  1:31 UTC (permalink / raw)


Dear Guile experts,

I am writing a C program that uses Guile as a scripting engine. There
doesn't seem to be a lot of documentation about this aspect of Guile and
I am relying my interpretation of other people's code. Now I have a
problem.

I need to catch Guile exceptions in my own handler. However, when I try
to display the backtrace, I invariably get the following message:

	Exception during displaying of backtrace: wrong-type-arg

Here's the exception-handling procedure I'm passing to scm_internal_cwdr
(mostly copied from an old email by Mikael Djurfeldt):

--- cut here ---

SCM guile_error_handler(void *data, SCM tag, SCM throw_args) {
  SCM port = scm_def_errp;

  if (scm_ilength (throw_args) >= 3) {
    SCM stack = scm_fluid_ref(SCM_VARIABLE_REF (scm_the_last_stack_fluid_var));
    SCM subr = SCM_CAR (throw_args);
    SCM message = SCM_CADR (throw_args);
    SCM args = SCM_CADDR (throw_args);

    scm_newline (port);
    scm_display_backtrace (stack, port, SCM_UNDEFINED, SCM_UNDEFINED);
    scm_newline (port);
    scm_display_error (stack, port, subr, message, args, SCM_EOL);
    return SCM_BOOL_F;
  }
  else {
    scm_puts ("uncaught throw to ", port);
    scm_prin1 (tag, port, 0);
    scm_puts (": ", port);
    scm_prin1 (throw_args, port, 1);
    scm_putc ('\n', port);
  }

  return SCM_BOOL_T;
}

--- cut here ---

I don't fully understand the internals of Guile, particlarly how to deal with
fluids, so perhaps my treatment of scm_the_last_stack_fluid_var is incorrect?
(But the call to scm_display_error seems fine...)

Any help would be appreciated.

Thanks,

-- 
William <wmorgan-gu2@masanjin.net>


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: wrong-type-arg in scm_display_backtrace
  2002-12-30  1:31 wrong-type-arg in scm_display_backtrace William Morgan
@ 2002-12-31 23:42 ` Neil Jerram
  2003-01-05  3:57   ` William Morgan
  0 siblings, 1 reply; 9+ messages in thread
From: Neil Jerram @ 2002-12-31 23:42 UTC (permalink / raw)
  Cc: guile-devel

>>>>> "William" == William Morgan <wmorgan-gu2@masanjin.net> writes:

    William> I need to catch Guile exceptions in my own
    William> handler. However, when I try to display the backtrace, I
    William> invariably get the following message:

    William> 	Exception during displaying of backtrace: wrong-type-arg

    William>     scm_display_backtrace (stack, port, SCM_UNDEFINED, SCM_UNDEFINED);

Is stack #f on entry to scm_display_backtrace?

The point is that the information displayed by scm_display_backtrace
mainly comes from a representation of the stack that was captured at
the point where the error occurred.  The problem is capturing and
saving the stack at that point.

In the context of the Guile REPL this is done using a `lazy-catch'
(see the reference manual) in:

- error-catching-loop
  - lazy-catch with handler lazy-handler-dispatch
    - default-lazy-handler
      - save-stack,

and it is save-stack that sets the value of `the-last-stack'.

To get scm_display_backtrace to work in your scenario, you essentially
need to replicate the kernel of all this in C, i.e.:

(lazy-catch #t
            thunk
            (lambda (args)
              (fluid-set! the-last-stack (make-stack #t))
              (apply throw args)))

Please say if you need more ...  (And yes, this should all be in the
manual.)

        Neil



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: wrong-type-arg in scm_display_backtrace
  2002-12-31 23:42 ` Neil Jerram
@ 2003-01-05  3:57   ` William Morgan
  2003-01-06 19:06     ` Neil Jerram
  0 siblings, 1 reply; 9+ messages in thread
From: William Morgan @ 2003-01-05  3:57 UTC (permalink / raw)


Excerpts (reformatted) from Neil Jerram's mail of 31 Dec 2002 (EST):
> Is stack #f on entry to scm_display_backtrace?

Indeed, it is #f after all.

> To get scm_display_backtrace to work in your scenario, you essentially
> need to replicate the kernel of all this in C, i.e.:
> 
> (lazy-catch #t
>             thunk
>             (lambda (args)
>               (fluid-set! the-last-stack (make-stack #t))
>               (apply throw args)))

Ok, this is helpful. I am starting to understand exactly what I need to
be doing. Unfortunately I am still unsuccesful:

>From perusal of throw.c, it seems that scm_internal_stack_catch is what I want
to call, as it sets scm_the_last_stack_fluid_var. However, using, the stack is
always #f at the point that I hit the error handler. So what am I doing wrong
in the code below?

--- snip ---

static SCM guile_safe_apply_handler(void *data, SCM tag, SCM throw_args) {
  SCM port = scm_def_errp;

  if(scm_ilength(throw_args) >= 3) {
    SCM stack = scm_fluid_ref(SCM_VARIABLE_REF(scm_the_last_stack_fluid_var));
    SCM subr = SCM_CAR(throw_args);
    SCM message = SCM_CADR(throw_args);
    SCM args = SCM_CADDR(throw_args);
    
    /* So far, I reach this point with non-user-throws exceptions (e.g.
	undefined variables). But stack is invariably #f. */

    scm_display_backtrace(stack, port, SCM_UNDEFINED, SCM_UNDEFINED);
    return SCM_BOOL_F;
  }

  else {
    /* I reach this point upon user-thrown exceptions. Why? */

    scm_puts("uncaught throw to ", port);
    scm_prin1(tag, port, 0);
  }

  return SCM_BOOL_T;
}

struct guile_body_apply_data {
  SCM proc;
  SCM args;
};

SCM guile_safe_apply_body(struct guile_body_apply_data* data) {
  return scm_apply_0(data->proc, data->args);
}

SCM guile_safe_apply(SCM proc, SCM args) {
  struct guile_body_apply_data data;

  data.proc = proc;
  data.args = args;

  return scm_internal_stack_catch(SCM_BOOL_T, (scm_t_catch_body)guile_safe_apply_body, (void*)&data, (scm_t_catch_handler)guile_safe_apply_handler, NULL);
}

--- snip ---

Is scm_apply_0 the wrong thing to call in the body?

Any further help would be appreciated.

Thanks,

-- 
William <wmorgan@masanjin.net>


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: wrong-type-arg in scm_display_backtrace
  2003-01-05  3:57   ` William Morgan
@ 2003-01-06 19:06     ` Neil Jerram
  2003-01-07  5:42       ` William Morgan
  0 siblings, 1 reply; 9+ messages in thread
From: Neil Jerram @ 2003-01-06 19:06 UTC (permalink / raw)
  Cc: guile-devel

>>>>> "William" == William Morgan <wmorgan@masanjin.net> writes:

    William> From perusal of throw.c, it seems that
    William> scm_internal_stack_catch is what I want to call, as it
    William> sets scm_the_last_stack_fluid_var. However, using, the
    William> stack is always #f at the point that I hit the error
    William> handler. So what am I doing wrong in the code below?

I don't know; it looks OK to me.  Perhaps you could try putting a
breakpoint on ss_handler, where the-last-stack is set, then (assuming
that setting makes it non-#f) step through from there to find out
where it gets reset.

What is your Guile version, BTW?

        Neil
 



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: wrong-type-arg in scm_display_backtrace
  2003-01-06 19:06     ` Neil Jerram
@ 2003-01-07  5:42       ` William Morgan
  2003-01-08 20:21         ` Neil Jerram
  0 siblings, 1 reply; 9+ messages in thread
From: William Morgan @ 2003-01-07  5:42 UTC (permalink / raw)


Excerpts (reformatted) from Neil Jerram's mail of  6 Jan 2003 (EST):
> I don't know; it looks OK to me.

Ok, it's good to know that I'm on the right track, at least.

> Perhaps you could try putting a breakpoint on ss_handler, where
> the-last-stack is set, then (assuming that setting makes it non-#f)
> step through from there to find out where it gets reset.

It seems as if scm_make_stack is always returning #f. In particular, the
code in throw.c :

static SCM
ss_handler (void *data SCM_UNUSED, SCM tag, SCM throw_args)
{
  /* Save the stack */
    scm_fluid_set_x (SCM_VARIABLE_REF (scm_the_last_stack_fluid_var),
                       scm_make_stack (SCM_BOOL_T, SCM_EOL));

always sets scm_the_last_stack_fluid_var to #f because of this. Why
would this be? I thought the whole point of lazy catches was to preserve
the call stack...

Anyways, I have looked at scm_make_stack briefly but haven't been able
to make head or tail of it yet.

> What is your Guile version, BTW?

I'm using 1.6.1. I have a small .c file that demonstrates this if you're
interested.

Thanks again for all of your help.

-- 
William <wmorgan@masanjin.net>


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: wrong-type-arg in scm_display_backtrace
  2003-01-07  5:42       ` William Morgan
@ 2003-01-08 20:21         ` Neil Jerram
  2003-01-08 22:38           ` William Morgan
  0 siblings, 1 reply; 9+ messages in thread
From: Neil Jerram @ 2003-01-08 20:21 UTC (permalink / raw)
  Cc: guile-devel

>>>>> "William" == William Morgan <wmorgan@masanjin.net> writes:

    William> It seems as if scm_make_stack is always returning #f. In
    William> particular, the code in throw.c :

Are you running with the debugging evaluator?

By default, the debugging evaluator is on when using Guile
interactively, and off when running a script.  To run a script in
debug mode, use `guile --debug'.

(Sorry, should have thought of this earlier?)

        Neil



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: wrong-type-arg in scm_display_backtrace
  2003-01-08 20:21         ` Neil Jerram
@ 2003-01-08 22:38           ` William Morgan
  2003-01-09 23:42             ` Neil Jerram
  0 siblings, 1 reply; 9+ messages in thread
From: William Morgan @ 2003-01-08 22:38 UTC (permalink / raw)


Excerpts (reformatted) from Neil Jerram's mail of  8 Jan 2003 (EST):
> Are you running with the debugging evaluator?

Ah hah! This was the key. In my invocation of scm_init_guile(), I write:

  scm_init_guile();
  SCM_DEVAL_P = 1;
  SCM_BACKTRACE_P = 1;
  SCM_RECORD_POSITIONS_P = 1;
  SCM_RESET_DEBUG_MODE;

and now I have backtraces. Yes!!! Now, I just have to figure out how to use
vports to steal the backtrace dump and put it somewhere intelligent...

Having finally succeeded, I have a couple comments:

1) The commands above are wicked voodoo that should be encapsulated in
   some kind of scm_enable_debugging() library call. There's no way I,
   as the application developer, should be playing with these variables
   directly.

2) This whole process has been unnecessarily difficult, considering that
   I am doing *only* and *exactly* what anyone who wants to embed Guile
   in their program must do (run Guile callbacks, catch errors, display
   errors nicely).

Issue #2, at least, is mostly a matter of lack of documentation. I
promise to write up a "how to embed Guile in your C program" document
and post it here.

Thank you, Neil, for all of your help.

-- 
William <wmorgan@masanjin.net>


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: wrong-type-arg in scm_display_backtrace
  2003-01-08 22:38           ` William Morgan
@ 2003-01-09 23:42             ` Neil Jerram
  2003-01-10 20:31               ` vports from c questions William Morgan
  0 siblings, 1 reply; 9+ messages in thread
From: Neil Jerram @ 2003-01-09 23:42 UTC (permalink / raw)
  Cc: guile-devel

>>>>> "William" == William Morgan <wmorgan@masanjin.net> writes:

    William> and now I have backtraces. Yes!!! Now, I just have to
    William> figure out how to use vports to steal the backtrace dump
    William> and put it somewhere intelligent...

Great!

    William> Having finally succeeded, I have a couple comments:

    William> 1) The commands above are wicked voodoo that should be
    William> encapsulated in some kind of scm_enable_debugging()
    William> library call. There's no way I, as the application
    William> developer, should be playing with these variables
    William> directly.

Agreed.  There is a Scheme `turn-on-debugging' proc in boot-9.scm, but
this is relatively hard to use from C.

    William> 2) This whole process has been unnecessarily difficult,
    William> considering that I am doing *only* and *exactly* what
    William> anyone who wants to embed Guile in their program must do
    William> (run Guile callbacks, catch errors, display errors
    William> nicely).

Yes, I'm afraid so.  But things are improving, and largely thanks to
positive experimentation and feedback like this.

    William> Issue #2, at least, is mostly a matter of lack of
    William> documentation. I promise to write up a "how to embed
    William> Guile in your C program" document and post it here.

Wonderful - I look forward to it!

        Neil



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

* vports from c questions
  2003-01-09 23:42             ` Neil Jerram
@ 2003-01-10 20:31               ` William Morgan
  0 siblings, 0 replies; 9+ messages in thread
From: William Morgan @ 2003-01-10 20:31 UTC (permalink / raw)


Dear Guile gurus,

I am now at the point in my application where I would like Guile to be
able to read from and write to a vport under my control. There is no
scm_c_make_soft_port, so what I'm doing is the following (for an
output-only port):

SCM vec = scm_c_make_vector(5, SCM_BOOL_F);
scm_vector_set_x(vec, scm_int2num(0), scm_c_make_gsubr("write a char",
		 1, 0, 0, (SCM (*)())handle_write_char);
scm_vector_set_x(vec, scm_int2num(1), scm_c_make_gsubr("write a string",
		 1, 0, 0, (SCM (*)())handle_write_string);
 
However, in the case of multiple vports, each of which references
my handle_write_char and handle_write_string functions, these two
functions have no way of telling which port is calling them, and thus
where in my application to send the output.

Questions:

1) Is there a nice way of specifying some kind of closure, from the C
   side, such that I can provide additional arguments to my
   handle_write_* functions? (I can think of two ways, one involving a
   scm_eval_string("(lambda (char) (...") in the above code, and one one
   involving a table of function pointers---but neither of these seems
   pretty.)

2) If not #1, do people see this as an API issue?

3) If #2, any suggestions on what you'd like the API to be if I were to
   submit a patch?

Thank you,

-- 
William <wmorgan@masanjin.net>


_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2003-01-10 20:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-30  1:31 wrong-type-arg in scm_display_backtrace William Morgan
2002-12-31 23:42 ` Neil Jerram
2003-01-05  3:57   ` William Morgan
2003-01-06 19:06     ` Neil Jerram
2003-01-07  5:42       ` William Morgan
2003-01-08 20:21         ` Neil Jerram
2003-01-08 22:38           ` William Morgan
2003-01-09 23:42             ` Neil Jerram
2003-01-10 20:31               ` vports from c questions William Morgan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).