Operating System - OpenVMS
cancel
Showing results for 
Search instead for 
Did you mean: 

sys$qio - how to get more info on a status 12

Anthony Magana
Occasional Advisor

sys$qio - how to get more info on a status 12

My application is executing a call to sys$qiow and is getting a status 12 returned. Status 12 basically translates to accvio. Frustrating thing is that this does not give me much information to go on diagnose and fix the problem. Through a process of elimination I found that there is something the qio call
doesn't like about the iosb that is passed in to it.

ret = SYS$QIOW(128, channel,
(unsigned longword)IO$_READVBLK|IO$M_NOVCACHE,
&siosb,
0,
0,
(void*)bufp, buflen,
offset
0,0,0);


A few relevant facts:

- The memory for the iosb is part of a larger memory allocation that is done with a call to mmap.

- After the failure, I confirm that the address
is indeed valid and accessible in the debugger.

- if I declare iosb as a local var or get the
memory for it through malloc, that status 12
does not occur.

- It usually has an address in the range 000000008xxxxxxx.

- The application is a 64 bit app.

- The first thing I thought was that perhaps qio doesn't like 64 bit addresses but then looking back at the system service documentation, its clearly stated that qio accepts 64 bit addresses.

- The other thing I thought was that maybe qio is doing an inappropriate sign extend on the iosb address. Have no way to determine that
though.

- Finally, the last possibility I could think of is that there is some characteristic of the mmap allocated memory that it doesn't like.


My main question is whether there is a way, via the debugger, or some other diagnostic tool to get more detailed info on the status 12 akin to what one would get when your app stack dumps, i.e. reason mask, virtual address, PC, PSL. Any insights, suggestions
on this problem would be appreciated. Thanks.
8 REPLIES
Volker Halle
Honored Contributor

Re: sys$qio - how to get more info on a status 12

Anthony,

assuming your 'elimination process' has lead to the underlying problem, please consider this:

The IOSB needs to be readable AND writeable from the caller's mode. If you run your program with the debugger and set a breakpoint before executing the QIOW, you have the IOSB address and could use SDA to look at the protection of the page:

$ ANAL/SYS
SDA> SET PROC/IND=
SDA> SHOW PROC/PAGE

Look at the Read Writ page protection codes.
Your IOSB seems to be in P2 space.

The ACCVIO happens in KERNEL mode when executing the SYS$QIOW code and the exception is being handled internally and returned as a system service failure code.

If the address would be incorrectly sign-extended, that would explain everything, as it would then become a S0 address, which would typically not be accessible (at least NOT writeable) from user mode.

Volker.
Antoniov.
Honored Contributor

Re: sys$qio - how to get more info on a status 12

Anthony,
Welcome to VMS forum :-)

I'm with Volker. Because using local iosb your program works fine, it appears like a iosb supplied is not writable by QIO service. If you have dubt about pointer addressing you can compile with /POINTER=32 qualifier, just for checking.

Antonio Vigliotti

Antonio Maria Vigliotti
Anthony Magana
Occasional Advisor

Re: sys$qio - how to get more info on a status 12

Volker,

Thanks for the suggestion on sda. Tried this
out, examining the associated memory for
both the buffer and for iosb. As near as I
can tell they look OK. Heres the output:

in debugger:
DBG> ex/hex bufp
SKGFR\skgfdisp\bufp: 0FFFFFEF903A94000

DBG> eval/addr/hex siosb
0000000080115E68


sho proc/pag 0FFFFFEF903A94000

P2 space
--------
Mapped Address FFFFFEF9.03A94000
PTE Address FFFFFEFD.BE40EA50
PTE 00014416.1016FF09
Type VALID
Read KESU
Writ KESU
MLOA M-U-
GH 0
PgTyp GBLWRT
Loc ACTIVE
Bak 000402AB.00010000
RefCnt 0001
Flink 00000001
Blink 00000000

sho proc/pag 0000000080115E68

