- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - OpenVMS
- >
- Re: DECC LIBRTL
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Discussions
Discussions
Forums
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 03:01 AM
тАО12-06-2007 03:01 AM
DECC LIBRTL
SYS$GETRMI and after this, program crashed on open function call.
Program is created with 64bit pointers
and $GETRMI requires 32bit pointers in args.
Pointers mismatch probably.
Here is output:
%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=00000000000A
4000, PC=FFFFFFFF8083D9E0, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
image module routine line rel PC abs PC
LIBRTL 0 000000000000D9E0 FFFFFFFF8083D9E0
DECC$SHR_EV56 0 000000000005EBA4 FFFFFFFF80AF6BA4
DECC$SHR_EV56 0 00000000000291A4 FFFFFFFF80AC11A4
DECC$SHR_EV56 0 0000000000131D54 FFFFFFFF80BC9D54
DECC$SHR_EV56 0 0000000000133674 FFFFFFFF80BCB674
DECC$SHR_EV56 0 000000000000BD48 FFFFFFFF80AA3D48
DECC$SHR_EV56 0 000000000002258C FFFFFFFF80ABA58C
SPI_agent GI_CPU_SNAPUSAGE SaveAsBMP
3019 0000000000000B64 0000000000032324
SPI_agent SPI_AGENT main 24407 0000000000001228 0000000000031228
SPI_agent SPI_AGENT __MAIN 0 0000000000000070 0000000000030070
SPI_agent 0 0000000000041FCC 0000000000041FCC
0 FFFFFFFF8037BCE4 FFFFFFFF8037BCE4
%TRACE-I-END, end of TRACE stack dump
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 03:37 AM
тАО12-06-2007 03:37 AM
Re: DECC LIBRTL
Robert,
The 'reason mask' in the signal:
%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=00000000000A
indicates a read/modify operation on address 00000000000A (10 decimal).
This is definitely not a valid address.
Is the item list for $GETRMI properly built?
(i.e. all data fields & return length variables are accessible). Any chance of a local variable getting corrupted?
Kris (aka Qkcl)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 03:59 AM
тАО12-06-2007 03:59 AM
Re: DECC LIBRTL
Thak you Kris,
The item list for $GETRMI is properly built, I mean. $GETRMI works fine alone and open()
works alone too, but when I call open() somewhere in program after $GETRMI return, it crashes.
ACCVIO occur inside of RTL, but why ?
Here is an output from analyzer:
$ anal /proc SPI_agent.DMP/image=SPI_agent.exe
OpenVMS Alpha Debug64 Version V8.3-009
%DEBUG-I-NOGLOBALS, some or all global symbols not accessible
%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=00000000000A
4000, PC=FFFFFFFF8083D9E0, PS=0000001B
break on unhandled exception at SHARE$LIBRTL_CODE0+55776
%DEBUG-I-SOURCESCOPE, source lines not available for %PC in scope number 0
Displaying source for 7\%PC
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 04:27 AM
тАО12-06-2007 04:27 AM
Re: DECC LIBRTL
It wouldn't be the first time that a variable is used and filled in one call and after that, used in another activity witout alteration - casuing havoc :). If applicaible: check overlay and slack-bytes (due to alighnment).
Also be sure that the expectation on what you received from the $GETRMI call is correct. If this requires 32-bit pointers, using a 64 bit pointer may cause problems.
Can you create a small reproducer and publish it with building instuctions, it would be of help.
WG
OpenVMS Developer & System Manager
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 05:08 AM
тАО12-06-2007 05:08 AM
Re: DECC LIBRTL
#pragma required_pointer_size 32
typedef struct
{
word buffer_length;
word item_code;
void *buffer;
word *return_buffer_length;
} ITEM_LIST;
int buffer_size = sizeof(LWORD) + ActiveCPU_cnt * sizeof(CPU_Modes_buffer);
unsigned char *buffer = (unsigned char *)_malloc32(buffer_size);
struct _iosb iosb;
unsigned __int64 error_code;
ITEM_LIST _RMI$_item_list[] = { { buffer_size, RMI$_MODES, buffer, NULL },
{ 0, 0}};
/* system service */
error_code = SYS$GETRMI(EFN$C_ENF, // event flag number
0, 0, // reserved to HP
(_void_ptr32)_RMI$_item_list, // item list
&iosb, // I/O status block
NULL, // AST function address
0 ); // AST parameter
if(error_code == SS$_NORMAL)
error_code = SYS$SYNCH(EFN$C_ENF,&iosb);
#pragma required_pointer_size 64
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 05:12 AM
тАО12-06-2007 05:12 AM
Re: DECC LIBRTL
$ CXX /POINTER_SIZE=64 SPI_agent.cpp
$ CXXLINK SPI_agent
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 11:48 AM
тАО12-06-2007 11:48 AM
Re: DECC LIBRTL
In all but a vanishingly small number of cases, the calling code contains one or more bugs. Sure, the RTLs can and do sometimes have bugs, but Occam points to the caller's code.
Probably a heap or stack corruption, but that's very far from certain.
I'd probably build the 32-bit code into one or more module(s) separate from the 64-bit code, but that's me. Add in fenceposts, some instrumentation, and related debugging.
Please post a full-source reproducer, or at least the full source of your $getrmi. CPU_Modes_buffer, _iosb and a bunch of stuff is missing here.
Here's Jim Duff's C example:
http://www.eight-cubed.com/examples/framework.php?file=sys_getrmi.c
And FWIW, the dollar sign in _RMI$_item_list... That's a reserved character; don't use dollars in any object that you own or that is unique to your code, unless you've registered the prefix with HP.
And FWIW, SS$_NORMAL is only one of many of the potential successful status codes that can be returned. Take a look at $VMS_STATUS_SUCCESS() macro or test the low bit, as I expect you want to issue the $synch for any successful status return.
Seeing in-line malloc calls tends to concern me. I've noticed that applications having these calls scattered around tend to also have run-time stability issues. I'd suggest that you centralize and instrument these calls. This class of bug can be difficult to locate and quite transient, too.
I've had a half-dozen complex applications over the years that had weird transient errors and irreproducible crashes; failures that I could never replicate nor successfully instrument. So I switched tactics. In all the cases, I found that ripping out the existing memory management and replacing it with centralized and instrumented handling resolved the bugs. Since then, I've found that the centralized memory handling has also exposed latent bugs in these and other applications.
Stephen Hoffman
HoffmanLabs LLC
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-06-2007 01:20 PM
тАО12-06-2007 01:20 PM
Re: DECC LIBRTL
Your code looks OK to me. I wouldn't expect $GETRMI to go beyond the stated buffer size, and your buffer certainly isn't smaller than what you've stated.
However, I've learnt not to trust what the code appears to do when dealing with item lists and other system structures. I'd recommend running your program under DEBUG and STEP/INTO the $GETRMI call (obviously you can't step through the system service, BUT you can get into the dispatch vector, so you're at least in the call frame of the service and can examine the actual arguments). Examine your item list in HEX to make sure you can see all the fields in the correct places. So
DBG> STEP/INTO
DBG> EXAMINE/HEX/LONG @R19 ! 4th arg
DBG> EXAMINE/HEX/LONG
...
This will help detect any alignment issues, typos and other oddities. Note that examining the structure symbolically from DEBUG will hide automatic alignment of fields.
If you want to find out which LIBRTL routine is being called, and what it was passed, use FAKE_RTL to build a fake LIBRTL.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
тАО12-07-2007 01:31 AM
тАО12-07-2007 01:31 AM
Re: DECC LIBRTL
many thanks for Your interest at first,
I provide some source for testing
HW = ALPHA
OS = OpenVMS 8.3
CXX = 7.3-009
$ CXX /POINTER_SIZE=64 test2.cxx
$ CXXLINK test2
$ ru test2
here is
/* to uncomment one of this - program will run correctly */
// #define MODE_$GETRMI_ONLY
// #define MODE_OPEN_ONLY
/* pure 64-bit application */
#if defined(__VMS) && (defined(__ALPHA) || defined(__ia64))
/* test for compilation option /POINTER_SIZE=64 */
#if !defined(__INITIAL_POINTER_SIZE) || __INITIAL_POINTER_SIZE != 64
#pragma message ("Module require compilation option /POINTER_SIZE=64")
#error __INITIAL_POINTER_SIZE
#endif
#pragma required_pointer_size 64
#endif
/* software identifier */
char SoftwareID[] = "SPI TEST";
typedef unsigned char byte;
typedef unsigned short int word;
typedef unsigned long int lword;
typedef unsigned long int LWORD;
typedef unsigned long int longword;
typedef unsigned __int64 quadword;
typedef unsigned __int64 QWORD;
// --------------------------------------------------------------------------------------
/* NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0L
#else /* __cplusplus */
#define NULL ((void *)0L)
#endif /* __cplusplus */
#endif /* NULL */
// --------------------------------------------------------------------------------------
#pragma required_pointer_size save
#pragma required_pointer_size 32
typedef void *_void_ptr32;
#pragma required_pointer_size restore
/* header files */
#define __NEW_STARLET 1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#pragma member_alignment save
#pragma nomember_alignment
// --------------------------------------------------------------------------------------
//
// *********************
// * IO_STATUS_BLOCK *
// *********************
//
// I/O status block
typedef struct
{
word status;
word counter;
longword info;
} IO_STATUS_BLOCK;
// --------------------------------------------------------------------------------------
//
// ***************
// * ITEM_LIST *
// ***************
//
// 32-bit item list
#pragma required_pointer_size save
#pragma required_pointer_size 32
typedef struct
{
word buffer_length;
word item_code;
void *buffer;
word *return_length_address;
} ITEM_LIST;
#pragma required_pointer_size restore
// --------------------------------------------------------------------------------------
//
// ******************
// * ITEM_LIST_64 *
// ******************
//
// 64-bit item list
typedef struct
{
word MBO;
word item_code;
longword MBMO;
quadword buffer_length;
void *buffer_address;
word *return_length_address;
} ITEM_LIST_64;
// --------------------------------------------------------------------------------------
//
// *******************
// * RMI_CPU_MODES *
// *******************
//
// Resource monitor information data for individual CPU
typedef struct RMI_CPU_Modes
{
byte ID; // physical CPU ID
longword interrupt; // actually sum of interrupt and idle modes !
longword MP_synchro; // multi-processor synchronization
longword kernel; // kernel mode
longword executive; // executive mode
longword supervisor; // supervisor mode
longword user; // user mode
longword reserved; // reserved, will be zero
longword idle; // CPU idle
} RMI_CPU_MODES;
// --------------------------------------------------------------------------------------
#pragma member_alignment restore
/* macro definitions */
#define IL64_MBO 1
#define IL64_MMBO -1
#define COLLECT_INTERVAL "WAIT 00:00:03"
//#define TIME_STOTCK(t) (quadword)(t * 10000000) // seconds conversion to 100ns ticks
/* global variables */
//_TIMER *CollectTimer = NULL; // collection timer
/* function and routine prototypes */
//void CollectTimerASTR (...); // AST routine for collection timer
// --------------------------------------------------------------------------------------
/* error codes */
enum
{
NOERROR,
ERROR_GETSYIW,
ERROR_GETRMIW
};
// --------------------------------------------------------------------------------------
/* 64-bit error code macro */
#define ERRQWORD(f,s) ((unsigned __int64) f << sizeof(unsigned __int32) * 8) | \
(unsigned __int32) s
// --------------------------------------------------------------------------------------
static const char *_f_name_output = "CPU_Usage.bmp";
// --------------------------------------------------------------------------------------
//
// *****************
// * GetCPU_Info *
// *****************
//
// Informations about CPUs in boot instance
quadword GetCPU_Info(longword *_active_cnt,
longword *_potential_cnt = NULL,
longword *_available_cnt = NULL)
{
ITEM_LIST_64 _SYI$_item_list[4];
IO_STATUS_BLOCK iosb;
quadword error_code;
int i = 0;
/* item list initialization */
_SYI$_item_list[i].MBO = IL64_MBO;
_SYI$_item_list[i].item_code = SYI$_ACTIVECPU_CNT;
_SYI$_item_list[i].MBMO = (lword)IL64_MMBO;
_SYI$_item_list[i].buffer_length = sizeof(*_active_cnt);
_SYI$_item_list[i].buffer_address = _active_cnt;
_SYI$_item_list[i].return_length_address = NULL;
i++;
if(_potential_cnt)
{
_SYI$_item_list[i].MBO = _SYI$_item_list[0].MBO;
_SYI$_item_list[i].item_code = SYI$_POTENTIALCPU_CNT;
_SYI$_item_list[i].MBMO = _SYI$_item_list[0].MBMO;
_SYI$_item_list[i].buffer_length = sizeof(*_potential_cnt);
_SYI$_item_list[i].buffer_address = _potential_cnt;
_SYI$_item_list[i].return_length_address = _SYI$_item_list[0].
return_length_address;
i++;
}
if(_available_cnt)
{
_SYI$_item_list[i].MBO = _SYI$_item_list[0].MBO;
_SYI$_item_list[i].item_code = SYI$_AVAILCPU_CNT;
_SYI$_item_list[i].MBMO = _SYI$_item_list[0].MBMO;
_SYI$_item_list[i].buffer_length = sizeof(*_available_cnt);
_SYI$_item_list[i].buffer_address = _available_cnt;
_SYI$_item_list[i].return_length_address = _SYI$_item_list[0].
return_length_address;
i++;
}
/* item list terminator (only first 8 bytes must be zero) */
_SYI$_item_list[i].MBO = 0;
_SYI$_item_list[i].item_code = 0;
_SYI$_item_list[i].MBMO = 0;
_SYI$_item_list[i].buffer_length = 0;
/* system service */
error_code = SYS$GETSYIW(EFN$C_ENF,
NULL,
NULL,
_SYI$_item_list,
(struct _iosb *)&iosb,
NULL,
0 );
/* error testing */
if(error_code != SS$_NORMAL)
error_code = ERRQWORD(ERROR_GETSYIW,(longword)error_code);
else
if(iosb.status == SS$_NORMAL)
error_code = ERRQWORD(ERROR_GETSYIW,(longword)iosb.status);
else
error_code = 0;
/* return */
return(error_code);
}
// --------------------------------------------------------------------------------------
//
// *******************
// * GetCPU_Modes *
// *******************
//
// Informations about active CPUs load
quadword GetCPU_Modes(_void_ptr32 buffer, int buffer_size)
{
#pragma required_pointer_size save
#pragma required_pointer_size 32
IO_STATUS_BLOCK iosb;
quadword error_code;
ITEM_LIST _RMI$_item_list[] = { { buffer_size, RMI$_MODES, buffer, NULL },
{ 0, 0 } };
/* system service */
error_code = SYS$GETRMI(EFN$C_ENF,
0, 0,
(void *)_RMI$_item_list,
(struct _iosb *)&iosb,
NULL,
0 );
#pragma required_pointer_size restore
if(error_code == SS$_NORMAL)
error_code = SYS$SYNCH(EFN$C_ENF, (struct _iosb *)&iosb);
if(error_code != SS$_NORMAL)
error_code = ERRQWORD(ERROR_GETRMIW,(longword)error_code);
else
if(iosb.status == SS$_NORMAL)
error_code = ERRQWORD(ERROR_GETRMIW,(longword)iosb.status);
else
error_code = 0;
/* return */
return(error_code);
}
// --------------------------------------------------------------------------------------
//
// ***************
// * SaveAsBMP *
// ***************
//
// Member method of some class for bitmap creation
void SaveAsBMP(void)
{
int _h_file;
int file_flags = O_WRONLY | O_CREAT;
int file_mode = 0x0777;
// error after open() call
// %SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=000000000009
// 4000, PC=FFFFFFFF8083D9F0, PS=0000001B
// %TRACE-F-TRACEBACK, symbolic stack dump follows
// image module routine line rel PC abs PC
// LIBRTL 0 000000000000D9F0 FFFFFFFF8083D9F0
// DECC$SHR_EV56 0 000000000005EBA4 FFFFFFFF80AF6BA4
// DECC$SHR_EV56 0 00000000000291A4 FFFFFFFF80AC11A4
// DECC$SHR_EV56 0 0000000000131D54 FFFFFFFF80BC9D54
// DECC$SHR_EV56 0 0000000000133674 FFFFFFFF80BCB674
// DECC$SHR_EV56 0 000000000000BD48 FFFFFFFF80AA3D48
// DECC$SHR_EV56 0 000000000002258C FFFFFFFF80ABA58C
// test2 TEST2 SaveAsBMP 24175 00000000000003B4 00000000000303B4
// test2 TEST2 main 24288 0000000000000EC4 0000000000030EC4
// test2 TEST2 __MAIN 0 0000000000000070 0000000000030070
// test2 0 000000000003B2CC 000000000003B2CC
// 0 FFFFFFFF8037BCE4 FFFFFFFF8037BCE4
_h_file = open(_f_name_output, file_flags, file_mode, "ctx=bin", "ctx=stm");
// ...
// to do something
// ...
close(_h_file);
}
// --------------------------------------------------------------------------------------
//
// **********
// * main *
// **********
//
// Main function
main(int argc, char *argv[])
{
longword PotentialCPU_cnt = 0;
longword ActiveCPU_cnt = 0;
quadword *CPU_load = NULL;
quadword *CPU_total_ticks = NULL;
byte *CPU_Modes_buffer = NULL;
RMI_CPU_MODES *CPU_ModesEntry;
int buffer_size;
word *_snap_vector = NULL;
int vector_size;
quadword load;
quadword total_ticks;
int i, j;
/* fake data */
#ifdef MODE_OPEN_ONLY
word _CPU_vector[] = { 5094,
6500, 8200, 7700, 6800, 5200, 4800, 4700, 3300,
3100, 3000, 2800, 6700, 5500, 4500, 4400, 4300 };
int CPU_vector_size = 17;
#endif
/* get informations about CPUs */
GetCPU_Info(&ActiveCPU_cnt, &PotentialCPU_cnt);
printf("\n ActiveCPU_cnt = %d", ActiveCPU_cnt );
printf("\nPotentialCPU_cnt = %d", PotentialCPU_cnt);
printf("\n");
/* buffer allocation in required size, system service accepts only 32 bit pointer */
buffer_size = sizeof(LWORD) + ActiveCPU_cnt * sizeof(CPU_Modes_buffer);
CPU_Modes_buffer = (byte *)_malloc32(buffer_size);
CPU_ModesEntry = (RMI_CPU_MODES *)(CPU_Modes_buffer + sizeof(LWORD));
CPU_load = new QWORD[ActiveCPU_cnt];
CPU_total_ticks = new QWORD[ActiveCPU_cnt];
vector_size = PotentialCPU_cnt + 1;
_snap_vector = new word[vector_size];
for(i = 0; i < vector_size; i++) _snap_vector[i] = 0;
/* collection init */
#ifndef MODE_OPEN_ONLY
GetCPU_Modes((_void_ptr32)CPU_Modes_buffer, buffer_size);
#endif
for( i = 0; i < (int)ActiveCPU_cnt; i++ )
{
/* sumarize */
CPU_total_ticks[i] = CPU_ModesEntry[i].interrupt +
CPU_ModesEntry[i].MP_synchro +
CPU_ModesEntry[i].kernel +
CPU_ModesEntry[i].executive +
CPU_ModesEntry[i].supervisor +
CPU_ModesEntry[i].user +
CPU_ModesEntry[i].reserved;
// CPU_ModesEntry[i].idle;
CPU_load[i] = CPU_total_ticks[i] - CPU_ModesEntry[i].idle;
}
/* collection */
for(j = 0; j < 10; j++)
{
/* wait */
system(COLLECT_INTERVAL);
#ifndef MODE_OPEN_ONLY
GetCPU_Modes((_void_ptr32)CPU_Modes_buffer, buffer_size);
#endif
_snap_vector[0] = 0;
for ( i = 0; i < (int)ActiveCPU_cnt; i++ )
{
#ifdef MODE_OPEN_ONLY
_snap_vector[i + 1] = _CPU_vector[j % CPU_vector_size];
#else
/* sumarize */
total_ticks = CPU_ModesEntry[i].interrupt +
CPU_ModesEntry[i].MP_synchro +
CPU_ModesEntry[i].kernel +
CPU_ModesEntry[i].executive +
CPU_ModesEntry[i].supervisor +
CPU_ModesEntry[i].user +
CPU_ModesEntry[i].reserved;
// CPU_ModesEntry[i].idle;
load = total_ticks - CPU_ModesEntry[i].idle;
/* current percentage load of CPU */
_snap_vector[i + 1] = (load - CPU_load[i]) * 10000 /
(total_ticks - CPU_total_ticks[i]);
_snap_vector[0] += _snap_vector[i + 1];
/* save data for next loop */
CPU_load[i] = load;
CPU_total_ticks[i] = total_ticks;
#endif
printf("\t %5d", _snap_vector[i + 1]);
}
_snap_vector[0] /= ActiveCPU_cnt;
printf("\n");
//
// ...
//
/* save created bitmap grah to BMP file */
#ifndef MODE_$GETRMI_ONLY
SaveAsBMP();
#endif
}
/* destruction of allocated memory */
if(CPU_Modes_buffer) delete(CPU_Modes_buffer);
if(CPU_load ) delete(CPU_load );
if(CPU_total_ticks ) delete(CPU_total_ticks );
if(_snap_vector ) delete(_snap_vector );
}