Operating System - OpenVMS
1748106 Members
4681 Online
108758 Solutions
New Discussion юеВ

ACCVIO in LIBRTL while calling malloc()

 
Jur van der Burg
Respected Contributor

Re: ACCVIO in LIBRTL while calling malloc()

>Interesting that the VA of the fault is 8000010 - that's the address of the AST dispatcher, and you're trying to WRITE to it!

John,

That's not the case. If you're compiling with 64 bit pointers you will get a 64 bit pointer to a piece of memory, in this case 00000000.80000010 which is a valid P2 space address.

Fwiw,

Jur.

Re: ACCVIO in LIBRTL while calling malloc()

Jur,

fake_librtl returns a signed(?) 32bit pointer. It is implicit converted to 64bit to the value FFFFFFFF.80000010. This means this is not a valid P2 address. I should have looked at the address given by the traceback.
I have verified this with the debugger. Or append:

printf("%Lx\n", c);

after the call to malloc(). Btw. malloc() has called lib$vm_malloc_64 which itself allocated P2 space at 00000000.80000000:00000000.80001FFF (see SDA). At least this has worked fine.

Dominik
Volker Halle
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

FAKE_RTL uses PUSHR/POPR to save and restore R0 and R1 around various calls. This seems to cause the high-order longword of the quadword register values to be clobbered.

$PUSH64 and $POP64 might be correct replacements for this.

Volker.
Volker Halle
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

you can make FAKE_RTL.COM work for routines returning 64-bit status values in R0/R1 like this:

In FAKE_RTL.COM replace

PUSHR #^M ; save R0 & R1

with

$PUSH64 R0 ; save full quadword values
$PUSH64 R1

and replace

POPR #^M ; restore registers

with

$POP64 R1 ; restore full quadword values
$POP64 R0

After this modification, your TEST64 program does work and the malloc returns the correct address in P2 sapce.

Making FAKE_DUMPARGS print the full 64-bit register values takes a little bit more work.

Volker.

Re: ACCVIO in LIBRTL while calling malloc()

Volker,

thanks for your patience. I got a dump file from my process. The accvio of this dumpfile is not in malloc() but in some module for which I have sourcecode. The module was compiled with /noopt and /debug enabled. This means I should have all symbols.
When invoking "ana/proc " the debugger always claims that the source listing for my module is not available. This is also the case if I force using specific sources by typing "set source/latest ".
Normally this works fine for me. But in this case the problem may be because my module is linked as a shared image and the symbols of the shared image are resolved at runtime (here: by Java's JNI).
Do you see any chance to make the source code visible in the debugger in this case?

Dominik
Volker Halle
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

did you try DBG> SET IMAGE xxx

Otherwise, you might have to compile your source code with /LIST/MACHINE and find the offending instruction stream by comparing the instructions around the failing PC in the dump and the machine code listing.

Volker.

Re: ACCVIO in LIBRTL while calling malloc()

Volker,

I tried to use "set image xxx" but it claims that the specified image cannot be found??? I also tried "set image/all" which loaded my module into the process set. At this time I could see the correct symbols in the call frames. But I am still not able to view the source code within the debugger.
I do not need to compile with /list/machine because the traceback (at the time the dump occurs) shows me the linenumbers. But I would like to examine the used variables and the contents of specific memory-addresses. I can do this only in the debugger, but only if the debugger finds the source-listings.


Okay, this is one thing. But let's go back to the origin for this thread:

Sure malloc() is not the origin of the failure. But I wonder that a module that is run in USER-MODE can corrupt memory areas which is used by system functions. (At least I call routines in LIBRTL as system function.)
I have expected that LIBRTL functions keep their internal structures within memory pages which are not accessable by USER-MODE modules. That's why I thought of an error within malloc().

Dominik
Volker Halle
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

the LIB$ routines are NOT system services, so they run in user mode and therefore can't protect their data from other user mode code.

To make progress with your process dump, you would probably need to resort to the machine code listings - tedious, but works...

Volker.
John Gillings
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

You may want to try using the HeapAnalyzer to see who's doing what with your heap memory. It's part of the debugger. See Chapter 12 in the "HP OpenVMS Debugger Manual".

http://h71000.www7.hp.com/doc/82final/4538/4538pro_024.html#index_x_1206
A crucible of informative mistakes

Re: ACCVIO in LIBRTL while calling malloc()

Thanks to all of you, who tried to help me. I have found the error!

Because my module and the 3rd party api are cross-platform I built the same code on Windows. With a good portion of luck the application then crashed near the point with the coding error. The problem was: I not only ported the code to 64bit-pointers but also tried to reduce the heap-usage by changing the sequence of some api-calls - in the wrong order...

Side-effect of the code review: On OpenVMS I now use lib$get/free_vm_64() directly. The code is about 25% faster than before, because the used api makes heavy use of memory allocation and deallocation.

Again, thanks to all of you!
Dominik