Re: Access violation in SV.C new_body_inline()

"John E. Malmberg" <[email protected]>
Newsgroups gmane.comp.lang.perl.perl5.porters,gmane.comp.lang.perl.ports.vms
Message-ID <[email protected]>
Craig A. Berry wrote:
> 
> 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.

To catch the exception in the VMS debugger:

1. Use the Perl debugger to start the test.
2. After the Perl image has been activated, enter Control-Y, and then 
type DEBUG to bring up the VMS debugger.
3. In the VMS Debugger, set break/exception, and then type go.

I use the Perl debugger in forked mode for X11 and also the VMS debugger 
for X11 to keep the test I/O separate from the debugger IO.

-John
[email protected]
Personal Opinion Only
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.