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

ACCVIO in LIBRTL while calling malloc()

 

ACCVIO in LIBRTL while calling malloc()

Recently I have ported my application from using 32bit pointers to 64bit pointers. The c-application is compiled with /pointer_size=64 on OpenVMS 8.2 for Alpha.

On a test system the application runs without any problems. Today we tried to run the application on our production system. After a couple of minutes we get the following Error and the process dies:


%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=0170495DD7D28823, PC=FFFFFFFF8083824C, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
LIBRTL 0 000000000000E24C FFFFFFFF8083824C
DECC$SHR_EV56 0 000000000005C01C FFFFFFFF80ACC01C
Ossl OSSL sizedMalloc 42784 0000000000000108 0000000003D40108


"Ossl" is my module, the "line" points to a call to the crtl-function "malloc()". This should return a 64bit-pointer to an unused memory block.

Does the virtual address in the error message point to S2 space? Is there an error in the LIBRTL.EXE sharable (this file is the same on the test and production system)?

More info: Till the error the application has done about 500 malloc()s and nearly the same count of free()s.
20 REPLIES 20
Volker Halle
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Hi,

consider to get a process dump. Use SET PROC/DUMP before running the image or run it with /DUMP if a detached process. Then look at the failing instrurtion, the registers and whatever value your routine passed to the malloc call.

The bad virtual address could be interpreted as a P2 space address, but it's most likely just an invalid address.

Volker.
Hein van den Heuvel
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

This is 99.99% sure to be a usage error.
I'm only saying that you help you focus your trouble shoorting. Do NOT waste time suspecting the sustem function.

This is likely to be a control structure corruption DETECTED (ok, not detected but stumbled into) by malloc, but caused by a bad FREE.

Something de-allocated which was (no more) allocated?
Some structure used after the memory was freed?

You may need to fully trace your mallocs/frees.

Good luck!
Hein.

Re: ACCVIO in LIBRTL while calling malloc()

Volker,
thanks to remind me to set the process's dump-flag. I usually use it in all my projects but forgot it here.

Hein,
and what about the other 0.01% ;-) Okay, I agree not to assume a system-function error.

I am definitly sure that each malloc() has its free() and that there are no double free()s. But I cannot be absolutely sure, wether the limits of the allocated memory blocks are respected or not - the blocks are used by a third party api.

During massive tests with several 100 thousand iterations on the test system the limits were respected (validated by using my own implementation of malloc/free). The crash on the production system occurred on the 3rd iteration.

While reading your reply I suspect that the LIBRTL keeps its structures within P2. Is this also the case for the lib$*vm* routines which I suppose you prefere?

And what about thread-safety? Are malloc() and free() (and realloc()) thread-save?

Regards,
Dominik
John Gillings
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

If you want to easily trace your LIBRTL calls, use FAKE_RTL. Here's a complete transcript, building the fake image and tracing all LIB$GET_VM and LIB$FREE_VM calls in a DIRECTORY command:


