Search code examples
ibm-midrangerpgle

Debugger API - Submit Debug Command (QteSubmitDebugCommand) API


Just to clarify, I'm on V7R3M0.

I'm trying to call the Submit Debug Command (QteSubmitDebugCommand) API but not getting back the results I expect or I don't correctly understand the results. I'm trying to follow the example for a BREAK statement (near the bottom of the page in the manual). I'm expecting similar results to what are shown but I'm not getting the same results.

My prototype is:

dcl-pr QteSubmitDebugCommand extproc(*dclcase);
  rcvrDta char(128);                          
  rcvrSiz int(10) const;                      
  viewID int(10) const;                       
  InputBuffer char(64) const;                 
  InpBfrSiz int(10) const;                    
  CompilerID char(20) const;                  
  apiError like(apiErrDs);                    
end-pr;                                       

The definitions of the variables are:

  dcl-pi *n ;
    pViewID int(10) const;
    pDebugCommand varchar(64) const options(*trim);  // This is BREAK 10 WHEN IDX > 2
    pCompilerID char(20) const;   // which is valid in the test harness program
  end-pi;

  dcl-s receiverVariable char(128);
  dcl-s i uns(5);

  dcl-ds apiErrDs likeDs(apiErrDsTmp) inz;

  dcl-ds resultEntryTmp template qualified;
    resultType uns(10);
    count uns(10);
    length uns(10);
  end-ds;

  dcl-s receiverPtr pointer;
  dcl-ds receiverData qualified based(receiverPtr);
    bytesReturned int(10);
    bytesAvailable int(10);
    entries int(10);
    resultArray dim(4) likeds(resultEntryTmp);
    stringSpace char(256);
  end-ds;

And I call the API with:

QteSubmitDebugCommand(receiverVariable :%Len(receiverVariable) :pViewID 
                      :pDebugCommand :%Len(pDebugCommand) :pCompilerID :apiErrDS);

  receiverPtr = %addr(receiverVariable);

At this point I dump the program to check the results.

What I see in the dump is:

RECEIVERDATA          DS
   BYTESAVAILABLE      INT(10)              57               '00000039'X
   BYTESRETURNED       INT(10)              57               '00000039'X
   ENTRIES             INT(10)              3                '00000003'X
   RESULTARRAY         DS                   DIM(4)
     (1)
       COUNT           UNS(10)              3                '00000003'X
       LENGTH          UNS(10)              0                '00000000'X
       RESULTTYPE      UNS(10)              33554432         '02000000'X
     (2)
       COUNT           UNS(10)              10               '0000000A'X
       LENGTH          UNS(10)              0                '00000000'X
       RESULTTYPE      UNS(10)              83886080         '05000000'X
     (3)
       COUNT           UNS(10)              10               '0000000A'X
       LENGTH          UNS(10)              0                '00000000'X
       RESULTTYPE      UNS(10)              83886080         '05000000'X
     (4)
       COUNT           UNS(10)              1849750016       '6E40F200'X
       LENGTH          UNS(10)              4210752          '00404040'X
       RESULTTYPE      UNS(10)              3385124672       'C9C4E740'X

STRINGSPACE is not shown but it does look correct

According to the manual is should be getting back:

Receiver Variable
Offset       Field                    Value
0            Bytes returned           59
             Bytes available          59
             Entry count              3

12           Result type              BreakR(2)
             Break results count      3
             Reserved

24           Result type              BreakPositionR(5)
             Line number              7 (in my case this = 10)
             Reserved

36           Result type              ExpressionTextR(7)
             Expression text offset   48
             Expression text length   10

48           String space    result > 5

So it looks like the Header record (Offset 0) is correct.

The resultArray(1) looks correct as the Hex value of the RESULTTYPE is '02000000'X which I think is the BreakR. But I was expecting the value in the dump to be 2 not 33554432. Can someone tell me why this is? Am I doing something wrong or just misunderstanding how it's displayed.

The resultArray(2) looks correct as the Hex value of the RESULTTYPE is '05000000'X which I think is the BreakPositionR. Same question as to why I have to look at the Hex value.

The resultArray(3) looks incorrect as the Hex value of the RESULTTYPE is '05000000'X and the manual shows I should have been expecting a ExpressionTextR (7).

As for the String space I don't see anything resembling IDX > 2 which the manual shows I should be expecting.

Can anyone see what I'm doing wrong in my call or in the definition of the prototype.

Also, can someone explain why the resultarray.count looks like a normal int yet the resultarray.recordtype appears correct only in Hex. Should I be looking at the Hex value?

Any thoughts would be greatly appreciated.

Thanks,

Rob

Update: After Mark's reply I changed the procedure to follow Mark's suggestion and it worked correctly. Thanks, Mark.

Here is what I ended changing the code to...

  dcl-s receiverPtr pointer;
  dcl-ds receiverData qualified based(receiverPtr);
    bytesReturned int(10);
    bytesAvailable int(10);
    entries int(10);
  end-ds;

  dcl-s resultEntryPtr pointer;
  dcl-ds resultEntry qualified based(resultEntryPtr);
    type uns(10) pos(1);
    count uns(10) pos(5);
    offset uns(10) pos(5);
    length uns(10) pos(9);
  end-ds;
  dcl-s stringSpace char(256);


  QteSubmitDebugCommand(receiverVariable :%Len(receiverVariable) :pViewID :pDebugCommand :%Len(pDebugCommand)
                       :pCompilerID :apiErrDS);
    receiverPtr = %addr(receiverVariable);

    resultEntryPtr = %addr(receiverVariable);

    // We want to position the pointer to the last entry which contains
    // the offset and the length of the character string.
    resultEntryPtr += 12 * receiverData.entries;
    stringSpace = %subst(receiverVariable: resultEntry.offset: resultEntry.length);  

Solution

  • Not real sure about the format of the result array entries, but one thing about this API is that the result array is variable length, and the string entries immediately follow the returned result array. That means unless you get exactly 4 entries in the result array, you will not end up with the string space in the your string space variable. Notice that if you convert the hex codes in result array entry 4 x'C9C4E740 6E40F200 00404040' you have a null terminated EBCDIC string that says IDX > 2. This is right where it should be, immediately following the third result array entry (since the API told you that there were 3 entries returned). The API does not know the format of your RPG fields, you are really just providing a buffer which you must interpret.

    I usually use a based variable to interpret things like variable length formats. So in this case I would define something like this:

    dcl-ds resultEntry        Qualified Based(pResultEntry);
      type                    Uns(10) Pos(1);
      count                   Uns(10) Pos(5);
      offset                  Uns(10) Pos(5);
      length                  Uns(10) Pos(9);
    end-ds;
    dcl-s pResultEntry        Pointer;
    

    Note resultEntry.count and resultEntry.offset overlay each other, but provide good names in the case that the entry is a type 3 entry with offset and length rather that a type 2 entry with just a count. You can define this differently, but the key is the Based keyword on the data structure declaration line.

    To process this you can do something like this:

    pResultEntry = %addr(ReceiverData);
    for ix = 1 to ReceiverData.entries;
      pResultEntry += 12;
      ProcessResultArrayEntry(resultEntry);
    endfor;
    

    But as I said before, I am not sure about what you are seeing in result array entry 3. It seems that it should be one of those 3 part entries with offset and length. You should be able to substring the text out of that using something like this:

    string = %subst(ReceiverData: resultEntry.offset: resultEntry.length);