P2 space
--------
Mapped Address 00000000.80114000
PTE Address FFFFFEFC.00200450
PTE 0006C29D.0016FF09
Type VALID
Read KESU
Writ KESU
MLOA M-U-
GH 0
PgTyp PROCESS
Loc ACTIVE
Bak FF000000.00000000
RefCnt 0001
Flink 00000001
Blink 000013B3

From my reading of the sda output this says that the page is readable and writeable in kernel, exec, supervisor, and user mode so it would appear everything is just fine.
Roger Tucker
Occasional Advisor

Re: sys$qio - how to get more info on a status 12

I know your just trying to figure out the original iosb problem, and there have been good suggestions about how to find it, but since the QIOW is synchronous, there may not be a need for the iosb to be in a memory mapped file. I would just create the iosb on the stack, like struct _iosb siosb; if itâ s not needed and make the program simpler. Also, the 128 event flag (used for No Event Flag) is also in efndef.h under the value EFN$C_ENF symbol. Is the application compiled /POINTER=64? Also, since you said the iosb is part of a larger structure it would seem as if the code should be something like &ptr->siosb. Could you post how siosb is getting set and the code to set it. If you define the value __NEW_STARLET and include starlet.h, you will get a version of sys$qiow() that checks parameters - this might also help point out bugs in the code.
Anthony Magana
Occasional Advisor

Re: sys$qio - how to get more info on a status 12

Roger, You're point on not needing iosb to be declared out of persistent memory is a valid one. The function in question however has a separate code path for async io (using sys$qio)as well and of course that case needs to have the persistent memory. Regarding your other questions, the app is compiled with /pointer=64. Yes, iosb is part of a larger struct, I just removed that detail to simplify the code fragment. The complete ref in the qio call is
&siosb->aioiosb_skgfrsisb where the iosb is declared like the following:


#pragma member_alignment save
#pragma nomember_alignment

struct iosb_disk
{
unsigned short int iosb_status;
unsigned int iosb_count;
unsigned short int iosb_fill;
};
#pragma member_alignment restore


I'm not sure I understand your question about how iosb is set. Thats done in the qio call. I had previously tried your idea of compiling with _NEW_STARLET that has the ansi style instead of k&r prototypes. That didn't uncover any probs (eg. casting) in the parameters.
Martin Vorlaender
Honored Contributor

Re: sys$qio - how to get more info on a status 12

>>>
#pragma member_alignment save
#pragma nomember_alignment

struct iosb_disk
{
...
<<<

Thinking aloud about the "nomember_alignment" part: could it be that the IOSB needs to be longword- (or even quadword-)aligned?

You could fix that by adding a base alignment to the pragma:

#pragma nomember_alignment longword

cu,
Martin
Volker Halle
Honored Contributor

Re: sys$qio - how to get more info on a status 12

Anthony,

yes, the page protection for both the (beginning of the) buffer and the IOSB look o.k.

To detect any read/write access problems BEFORE issueing the QIOW, could you just try to read and write the IOSB and the whole buffer ?

Or use SDA> show proc/page buf;buflen ?

What kind of device is the channel assigned to (any non-standard OpenVMS device driver) ?

You could also try to compile with /LIS/MACHINE_CODE and look at the code generated for the SYS$QIOW call. The IOSB address should be passed in R19 into the SYS$QIOW routine.

Volker.
Anthony Magana
Occasional Advisor

Re: sys$qio - how to get more info on a status 12

Martin, your observations about the pragma made me think that there could also be some issue with alignment for the larger structure wherein iosb is contained. Certainly something worth investigating further, thanks.

Volker, to answer your question about the device the channel is assigned to, its a standard disk device. About the register placement of the iosb for the qio call, yep, I also observed that iosb is placed in R19 (did a display of the machine code in the debugger then did step/instr leading up to the failure and poked around the registers). Haven't had a chance to try out your suggestion of reading and writing to buf and iosb before the call.