$ @fake_rtl
Defining FAKE_RTL environment
$ @fake_rtl librtl
%COPY-S-COPIED, SYS$COMMON:[SYSLIB]LIBRTL.EXE;1 copied to DISK_USER0:[JG.FAKE_RTL]REAL_LIBRTL.EXE;1 (2080 blocks)
Generating symbol vector for LIBRTL on Alpha
%ANALYZE-I-ERRORS, DISK_USER0:[JG.FAKE_RTL]REAL_LIBRTL.EXE;1 0 errors
Generating MACRO code for LIBRTL
Assumed JSB routine LIB$ANALYZE_SDESC_R2
Warning - vector hole before LIB$CVT_DTB. Expecting 272, got 288
Warning - vector hole before LIB$DELETE_FILE. Expecting 336, got 352
Warning - vector hole before LIB$EXTV. Expecting 432, got 448
Warning - vector hole before LIB$GET_COMMAND. Expecting 544, got 576
Warning - vector hole before LIB$INDEX. Expecting 608, got 624
Warning - vector hole before LIB$LOCC. Expecting 656, got 672
Warning - vector hole before LIB$SCANC. Expecting 848, got 864
Assumed JSB routine LIB$SGET1_DD_R6
Warning - vector hole before LIB$TRA_ASC_EBC. Expecting 1168, got 1184
Assumed JSB routine OTS$$CVT_D_T_R8
Assumed JSB routine OTS$$CVT_F_T_R8
Assumed JSB routine OTS$$CVT_G_T_R8
Assumed JSB routine OTS$$CVT_H_T_R8
Assumed JSB routine OTS$MOVE3_R5
Assumed JSB routine OTS$MOVE5_R5
Assumed JSB routine OTS$SGET1_DD_R6
Assumed JSB routine STR$ANALYZE_SDESC_R1
Assumed JSB routine STR$COPY_DX_R8
Assumed JSB routine STR$COPY_R_R8
Assumed JSB routine STR$FREE1_DX_R4
Assumed JSB routine STR$GET1_DX_R4
Assumed JSB routine STR$LEFT_R8
Assumed JSB routine STR$LEN_EXTR_R8
Assumed JSB routine STR$POSITION_R6
Assumed JSB routine STR$POS_EXTR_R8
Assumed JSB routine STR$REPLACE_R8
Assumed JSB routine STR$RIGHT_R8
Assumed JSB routine OTS$$RET_A_CVT_TAB_R1
Warning - vector hole before LIB$EMUL. Expecting 2896, got 2912
Warning - vector hole before LIB$REMQHI. Expecting 3104, got 3120
Warning - vector hole before STR$ADD. Expecting 3392, got 3680
Assumed JSB routine STR$ELEMENT_R8
Warning - vector hole before LIB$TABLE_PARSE. Expecting 4496, got 4576
Warning - vector hole before LIB$FIND_VM_ZONE. Expecting 4608, got 4640
Warning - vector hole before LIB$LOCK_IMAGE. Expecting 6912, got 7248
Warning - vector hole before OTS$CNVOUT_S. Expecting 7328, got 7376
Start of data block 1 0000000000107230 LIB$AB_ASC_EBC
Compiling FAKE_LIBRTL
Linking FAKE_LIBRTL
$

$ define FAKE_DUMPARGS TRUE ! Enable argument dumping
$ fake_librtl ! enable fake_librtl for next image to run
$ dir *librtl*

Directory DISK_USER0:[JG.FAKE_RTL]

FAKE_LIBRTL.EXE;1 271 4-MAR-2008 08:28:41.70
FAKE_LIBRTL.MAR;1 60 4-MAR-2008 08:28:30.62
FAKE_LIBRTL.OBJ;1 426 4-MAR-2008 08:28:32.16
FAKE_LIBRTL.OPT;1 57 4-MAR-2008 08:28:30.62
LIBRTL.DATA;1 1 4-MAR-2008 08:28:30.58
LIBRTL.VEC;1 60 4-MAR-2008 08:28:30.54
REAL_LIBRTL.EXE;1 2080 4-MAR-2008 08:28:29.14

Total of 7 files, 2955 blocks.

$ search fake_argdump.log _VM ! Look for calls in argument dump
LIB$GET_VM at 08:30:30.43 from 00000000000342B4
LIB$GET_VM called with 3 args
LIB$GET_VM returning 3 args
LIB$GET_VM returned: 00000001 at 08:30:30.43
LIB$GET_VM at 08:30:30.43 from 00000000000342B4
LIB$GET_VM called with 3 args
LIB$GET_VM returning 3 args
LIB$GET_VM returned: 00000001 at 08:30:30.43
LIB$GET_VM at 08:30:30.43 from 000000007AFA0D5C
LIB$GET_VM called with 2 args
LIB$GET_VM returning 2 args
LIB$GET_VM returned: 00000001 at 08:30:30.43
LIB$GET_VM at 08:30:30.45 from FFFFFFFF80DD06B8
LIB$GET_VM called with 2 args
LIB$GET_VM returning 2 args
LIB$GET_VM returned: 00000001 at 08:30:30.45
LIB$FREE_VM at 08:30:30.46 from 0000000000034434
LIB$FREE_VM called with 3 args
LIB$FREE_VM returning 3 args
LIB$FREE_VM returned: 00000001 at 08:30:30.46
LIB$FREE_VM at 08:30:30.46 from 0000000000034434
LIB$FREE_VM called with 3 args
LIB$FREE_VM returning 3 args
LIB$FREE_VM returned: 00000001 at 08:30:30.46
LIB$FREE_VM at 08:30:30.46 from FFFFFFFF80DD6004
LIB$FREE_VM called with 2 args
LIB$FREE_VM returning 2 args
LIB$FREE_VM returned: 00000001 at 08:30:30.46

