develooper Front page | perl.perl5.porters | Postings from April 2008

Re: [perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)

Thread Previous | Thread Next
From:
Rafael Garcia-Suarez
Date:
April 27, 2008 14:38
Subject:
Re: [perl #51370] Clearing magic (was: [#perl 51370] length($@)>0 for empty $@ if utf8 is in use)
Message ID:
b77c1dce0804271438r39964095mfcc5c196d31b9cae@mail.gmail.com
2008/4/26 Animator via RT <perlbug-followup@perl.org>:
>  I took a look at this bug-report and the magic assoicated with $@ does
>  not get cleared.
>
>  I did some testing on how to turn it off but I'm not sure what 'the
>  correct way' is. (Therefor there is no patch)
>  Can someone offer some guidance?
>
>
>  The test case:
>
>  #!/usr/bin/perl -l
>
>  use utf8;
>  use Devel::Peek
>  eval { 1 };
>  Dump($@);
>  eval { die "\x{a10d}"};
>  $_ = length $@;
>  eval { 1 };
>  Dump($@);
>
>
>  The current output (on blead):
>
>  SV = PV(0x8130f04) at 0x812ffd8
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   PV = 0x813d8d0 ""\0
>   CUR = 0
>   LEN = 240
>  SV = PVMG(0x813d390) at 0x812ffd8
>   REFCNT = 1
>   FLAGS = (SMG,POK,pPOK,UTF8)
>   IV = 0
>   NV = 0
>   PV = 0x813d8d0 ""\0 [UTF8 ""]
>   CUR = 0
>   LEN = 240
>   MAGIC = 0x8145e38
>     MG_VIRTUAL = &PL_vtbl_utf8
>     MG_TYPE = PERL_MAGIC_utf8(w)
>     MG_LEN = 23
>
>  Which shows that the flags SMG and UTF8 are (still) set and the
>  IV,NV,MAGIC is also set.
>
>
>
>  In pp_ctl.c, Perl_create_eval_scope I modified this code:
>
>     if (flags & G_KEEPERR)
>         PL_in_eval |= EVAL_KEEPERR;
>     else
>         sv_setpvn_mg(ERRSV,"",0);
>
>  Into:
>
>     if (flags & G_KEEPERR)
>         PL_in_eval |= EVAL_KEEPERR;
>     else {
>         sv_setpvn_mg(ERRSV,"",0);
>     }

The first one should be sv_setpvn actually.

>  Which turned the output into:
>
>  SV = PV(0x814e3a8) at 0x81504f8
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   PV = 0x815cbc0 ""\0
>   CUR = 0
>   LEN = 240
>  SV = PVMG(0x815c870) at 0x81504d8
>   REFCNT = 1
>   FLAGS = (SMG,POK,pPOK,UTF8)
>   IV = 0
>   NV = 0
>   PV = 0x815cba0 ""\0 [UTF8 ""]
>   CUR = 0
>   LEN = 240
>   MAGIC = 0x8167638
>     MG_VIRTUAL = &PL_vtbl_utf8
>     MG_TYPE = PERL_MAGIC_utf8(w)
>     MG_LEN = -1
>
>
>  Which makes the length 0 but it stil lhas all the extra flags attached
>  to it.
>
>
>  Next: I changed it into
>
>     if (flags & G_KEEPERR)
>         PL_in_eval |= EVAL_KEEPERR;
>     else {
>         sv_setpvn_mg(ERRSV,"",0);
>         if (SvMAGICAL(ERRSV)) {
>             mg_clear(ERRSV);
>         }
>     }
>
>  Output:
>
>  SV = PV(0x814e3a8) at 0x81504f8
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   PV = 0x815cbc0 ""\0
>   CUR = 0
>   LEN = 240
>  SV = PVMG(0x815c890) at 0x81504f8
>   REFCNT = 1
>   FLAGS = (SMG,POK,pPOK,UTF8)
>   IV = 0
>   NV = 0
>   PV = 0x815cbc0 ""\0 [UTF8 ""]
>   CUR = 0
>   LEN = 240
>   MAGIC = 0x8167658
>     MG_VIRTUAL = &PL_vtbl_utf8
>     MG_TYPE = PERL_MAGIC_utf8(w)
>     MG_LEN = -1
>
>
>  Which is the same as the previous output.
>
>
>
>  Next:
>
>     if (flags & G_KEEPERR)
>         PL_in_eval |= EVAL_KEEPERR;
>     else {
>         sv_setpvn_mg(ERRSV,"",0);
>         if (SvMAGICAL(ERRSV)) {
>             mg_free(ERRSV);
>         }
>     }
>
>  Output:
>
>  SV = PV(0x814e3a8) at 0x81504f8
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   PV = 0x815cbc0 ""\0
>   CUR = 0
>   LEN = 240
>  SV = PVMG(0x815c890) at 0x81504f8
>   REFCNT = 1
>   FLAGS = (SMG,POK,pPOK,UTF8)
>   IV = 0
>   NV = 0
>   PV = 0x815cbc0 ""\0 [UTF8 ""]
>   CUR = 0
>   LEN = 240
>
>
>  Now the MAGIC is gone, but the UTF8 and the flags are still set.
>
>
>
>  Next:
>
>     if (flags & G_KEEPERR)
>         PL_in_eval |= EVAL_KEEPERR;
>     else {
>         sv_setpvn_mg(ERRSV,"",0);
>         if (SvMAGICAL(ERRSV)) {
>             mg_free(ERRSV);
>         }
>         SvPOK_only(ERRSV);
>     }
>
>  Output:
>
>  SV = PV(0x814e3c8) at 0x8150518
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   PV = 0x815cbe0 ""\0
>   CUR = 0
>   LEN = 240
>  SV = PVMG(0x815c8b0) at 0x8150518
>   REFCNT = 1
>   FLAGS = (SMG,POK,pPOK)
>   IV = 0
>   NV = 0
>   PV = 0x815cbe0 ""\0
>   CUR = 0
>   LEN = 240
>
>
>  Now the MAGIC and the UTF8 are gone but the SMG flag is still there.
>
>
>
>  Next:
>
>     if (flags & G_KEEPERR)
>         PL_in_eval |= EVAL_KEEPERR;
>     else {
>         sv_setpvn_mg(ERRSV,"",0);
>         if (SvMAGICAL(ERRSV)) {
>             mg_free(ERRSV);
>             mg_clear(ERRSV);
>         }
>         SvPOK_only(ERRSV);
>     }
>
>
>  Output:
>
>  SV = PV(0x814e3e8) at 0x8150538
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   PV = 0x815cc00 ""\0
>   CUR = 0
>   LEN = 240
>  SV = PVMG(0x815c8d0) at 0x8150538
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   IV = 0
>   NV = 0
>   PV = 0x815cc00 ""\0
>   CUR = 0
>   LEN = 240
>
>  The MAGIC is gone, the UTF8 is gone, the SMG flag is gone.
>
>
>  Next: (back to sv_setpvn instead of sv_setpvn_mg)
>
>     if (flags & G_KEEPERR)
>         PL_in_eval |= EVAL_KEEPERR;
>     else {
>         sv_setpvn(ERRSV,"",0);
>         if (SvMAGICAL(ERRSV)) {
>             mg_free(ERRSV);
>             mg_clear(ERRSV);
>         }
>         SvPOK_only(ERRSV);
>     }
>
>
>  Output:
>
>  SV = PV(0x814e3e8) at 0x8150538
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   PV = 0x815cc00 ""\0
>   CUR = 0
>   LEN = 240
>  SV = PVMG(0x815c8d0) at 0x8150538
>   REFCNT = 1
>   FLAGS = (POK,pPOK)
>   IV = 0
>   NV = 0
>   PV = 0x815cc00 ""\0
>   CUR = 0
>   LEN = 240
>
>
>  So, is this the correct way?

Might be correct. Do all tests pass including the new ones you'll
probably have written for this bug ? :)
However there might be a more concise way to achieve more or less the
same thing, maybe along the macro SvPVbyte_force or another similar one
(sorry, I always have to check the code when I dabble in the SV
internals, this is not the part of the core I know the most.)

>  And: should this be changed in every place where sv_setpvn(ERRSV,"",0)
>  is used?

Probably, yes.

>  grep -r 'sv_setpvn(ERRSV,"",0);' * # shows that it is used in 9 other
>  places
>
>
>  And: if it has to change everywhere then what would the best approach
>  be?
>  Placing it in a separate function? (If so, in what file, what
>  name, ...)
>
>
>  (If I know the correct way I'll create a patch with a test case for it)

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About