Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Debugging XS modules under Strawberry perl

by salva (Abbot)
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".

With gdb running under Linux/Unix, I could set a breakpoint for a function on a DLL and gdb would set it once the library is loaded but that doesn't seem to work on Windows.

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.

Currently, I am in the process of recompiling Strawberry perl with debugging enabled, but in the meantime, I would really appreciate if somebody could give me some practical advice on the matter.

Replies are listed 'Best First'.
Re: Debugging XS modules under Strawberry perl
by BrowserUk (Pope) on Sep 06, 2013 at 13:17 UTC

    I'd suggest you consider employing DebugBreak() call in the function(s) you want to debug.

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    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

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Debugging XS modules under Strawberry perl
by syphilis (Chancellor) 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?
Others examining the Monastery: (3)
As of 2018-08-14 06:42 GMT
Find Nodes?
    Voting Booth?
    Asked to put a square peg in a round hole, I would:

    Results (144 votes). Check out past polls.