Re: Issues in generating unique time id using virtual memory address
On Jun 11, 4:56 am, Pavel
<pauldontspamt...@removeyourself.dontspam.yahoo> wrote:
ittium wrote:
Group,
I came across a timer implementation where to generate unique timer id,
implementer has used virtual memory address. In the program written =
below,
using new, 1 byte memory is allocated, this memory is kept reserved til=
l timer
expiry. Since this address will be unique (in program virtual memory),
uniqueness of timer id is guaranteed. This code is used in a multi-thre=
aded
program and is supposed to generate unique ids on 32bit and 64bit machi=
nes. The
code always work fine during unit testing. But in field trials (code ru=
nning for
more than a month or so) , some time, we have seen on a 32 bit machine =
code
generates junk timerId.
How do you determine when the timerId is junk?
We have taken gcore of running process, all of timer ids except few
are less than 32 bit. Few timer ids are more than 32 bit. Since
machine is 32 bit, I was wondering if new can return more than 32 bit
long address.
Are you trying to narrow that BYTE8 back to the pointer type and are not =
finding
the original BYTE8* there? How are you doing the reverse conversion?
I doubt a possible heap corruption, but we can not run
memory profilers in field trials. Please go through the code. I have=
added my
comments, where I think code might have some issue.
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef uint64_t BYTE8;
typedef unsigned char BYTE;
#define _AAANEW(ptr,structClass) \
try \
{ \
ptr = NULL; // Comment - not needed but see the catch bloc=
k
ptr = new structClass; \
} \
catch(...) \
{ \
if(ptr == NULL) \
{ \
cout<<"Failure in _AAANEW, exiting the process";\
exit(0); \
} \
}
BYTE8 getTimerId()
{
BYTE* timer;
_AAANEW(timer,BYTE); //Comment - On 32 bit machine, timer w=
ill
//contain 32 bit virtual memory =
address
/* Timer id is taken as BYTE 8 since timer Id will be gener=
ated
on 32 bit an 64 bit also */
BYTE8 timerId = (BYTE8)timer; //Comment - I am not sure
// whether for 32 bit machine this
//conversion is safe
It is safe as long as BYTE8 is a large enough integer to hold the value o=
f the
pointer (which should hold in your situation), but see below:
Theoretically, reinterpret_cast which is IMHO what is applied here for th=
e
explicit cast conversion can change representation, so you might want to
double-check check you are not using some fancy union stuff when you are
converting the BYTE8 back to BYTE*.
While deleting the memory, we are just doing
delete((BYTE* )timerId); //Comment we should probably use reinterpret
cast.
timerId that is 8 byte. My question is, is this code unsafe on 32 bit
or 64 bit machine?. We have run it on both architecture without any
issue. We might be missing some use case where this code can fail or
corrupt the heap.
thanks Jorgen and Pavel for your time.
return timerId;
}
thanks
Ittium
HTH
-Pavel