Menu

#375 LZMA SDK on IBM i (OS/400)

open
nobody
None
5
2020-10-14
2020-10-13
No

Hi,

I am using LZMA SDK to compress/decompress data as a plugin for IBM MQ. I have tested it on AIX, HP-UX, IBM i (OS/400), Linux x86, x64, POWER & z/System, Solaris SPARC & x64 and Windows.

The decompress routine crashes on IBM i (OS/400).

The compression appears to work. Here is a code snippet of it:

int         res;
size_t      propsSize = LZMA_PROPS_SIZE;
CLzmaEncProps props;
ISzAlloc    my_g_Alloc = { SzAlloc, SzFree };
ISzAlloc    my_g_BigAlloc = { SzBigAlloc, SzBigFree };

LzmaEncProps_Init(&props);
props.level = 4;
props.dictSize = 65536;
props.lc = 3;
props.lp = 0;
props.pb = 2;
props.fb = 32;
props.numThreads = 1;

res = LzmaEncode(pTgt + LZMA_PROPS_SIZE,
                 targetLength,
                 pSrc,
                 sourceLength,
                 &props,
                 pTgt,       // out props
                 &propsSize, // out props size
                 0,
                 NULL,
                 &my_g_Alloc,
                 &my_g_BigAlloc);

And here is what I'm using to decompress it:

int         res;
ELzmaStatus status;
size_t      compressed_size = sourceLength - LZMA_PROPS_SIZE;
ISzAlloc    my_g_Alloc = { SzAlloc, SzFree };

res = LzmaDecode(pTgt,
                 targetLength,
                 pSrc + LZMA_PROPS_SIZE,
                 &compressed_size,
                 pSrc,               // props
                 LZMA_PROPS_SIZE,
                 LZMA_FINISH_ANY,
                 &status,
                 &my_g_Alloc);

I spent serveral days trying to figure this out but I'm stumped.

At first I thought it was CLzmaDec p in the LzmaDecode subroutine, so I change it to a pointer and allocate memory for it. But it didn't fix the issue of crashing. So, I put printfs everywhere and tracked it done to LZMA_DECODE_REAL subroutine. Specifically, it is in the define IF_BIT_0(prob) where ttt = *(prob); is used.

Note: It is on the first pass in LZMA_DECODE_REAL subroutine. Here is the output from the last 3 printfs before it crashes (p, probs & prob are outputted as a pointer i.e. %p):

LZMA_DECODE_REAL 1 p=SPP:0000 :0000 :0:0:1d : sizeof(CLzmaProb)=2
LZMA_DECODE_REAL 2 probs=SPP:0000 :0000 :0:1:1d : IsMatch=-256 : COMBINED_PS_STATE=0
LZMA_DECODE_REAL 3 prob=SPP:0000 :0000 :0:2:1d

Printf #1 is right before entering the do while loop (line # 238).
Printf #2 is right before setting prob (line # 245).
Printf #3 is right before IF_BIT_0(prob) (line # 247).

I expanded IF_BIT_0(prob) into its 4 parts and put printfs after each one.

The code crahed on ttt = *(p); aka ttt = *(prob); because printf # 4 was not executed because of the crash.

The only compile define that I am using is _7ZIP_ST but that define is not used by LzmaDec.c.

I thought maybe it was a Big Endian isue but the code runs fine on AIX and Solaris SPARC. The other odd thing I noticed when running it on AIX and Solaris SPARC, is that IsMatch is always -256.

Is there some other define I should be setting to get it to work on IBM i (OS/400)?

Regards,
Roger

Discussion

  • Igor Pavlov

    Igor Pavlov - 2020-10-14

    try to look sizeof(UInt32).
    it must be 4.

     
  • Igor Pavlov

    Igor Pavlov - 2020-10-14

    to debug the code, you can simplify situation.
    1) find the smallest file with failure.
    2) reduce the properties with props.lc = 0;
    3) call Lzma decoder in loop, where each itaration decompresses only one byte with LzmaDec_DecodeToDic().
    LzmaDec_Construct()
    LzmaDec_Allocate()
    LzmaDec_Init()
    LzmaDec_DecodeToDic()
    LzmaDec_DecodeToDic()
    LzmaDec_DecodeToDic()

    you can printf() partial or full state including probs array after each decoded byte to text file.
    Then compare text files for normal decoding and decoding with failure. That can show the exact step with difference.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.