Operating System - OpenVMS
1747990 Members
5174 Online
108756 Solutions
New Discussion

Re: Itanium migration issue with function

 
SOLVED
Go to solution
TresaH
Frequent Visitor

Itanium migration issue with function

Hi,

 

I am in the process of migrating our code base from Alpha to Itanium and I have a defined function not returning proper results on the Itanium.  This function works properly on the Alpha.

 

The alpha environment I am running this on is 

VMS version 7.3-1, Basic 1.5

I am porting to 

Itanium VMS version 8.3-1H1, Basic version 1.7

 

When the code executes it seems to have the proper value at the end of the function and when the system passes the parameter back the string is always empty.

The function is locally defined in the program executing it.

 

One thing I have noticed is debugger will not allow me to evaluate R1$, I receive the error "no access to address".

 

I set the R1$ to another local variable to examine the contents just before the parameter is passed back and the results are what I am expecting.

 

Any suggestions would be greatly appreciated.

9 REPLIES 9
Craig A Berry
Honored Contributor

Re: Itanium migration issue with function

What happens if you declare the return value of your function, i.e., instead of

 

DEF FNREAD$ ( STRING R1$ )

you had

 

DEF STRING FNREAD$ ( STRING R1$ )

TresaH
Frequent Visitor

Re: Itanium migration issue with function

I have tried that and I receive the same results.

I have also tried it as an external function with the same results.

abrsvc
Respected Contributor

Re: Itanium migration issue with function

I will admit that I have not used Basic in a while, but the following appears to be incorrect:

 

You are referencing REC$ within the function.  REC$ is the passes parameter and within the function itself, the variable that should be used is R1$.  Is the confusion due to a "local" variable within the function also called REC$ that is causing this problem?  I don't have the Basic compiler to confirm, but a crossreference listing should indicate whether or not REC$ is actually two separate memory locations.

 

Dan

John Gillings
Honored Contributor

Re: Itanium migration issue with function

TresaH,

 

    I'd try recoding the function as a procedure returning the value as the first parameter instead of as a function value, just to check that you can pass it back to the caller. Note that is exactly how the VAX procedure calling standard would have implemented the call, as only scalar types could be returned in registers.

 

    Next simplify the function, for example, try:

 

DEF FNREAD$ ( STRING R1$ )

  FNREAD$ = R1$

FNEND

 

which is probably simple enough to try to follow it in machine code to see how the routine thinks it's returning a value, and where the caller is looking for it. Some judicious debug watchpoints might help too.

 

I don't have a compiler to experiment with. In my experience, Basic has a nasty habit of performing numerous hidden data conversions, which sometimes cause values to change unexpectedly. They are usually "correct" from the compilers perspective, but unexpected by the programmer. You appear to be doing the right thing to minimises surprises, using specific data type suffixes everywhere.

  re: unable to examine a variable... are you compiling /DEBUG/NOOPTIMIZE?

A crucible of informative mistakes
Hein van den Heuvel
Honored Contributor

Re: Itanium migration issue with function

Hmmm,

Seems to work for me using  I64 BASIC V1.7-000

I changed the provide program (why a sill DOC file??? why not good old TXT !!!) to read:

1 !Call to Function      

   REC$ = "aaaaa.bbbbb;ccccc          "        

   option_piece$ = FNREAD$ ( REC$ )        

    PRINT option_piece$

:

Compile, link, run ... "bbbbb"

 

As pointed out, the function seems to freely use data scoped in 'main' and in the 'function'.

Specifically I don't like seeing REC$ used when R1$ is passed with the the value of REC$.. in the example.

Are you sure each call to FNREAD$ passes REC$. Maybe REC$ was empty on entry?? Check with debugger!

I am also not a fan of modifying my function argument.

I suppose that's legal, but why not grab a fresh intermediate variable?

 

The debugger also happily looked at the variables for me:

break at X$MAIN\X$MAIN\FNREAD$\%LINE 40X$MAIN\X$MAIN\FNREAD$\R1$:      "bbbbb"X$MAIN\X$MAIN\REC$:     "aaaaa.bbbbb;ccccc          "

 

So I suspect it is an interaction with variable declarations as main level.

As suggested, compil/list and specifically look for "Allocation information for DEF FNREAD$ "

And any and all variable used in that function.

 

Good luck!

Hein

 

 

 

 

 

 

 

TresaH
Frequent Visitor

Re: Itanium migration issue with function

I wanted to thank everyone for their help and suggestions.

 

I have found what is causing my error.  I don't know why and would love to get some help with why this is happening and how to resolve it.  

 

This is what I have found:

The call to FNREAD$ works correctly until I call CMS$SET_LIBRARY.  After the call then FNREAD$ no longer passes back the expected results.  It is always passing back an empty string. 

 

I get the same results whether I compile with nooptimize or optimize=level=4

 

I have created and attached a program that re-produces the error.  

 

Again, any suggestions would be great.

Tresa

 

Hein van den Heuvel
Honored Contributor
Solution

Re: Itanium migration issue with function

Now we're cooking with gas!
Ayup that reproduces, even without library present.
Surely a memory overwrite.
If you double the CMS LIB_DB structure in size, and/or move it away from the other variables then the program will work again.

Report with the reproducer to HP, and let them tell you want the new minimum size of LIB_DB should be.
CMS$SET_LIBRARY says it uses 57 longs, where you allocated 51.

This 'appears' to fix it:
MAP (X) LONG LIB_DB ( 50 ) ! Declaration of Library Data Block

This fixes better:
DIM LONG LIB_DB ( 99 ) ! Declaration of Library Data Block

This reports usage:
PRINT "******* ";option_piece$;" ******. LIB_DB(0)="; LIB_DB(0)

Cheers,
Hein

John Gillings
Honored Contributor

Re: Itanium migration issue with function

TresaH,

 

   That symptom suggests the CMS$SET_LIBRARY call is corrupting something.

 

I'd also recommend getting rid of the up reference to REC$ from inside FNREAD$. I still don't understand why its there, when the same record is passed in as R1$.

 

I'm a bit concerned that your argument list declaration for CMS$SET_LIBRARY is not strictly correct. You've said (LONG, STRING BY DESC). The first argument is really a 50 element array by reference. If Basic has interpreted your actual argument "LIB_DB(0)" as an expression, evaluated it to a stack temporary and passed the result by reference to CMS$SET_LIBRARY, then that might account for some stack corruption.

 

Try changing the declaration to

 

(LONG BY REF, STRING BY DESC),

 

[or even better whatever the syntax is for "50 element LONG array by reference"]

 

and calling as (LIB_DB ,cms_library)

 

It pays to be very precise when declaring argument lists. Depending on optimisation, some compilers might realise that the expression "LIB_DB(0)" could be satisfied by using the actual address of the array element, which would behave exactly as if the array were passed by reference. A different compiler which evalulates the expression to a temporary location would behave differently. That might explain why this code may have "worked" on Alpha but behaves differently on Itanium (do any of the subsequent CMS$ calls work on Itanium?)
A crucible of informative mistakes
TresaH
Frequent Visitor

Re: Itanium migration issue with function

Thanks Hein and John for all your help and suggestions!!

 

I have submitted this to HP to get the minimum size the the lib data block.

I also have updated the code and removed all references to REC$ in the function as John suggested.

 

Thanks again!!