Re: Access violation in SV.C new_body_inline()

"Craig A. Berry" <[email protected]>
Newsgroups gmane.comp.lang.perl.ports.vms,gmane.comp.lang.perl.perl5.porters
Message-ID <[email protected]>
On Apr 27, 2009, at 8:40 AM, Nicholas Clark wrote:

> On Mon, Apr 27, 2009 at 12:27:02AM -0500, John E. Malmberg wrote:
>> I just started looking into a failure of 19_CPANPLUS-Dist.  I have  
>> not
>> determined what exactly is wrong, and am out of time for the moment.
>>
>> I will try to get some more information later.
>>
>> It is failing from an access violation in SV.C.
>>
>> ok 57 -    Perl version not high enough
>> %SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual
>> address=000000000000002C, PC=00000000000F9AB8, PS=0000001B
>> %TRACE-F-TRACEBACK, symbolic stack dump follows
>>  image    module    routine             line      rel PC
>> abs PC
>> DBGPERLSHR  SV  Perl_sv_upgrade        73671 0000000000001F58
>> 00000000000F9AB8
>> DBGPERLSHR  SV  Perl_sv_setsv_flags    76204 000000000000AC88
>> 00000000001027E8
>
>> EAGLE> search [-]sv.lis/window=10 73671
>>      2   73667         /* We always allocated the full length item
>> with PURIFY.
>> To do this
>>      2   73668            we fake things so that arena is false for
>> all 16 type
>> s..  */
>>      3   73669         if(new_type_details->arena) {
>>      3   73670             /* This points to the start of the
>> allocated area.
>> */
>>      3   73671             new_body_inline(new_body, new_type);
>
> #define new_body_inline(xpv, sv_type) \
>    STMT_START { \
> 	void ** const r3wt = &PL_body_roots[sv_type]; \
> 	xpv = (PTR_TBL_ENT_t*) (*((void **)(r3wt))      \
> 	  ? *((void **)(r3wt)) : more_bodies(sv_type)); \
> 	*(r3wt) = *(void**)(xpv); \
>    } STMT_END
>
> I'm curious what the value of sv_type is. It's the second (real)  
> parameter:
>
> void
> Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type)


For me the access violation does not happen when running under the  
debugger, where it would be easy to examine new_type.  Without running  
in debug, we see

ok 56 - Perl binary version too low
ok 57 -    Perl version not high enough
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual  
address=000000000000002C, PC=00000000000FA491, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image     module    routine               line      rel PC            
abs PC
DBGPERLSHR  SV  Perl_sv_upgrade          86326 0000000000004641  
00000000000FA491

etc., as John reported.  Note that a virtual address of 0x2c (decimal  
44) is not a possible address.


Whereas running under the debugger we get:

ok 55 - Rebuilding trees
not ok 56 - Perl binary version too low
#   Failed test 'Perl binary version too low'
#   at [-.lib.cpanplus.t]19_cpanplus-dist.t line 358.
#          got: '1'
#     expected: ''

line 358 is:

             is( !!$flag, !!$bool,   $txt );

not ok 57 -    Perl version not high enough
#   Failed test '   Perl version not high enough'
#   at [-.lib.cpanplus.t]19_cpanplus-dist.t line 232.
#                   ''
#     doesn't match '(?-xism:needs perl version)'
ok 58 - Rebuilding trees

line 232 is:

                 sub { like( CPANPLUS::Error->stack_as_string,
                             qr/needs perl version/,
                             "   Perl version not high enough" ) },

The debugger is likely to zero out uninitialized memory and do other  
things that might protect the stack from corruption, so that may be a  
partial explanation of the difference.  It does look as though the  
damage is being done at test 56 (or earlier) but doesn't show up until  
test 58 unless you are running under the debug environment.

The particular expansion of the new_body_inline macro where the crash  
occurs looks like:

      3   86326             new_body_inline(new_body, new_type);
        E              do { void * * const r3wt = & ( my_perl ->  
Ibody_roots ) [ new_type ] ; new_body = ( PTR_TBL_ENT_t * ) ( * ( (
        E        void * * ) ( r3wt ) ) ? * ( ( void * * ) ( r3wt ) ) :  
S_more_bodies ( my_perl , new_type ) ) ; * ( r3wt ) = * ( void
        E         * * ) ( new_body ) ; } while ( 0 )


That's all the debugging time I have for now.

________________________________________
Craig A. Berry
mailto:[email protected]

"... getting out of a sonnet is much more
  difficult than getting in."
                  Brad Leithauser
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.