(that said, I'd be interested to see how FAKE_RTL handles 64 bit addressing... it might not work properly)
A crucible of informative mistakes

Re: ACCVIO in LIBRTL while calling malloc()

Hi John,

thank you for the hint. I will try this tomorrow. Btw. I've never heard of fake_rtl. Is this link the latest version of it?

http://h71000.www7.hp.com/openvms/journal/v7/fake_rtl_com.txt

Dominik
John Gillings
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

Come to think of it, that version is a bit old. I've attached the latest version as a text file, just rename to FAKE_RTL.COM

Please let me know what happens with the 64 bit addresses.
A crucible of informative mistakes
Hoff
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

If you have more than one malloc() call and one free() in a typical application, you'll want to resolve that. Scattered calls are a classic coding issue, because it makes it far harder to find these issues.

Do centralize your memory management calls.

Once you have your memory management calls centralized into your own my_malloc() and my_free(), you can do a couple of things. The first of which is (if platform-specific code is permissible) ditch malloc() and free() in favor of direct lib$get_vm and lib$free_vm calls. You have more control here, and you can particularly establish VM zones for various purposes including for garbage-collection-style memory management. More importantly for this particular situation, you can implement what I call "fenceposts"; structures in the memory management that allow you to detect errors at deallocation (by checking the integrity of the memory), or at run-time using the RTL VM verification call.

Articles on C memory management debugging are here, including details on fenceposts:

http://64.223.189.234/node/401
http://64.223.189.234/node/260

Stephen Hoffman
HoffmanLabs LLC

Re: ACCVIO in LIBRTL while calling malloc()

John,

I have written this small C-code:

$ type test64.c
//#include stdlib.h // suppress compile err
void main() {
char *c = malloc(1);
*c = 1; // this is line 4 in traceback
}

and compiled it with 64bit-pointer support:
$ cc test64/noopt/debug/pointer_size=64
$ link test64
$ r test64

This works fine so far. If run after a call to fake_librtl test64 will crash. If the same code is compiled without 64bit-pointer support then test64 does not crash.

In the 64bit-version of test64 the address I get from malloc() is a valid address. But it seems that the related memory page is still protected when used with fake_librtl :-(

$ fake_librtl
$ r test64
%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=FFFFFFFF80000010, PC=0000000000020108, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
test64 TEST64 main 4 0000000000000108 0000000000020108
test64 TEST64 __main 0 0000000000000094 0000000000020094
0 FFFFFFFF8033BF94 FFFFFFFF8033BF94


I have also tried to use fake_librtl to trace lib$ calls within my module. But because my module is itself a sharable image it is very difficult to get it running (the main image crashed while using fake_librtl). I have given it up to get this running.

Next I will check if any code tries to reuse invalid memory addresses.

Dominik
John Gillings
Honored Contributor

Re: ACCVIO in LIBRTL while calling malloc()

Dominik,

Thanks for the feedback, I suspected it might not work, as there has been no consideration for 64 bit addresses in FAKE_RTL. FAKE_RTL assumes a VAX style calling standard with homed 32 bit arguments. I'll consider adding 64 bit support when I have long term access to an I64 system to test on.

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!

The implication is your pointer "c" has been corrupted with the system address.
A crucible of informative mistakes