Beefy Boxes and Bandwidth Generously Provided by pair Networks vroom
go ahead... be a heretic

Debugging XS modules under Strawberry perl

by salva (Monsignor)
on Sep 06, 2013 at 12:58 UTC ( #1052707=perlquestion: print w/ replies, xml ) Need Help??
salva has asked for the wisdom of the Perl Monks concerning the following question:

The title says mostly all.

I have a XS module (Math::Int128) which I want to debug on Windows using some C debugger.

I have installed the latest Strawberry perl (5.18.1 for x64) and the gdb binary from here (syphilis, thanks for the pointer) and compiled the module with OPTIMIZE="-g -O2".


I am not able to set breakpoints on functions inside perl.exe either. I know, the executable is compiled without debugging information but on Unix, gdb would be able to set a breakpoint at the function anyway.


Comment on Debugging XS modules under Strawberry perl
Select or Download Code
Re: Debugging XS modules under Strawberry perl
by BrowserUk (Pope) on Sep 06, 2013 at 13:17 UTC


    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks, that was enough to get near the place where the error was happening and from there trace the program with WinDbg.

      The actual problem is that gcc generates MOVDQA (Move Aligned Double Quadword) instructions to load the int128 integers from memory to the mmx registers, and those require 16-byte alignment for their memory arguments. Perl own malloc implementation only guarantees 8-byte alignment on Windows, so eventually, the module crashes.

        Maybe this will help, its only for VC, maybe Mingw implemented it to the GCC equivalent. . You can create aligned Perl memory with sv_chop and initially allocating extra bytes that may or may not get used, but the used portion of the memory block may get moved forward depending on the claimed start of the memory block from Newx/Perl mem allocator. Here is some private code that shows an example of aligning with sv_chop. It allows kernel DMA writes directly into SV which have huge alignment requirements (512, etc). The code also allows alignment to non-powers of 2 for completeness.
        void ReadFileEx(self, hFile, opBuffer, uBytes, uqwOffset, uAlign=0) HV * self HANDLE hFile SV * opBuffer unsigned long uBytes unsigned __int64 uqwOffset unsigned long uAlign ..................................................... PREINIT: char * opBufferPtr; BOOL ret; unsigned long alignRemainder; ................................................ CODE: ................................................ //idea is to avoid a sv_grow and a sv_chop if current SvPVX meets +alignment and len requirements //SvPVX may already be aligned from a previous ReadFileEx if( SvTYPE(opBuffer) < SVt_PV) { goto grow;} // +svpvx cant be used unless sv type >= pv else if( ! (opBufferPtr = SvPVX(opBuffer))){ goto growPV;} else if(uAlign){ alignRemainder = (DWORD_PTR)opBufferPtr % uAlign; //opBufferP +tr and uAlign can't be 0 here //test uBytes+offset to align multiple for current PVX, uBytes ++uAlign only needed for a re/malloc op //since the alignment of the returned alloc block is assumed t +o be 0 thru uAlign if(alignRemainder && ! (SvLEN(opBuffer) > uBytes + (uAlign-ali +gnRemainder))){ goto growPV; } // PVX is already aligned, check alloc len else { goto testLen;} } testLen: if(SvLEN(opBuffer) <= uBytes) { goto growPV;} if(0){ growPV: //only if PV, access vio, prevent needless copy in sv_ +grow SvCUR(opBuffer) = 0; grow: //always include full alignment here, we can't predict a +lignment of realloced ptr opBufferPtr = sv_grow(opBuffer, uBytes+1+uAlign); } //offset to next align bouindary must be recacled, opBufferPtr m +ay have changed from 1st align calc if(uAlign && (alignRemainder = (DWORD_PTR)opBufferPtr % uAlign)) { char * newptr = opBufferPtr = opBufferPtr+(uAlign-alignRemaind +er); //any alignment, any odd number, any even number, any number, +not just power of 2, rope to hang yourself //(alignRemainder && 1) is a cancel part, so ptr 26 on align 1 +3 doesn't become 39 (26+13) needlessly assert(newptr + uBytes < SvPVX(opBuffer) + SvLEN(opBuffer)); SvPOK_on(opBuffer); sv_chop(opBuffer,newptr); //there is an assumption that sv_cho +p will not realloc since PVX is long enough assert(opBufferPtr == SvPVX(opBuffer)); } assert(uAlign?((DWORD_PTR)SvPVX(opBuffer) % uAlign == 0) :1); ......................................................
        Some code was removed, regarding sanity checks on whether the SV opBuffer is safe to use or not and all mentions of self object removed.

        Here is a 2nd usage of Perl and aligned memory I use,

        TLDR: Use Visual C or Intel C

        Although this isn't an answer to your problem. I hate Mingw64/Org/GCC, usually for its debugging abilities. Windows uses pdb symbol files, they work, forwards and back. VC 2008 with VS 2003 GUI. VC 2003 with VS 6 GUI. VC 2003 with VS 2008 GUI. ICC with VS 2008 GUI. It is a wonderful life. With GCC family, symbols are in the binaries, now you have to hack Makefile.PL and MakeMaker and provide those MY:: method overrides to keep the symbols in the binaries. Next problem is the gdb binaries having poor to no binary compatibility forwards or back or w64 vs org vs cygwin. If every binary with GCC symbols, wasnt made by the exact gcc binary that came in the archive/tarball that the gdb binary you are using came with, expect the gdb process to freeze (Task Man kill time), throw errors/not set breakpoints, cant find the original source code, take really long timeouts on the order of dozens of seconds with no CPU usage in the debugger and the debugee. If you are using a win32 GUI for gdb, expect more freezes or timeouts than in the gdb prompt (I've tried 2 different ones). Even if the latest GCCs from the 3 GCC on Win32 families generate cross compatible symbols now (and IDK if they do). It doesn't fix the 10 years of older Win32 GCCs out in the field and their binaries symbol formats. I think there is a principle in the GCC world, that different GCC builds dont need to be binary compatible, since each OS is compiled with 1 C compiler, and all binaries on that OS were made with the same C compiler. Compiling your own GCC with different compile flags and replacing the system GCC, then asking why nothing works, is simply insane and "not supported". But that is what we have on Windows with 3 different GCC forks.

        Originally Strawberry used org. Then due to seeing the political problems that org was causing and the w64 project more progressive, Strawberry switch to w64. ActivePerl's GCC PPM package is still org 3.4.5 from 2005ish as of 2013. So still as of today Win32 Perl has 2 different GCCs in circulation with great animosity for each others developers. Cygwin GCC has always been Cygwin GCC. I dont think anyone is crazy enough to try to build XS modules using Cygwin GCC that will load into a native Perl process. Org was a fork of cygwin GCC from 1998. The frequency of code sharing of Cygwin GCC and Org and W64 I am not sure of. But I've had to create ifdefs for all 3 compilers due to header differences and different spec files compiled into each GCC fork.

        See also

        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Debugging XS modules under Strawberry perl
by syphilis (Canon) on Sep 06, 2013 at 13:34 UTC
    Another place you could seek assistance would be the Strawberry Perl mailing list.
    I don't think any of the Strawberry developers call in at the monastery on a regular basis.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1052707]
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
As of 2013-12-20 16:20 GMT
Find Nodes?
    Voting Booth?

    How do you parse XML?

    Results (429 votes), past polls