guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: frames / stacks / source? was Re: coverage/profiling


From: Neil Jerram
Subject: Re: frames / stacks / source? was Re: coverage/profiling
Date: Tue, 09 Jan 2007 22:15:04 +0000
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Han-Wen Nienhuys <address@hidden> writes:

> Since noone responded, I decided to take a look myself.
> My overall idea was to do the following:
>
>  - at the top of deval(), find out current source file and line

OK, but with the code where you have it at the moment, you'll miss
tail-recursive calls.

>  - invoke some kind of callback that increments a counter for the
> source location
>
>  - produce pretty pretty coverage graphs with the contents of the hash
>
> The last two steps are trivial, but I'm getting lost with the first
> step.
>
> I tried to follow what happens when an error backtrace is generated.
> My try is below. Unfortunately, I can't find much documentation on how
> frames/stacks/etc. interact. Can anyone gently nudge me in the right
> direction?

Do you think you need to do this in C?  (You might do, for reasonable
performance - I genuinely don't know yet.)  The evaluator already has
hooks (see "Evaluator trap options" in the manual) that allow you to
call out to arbitrary Scheme code at the entry and exit of every
frame.

You could use these directly, or you could use/modify/tweak one of the
following three modules that provides a higher level abstraction on
top of these.

1. The (ice-9 debug) trace code.  This traces procedure calls, though,
   not source coverage.

2. statprof, as others have already mentioned.  This is statistical,
   though.

3. My guile-debugging stuff (which is now in Guile CVS, if that's what
   you're using).

guile-debugging should be able to accumulate coverage of all source
expressions - say in a particular file - but it might incur a big
performance cost in so doing.  I'll try this out and let you know what
I find.

> +#ifdef DEVAL
> +  if (scm_do_profiling)
> +    {
> +      struct scm_t_info_frame info_frame;
> +      SCM source;
> +      SCM file;
> +      SCM line;
> +    
> +      read_frame (&debug, 0, &info_frame);
> +
> +      source = info_frame.source;
> +      file = SCM_MEMOIZEDP (source) ? scm_source_property (source, 
> scm_sym_filename) : SCM_BOOL_F;
> +      line = (SCM_MEMOIZEDP (source)) ? scm_source_property (source, 
> scm_sym_line) : SCM_BOOL_F;

Why SCM_MEMOIZEDP?  I believe non-memoized expressions have source
properties too.

> +
> +      if (scm_is_true (line)
> +         && scm_is_true (file))
> +       {
> +         printf ("%s %d - size %ld\n", scm_i_string_chars (file), scm_to_int 
> (line), scm_debug_eframe
> _size);

That looks OK, although I'm not sure what the point of printing
scm_debug_eframe_size is.

> +       }
> +      else
> +       {
> +         scm_display (source, scm_current_output_port ());
> +         scm_puts ("\n", scm_current_output_port ());
> +       }
> +    }
> +#endif

So what do you find happens with this code?

Regards,
     Neil





reply via email to

[Prev in Thread] Current Thread [Next in Thread]