Compilation with gcc 4.6.0

Julien ÉLIE julien at
Sun Jun 12 21:57:03 UTC 2011

Hi Russ,

>>>>     for (c = *p; (q = *list) != NULL; list++)
>>>       for (i = 0; list[i] != NULL; i++)
>>>           if (strcasecmp(p, list[i]) == 0)
> I'm not following.  list is just an array of strings.  Previously, we
> traversed the array via incrementing a pointer; in the new version, we
> traverse the array using an explicit offset.

I thought that in the first version, we would only have one incrementation
(list++) and an assignment (q).  Therefore, we read the list sequentially,
traversing it.
Whereas in the new version, we would have an incrementation (i++) and
a traversal at each iteration (list[i]).

> But either way, the
> generated assembly code should amount to functionally the same thing

Yes, you're right.  I was a bit too naive when I thought that list[n]
would lead to code that parsed list[0], list[1], list[2], etc.
up to list[n].
The assembly code should directly use the address n*(size of a pointer)
after list[0].  So, OK, it is equivalent.

> I suspect there are latent stack handling bugs in PERLfilter should the
> stack ever end up getting reallocated.  There is a lot of code like:
>      if (perl_get_cv("filter_before_reload", false) != NULL)    {
>          perl_call_argv("filter_before_reload", G_EVAL|G_DISCARD|G_NOARGS, argv);
>          if (SvTRUE(ERRSV))     /* check $@ */ {
>              syslog (L_ERROR,"SERVER perl function filter_before_reload died: %s",
>                      SvPV(ERRSV, PL_na)) ;
>              (void)POPs ;
>              PerlFilter (false) ;
>          }
>      }
> in that function that I think, according to perlcall, should be surrounded
> in similar macro calls.

Normally, as G_DISCARD is specified, no need to use macro calls :-)
Nonetheless, I admit I am still not reassured…
(There is a POPs afterwards.)

> I'm not sure about the perl_eval_pv() calls,
> although I suspect they may do the same thing.

Hmm…  I will try to have a look.  Adding a mere SPAGAIN between the previous
perl_call_arg() and this perl_eval_pv() does not work:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1220905280 (LWP 20853)]
0x082bcb26 in ?? ()
(gdb) bt
#0  0x082bcb26 in ?? ()
#1  0xb76d8019 in Perl_runops_standard () from /usr/lib/
#2  0xb7679b6e in Perl_magicname () from /usr/lib/
#3  0xb7679e4b in Perl_eval_sv () from /usr/lib/
#4  0xb767a146 in Perl_eval_pv () from /usr/lib/
#5  0x0809f880 in PERLreadfilter (filterfile=0x82baa28 "/home/news/bin/filter/", function=0x80a2708 "filter_art")
    at perl.c:202
#6  0x08059333 in CCreload (av=0xbfa5e200) at cc.c:1406
#7  0x08058891 in CCreader (cp=0xb70506d8) at cc.c:1879
#8  0x0805cc7a in CHANreadloop () at chan.c:1216
#9  0x0805f88f in main (ac=135349642, av=0x8114a48) at innd.c:736

Maybe everything should be separated and use FREETMPS;LEAVE; when finished.
That does not seem a satisfying solution :-/

The perlcall documentation is not clear enough, and even confusing.
For instance:

  The PUSHMARK macro tells Perl to make a mental note of the current
  stack pointer.  Even if you aren't passing any parameters (like the
  example shown in the section No Parameters, Nothing Returned)
  you must still call the PUSHMARK macro before you can call any
  of the call_* functions -- Perl still needs to know that there
  are no parameters.

and afterwards:

  static void
        call_argv("PrintList", G_DISCARD, words);
  Note that it is not necessary to call PUSHMARK in this instance.
  This is because call_argv will do it for you.

It is confusing…

> There are deeper problems with all that code, though, namely that it uses
> a rather awkward way to load code, and the way it runs the filter code is
> even worse.  Once upon a time, I had started figuring out what the "right"
> way to do this probably would be, and then never finished.  :/ PerlSilence
> is weird and needs a better solution,

Oh, yes.

> I think there were native
> functions that did what we're doing with perl_eval_pv() to load Perl code
> from a file.

I did not find it in perlembed, which says "Perl provides two API functions
to evaluate pieces of Perl code.  These are eval_sv in perlapi and eval_pv
in perlapi.  Arguably, these are the only routines you'll ever need to execute
snippets of Perl code from within your C program.  Your code can be as long as
you wish; it can contain multiple statements; it can employ use, require,
and do to include external Perl files."
Too bad they do not mention the other better routines :-/

The right use of stacks and functions is still obscure, even after reading
perlcall and perlembed.  It looks as though reading the source code of these
Perl functions would explain more things about how to use them!

Julien ÉLIE

« Le vrai danger, ce n'est pas quand les ordinateurs penseront comme
  les hommes, c'est quand les hommes penseront comme les
  ordinateurs. »

More information about the inn-workers mailing list