Boost C++ struct in shared memory via function - c++

I'm currently working with the Boost library to create a simple IPC.
I decided to outsource the creation of the shared_memory_object and the assignment of the structure into a function.
This is my function connect:
shared_data* connect(char *name){
//open or create shared memory object
shared_memory_object shm_obj(open_or_create, name, read_write);
offset_t size;
shm_obj.get_size(size);
shared_data * data;
//newly created
if(size == 0){
//set size
shm_obj.truncate(sizeof(data));
//map region to process
mapped_region region(shm_obj, read_write);
//get adress from region
void * addr = region.get_address();
//save structure to memory
data = new (addr) shared_data;
return static_cast<shared_data *>(addr);
//or return data;
}
It is called by:
shared_data * data = connect("shared_memory");
in the main function.
But as soon as the program leaves the function through the return statement my debugger shows, that all the values in the struct are no longer accessible. (unable to read memory)
The memory adress is correct and my calling line also receives this memory adress, but as soon as any other function wants to work with the variable data, it throws an access violation error.
I have absolutely no clue on how to solve this. I have already tried creating my object anywhere and then moving it to the wanted adress.
It would be great if you guys could help me!

The lifetime of your shared_memory_object ends as soon as the function scopes exits, so yes, you can't refer to the shared memory object anymore.
Keep the shared_memory_object in a location where the lifetime extends beyond the end of the function.
The usual approach is class members. You could make the function a member of the same class and keep the object instance around.

Related

IoBuildAsynchronousFsdRequest with IRP_MJ_WRITE

I developed a WDM filter driver on disk driver. I want to send an asynchronous request to write data on disk. The windows will crash when I delete the writeBuffer memory in WriteDataIRPCompletion function.
My question is: How can I safely free the writeBuffer memory without crashing?
This my send request code:
#pragma PAGEDCODE
NTSTATUS WriteToDeviceRoutine() {
PMYDRIVER_WRITE_CONTEXT context = (PMYDRIVER_WRITE_CONTEXT)ExAllocatePool(NonPagedPool,sizeof(PMYDRIVER_WRITE_CONTEXT));
context->writeBuffer = new(NonPagedPool) unsigned char[4096];
PIRP pNewIrp = IoBuildAsynchronousFsdRequest(IRP_MJ_WRITE,
pdx->LowerDeviceObject,
context->writeBuffer,(wroteRecordNodeCount<<SHIFT_BIT),
&startingOffset,NULL);
IoSetCompletionRoutine(pNewIrp,WriteDataIRPCompletion,context,TRUE,TRUE,TRUE);
IoCallDriver(pdx->LowerDeviceObject,pNewIrp);
}
This is my completion routine code:
#pragma LOCKEDCODE
NTSTATUS WriteDataIRPCompletion(IN PDEVICE_OBJECT DeviceObject,IN PIRP driverIrp,IN PVOID Context) {
PMDL mdl,nextMdl;
KdPrint((" WriteDataIRPCompletion \n"));
PMYDRIVER_WRITE_CONTEXT writeContext = (PMYDRIVER_WRITE_CONTEXT) Context;
if(driverIrp->MdlAddress!=NULL){
for(mdl=driverIrp->MdlAddress;mdl!=NULL;mdl = nextMdl) {
nextMdl = mdl->Next;
MmUnlockPages(mdl);
IoFreeMdl(mdl);
KdPrint(("mdl clear\n"));
}
driverIrp->MdlAddress = NULL;
}
delete [] writeContext->writeBuffer;
if(Context)
ExFreePool(Context);
KdPrint(("leave WriteDataIRPCompletion \n"));
return STATUS_CONTINUE_COMPLETION;
}
you error in next line
context = ExAllocatePool(NonPagedPool,sizeof(PMYDRIVER_WRITE_CONTEXT));
when must be
context = ExAllocatePool(NonPagedPool,sizeof(MYDRIVER_WRITE_CONTEXT));
not sizeof(PMYDRIVER_WRITE_CONTEXT) but sizeof(MYDRIVER_WRITE_CONTEXT) you allocate not structure but pointer to it.
this not produce error only if your MYDRIVER_WRITE_CONTEXT containing single field writeBuffer and no more data. otherwise you overwrite allocated memory (which is only sizeof(PVOID)) and this create bug
and about completion for IoBuildAsynchronousFsdRequest. unfortunately documentation not very good. here sated that
Before calling IoFreeIrp, an additional step is required to free the
buffer for an IRP built by IoBuildAsynchronousFsdRequest if the
following are all true:
The buffer was allocated from system memory pool.
but then all attention for
The Irp->MdlAddress field is non-NULL.
however we must check and for IRP_DEALLOCATE_BUFFER|IRP_BUFFERED_IO, without this we can leak Irp->AssociatedIrp.SystemBuffer. need next code
if (Irp->Flags & IRP_BUFFERED_IO)
{
if (Irp->Flags & IRP_INPUT_OPERATION)
{
if (!NT_ERROR(Irp->IoStatus.Status) && Irp->IoStatus.Information)
{
memcpy( Irp->UserBuffer, Irp->AssociatedIrp.SystemBuffer, Irp->IoStatus.Information );
}
}
if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
{
ExFreePool(Irp->AssociatedIrp.SystemBuffer);
Irp->AssociatedIrp.SystemBuffer = 0;
}
Irp->Flags &= ~(IRP_DEALLOCATE_BUFFER|IRP_BUFFERED_IO);
}
and check for if (writeContext) after use writeContext->writeBuffer already senseless and nosense. really you need do check for context != NULL yet in WriteToDeviceRoutine()
I'm not too familiar with the specifics of what you're working with, so here're a few details that caught my attention.
In WriteDataIRPCompletion function
PMYDRIVER_WRITE_CONTEXT writeContext = (PMYDRIVER_WRITE_CONTEXT) Context;
// ...
delete [] writeContext->writeBuffer;
if(Context)
ExFreePool(Context);
Notice that your writeContext originates from your Context argument. However, you seem to be deleting/freeing the allocated memory twice.
The ExFreePool function docs state:
Specifies the address of the block of pool memory being deallocated.
It looks like the delete [] writeContext->writeBuffer; line might be causing the problem and it just needs to be removed.
As it is right now, part of the memory that should be freed by the function has already been manually deleted by the time you invoke ExFreePool, but not set to NULL, which in turn causes ExFreePool to receive a now-invalid pointer (i.e. a non-null pointer pointing to de-allocated memory) in its Context argument, causing the crash.
In WriteToDeviceRoutine function
The documentation for ExFreePool explicitly states that it deallocates memory that has been allocated with other functions, such as ExAllocatePool and other friends.
However, your code is trying to allocate/deallocate the writeContext->writeBuffer directly using the new/delete operators respectively. It seems like you should be allocating your memory with ExAllocatePool and then deallocating with ExFreePool instead of trying to do things manually like that.
These functions may be organizing the memory in a specific way and if/when this pre-condition is not met in ExFreePool, it could end up in a crash.
On a separate note, it seems odd that you check if(Context) is null before invoking ExFreePool, but not above before you try to type-cast for your local writeContext variable and use it.
Maybe you should also check at that first point of use? If Context is always non-null, then the check might also be unnecessary prior to invoking ExFreePool.

Pass an object to another thread with AfxBeginThread

My program has a callback function which is called to handle notifications that are received in the form of objects. Because we can handle hundreds a second, this callback function handles the events by spawning a separate thread to handle each one. This is the callback function:
void _OnEvent(LPCTSTR eventID, CNotification cNotificaton) {
if (_pActiveDoc) {
Param_Event* p = new Param_Event;
p->pDoc = _pActiveDoc;
p->lpszEventID = eventID;
p->cNotification = cNotification;
AfxBeginThread(ProcessEvent,p);
}
}
My query comes from the fact that is passed to the callback method is initially created on the stack, and is therefore (according to my understanding) limited to the scope of the calling method:
void CallingMethod(CString strEventID) {
CNotification cNotification;
// Fill in the details of the notification
_OnEvent(strEventID,cNotification);
}
CNotification has a full copy constructor, and since the Param_Event object is created on the heap, my belief was that this would allow the original CNotification object to fall out of scope safely, with the spawned thread working from its own "private" CNotification object that exists until the Param_Event object is deleted with delete. The fact is, however, that we are getting (rare but occasional) crashing, and I am wondering if perhaps my belief here is incorrect: is it possible that the spawned thread is still accessing the original object somehow? If this was the case, this would explain the crashing by the rare occurrence of the object both falling out of scope and being overwritten in memory, thus creating a memory access exception.
Could I be right? Is there anything actually wrong with the method I am using? Would it be safer create the notification object on the heap initially (this would mean changing a lot of our code), or building a new object on the heap to pass to the spawned thread?
For reference, here is my ProcessEvent() method:
Param_TelephoneEvent *p = (Param_TelephoneEvent*)lParam;
p->pDoc->OnTelephoneEvent(p->lpszEventID,p->cNotification);
delete p;
return 0;
All advice welcome. Thanks in advance!
Edit: Copy constructor:
CNotification& CNotification::operator=(const CNotification &rhs)
{
m_eamspeMostRecentEvent = rhs.m_eamspeMostRecentEvent;
m_eamtcsCallStatusAtEvent = rhs.m_eamtcsCallStatusAtEvent;
m_bInbound = rhs.m_bInbound;
strcpy(m_tcExtension , rhs.m_tcExtension);
strcpy(m_tcNumber, rhs.m_tcNumber);
strcpy(m_tcName,rhs.m_tcName);
strcpy(m_tcDDI,rhs.m_tcDDI);
strcpy(m_tcCallID,rhs.m_tcCallID);
strcpy(m_tcInterTelEvent,rhs.m_tcInterTelEvent);
m_dTimestamp = rhs.m_dTimestamp;
m_dStartTime = rhs.m_dStartTime;
m_nCallID = rhs.m_nCallID;
return *this;
}

Programmatically deallocate memory in libstagrab

When and how do we free the memory when using libstatgrab. I didn't see any function call like sg_free that deallocates the memory object for storing the system statistics. For example:
sg_init(1);
sg_drop_privileges()
sg_load_stats *load_stat;
while(load_stat = sg_get_load_stats(NULL) != NULL) {
cout << load_stat->min1 << load_stat->min5 << load_stat->min15);
}
The above while loop keeps calling the sg_get_load_stats function to get the cpu load. Does it use internal buffer or create a new one every time it is called? If the later is true, shouldn't we free the object? Thanks.
The Documentation appears to state that sg_get_load_stats() has local scope and is handled by the libstatgrab library.
sg_get_load_stats_r(), which is presumably used to return the value of the stats out of the current scope, dynamically allocates and the resulting buffer needs to be cleaned up by the user.

Trouble tracking down a Bus Error/Seg Fault in C++ and Linux

I have a program that processes neural spike data that is broadcast in UDP packets on a local network.
My current program has two threads a UI thread and a worker thread. The worker thread simply listens for data packets, parses them and makes them available to the UI thread for display and processing. My current implementation works just fine. However for a variety of reasons I'm trying to re-write the program in C++ using an Object Oriented approach.
The current working program initialized the 2nd thread with:
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, getNetSpike, (void *)NULL);
Here is the getNetSpike function that is called by the new thread:
void *getNetSpike(void *ptr){
while(true)
{
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s;
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
}
Now in my new OO version of the program I setup the 2nd thread in much the same way:
void SpikePlot::initNetworkRxThread(){
pthread_t netThread;
net = NetCom::initUdpRx(host,port);
pthread_create(&netThread, NULL, networkThreadFunc, this);
}
However, because pthead_create takes a pointer to a void function and not a pointer to an object's member method I needed to create this simple function that wraps the SpikePlot.getNetworSpikePacket() method
void *networkThreadFunc(void *ptr){
SpikePlot *sp = reinterpret_cast<SpikePlot *>(ptr);
while(true)
{
sp->getNetworkSpikePacket();
}
}
Which then calls the getNetworkSpikePacket() method:
void SpikePlot::getNetworkSpikePacket(){
spike_net_t s;
NetCom::rxSpike(net, &s);
spikeBuff[writeIdx] = s; // <--- SegFault/BusError occurs on this line
writeIdx = incrementIdx(writeIdx);
nSpikes+=1;
totalSpikesRead++;
}
The code for the two implementations is nearly identical but the 2nd implementation (OO version) crashes with a SegFault or BusError after the first packet that is read. Using printf I've narrowed down which line is causing the error:
spikeBuff[writeIdx] = s;
and for the life of me I can't figure out why its causing my program to crash.
What am I doing wrong here?
Update:
I define spikeBuff as a private member of the class:
class SpikePlot{
private:
static int const MAX_SPIKE_BUFF_SIZE = 50;
spike_net_t spikeBuff[MAX_SPIKE_BUFF_SIZE];
....
}
Then in the SpikePlot constructor I call:
bzero(&spikeBuff, sizeof(spikeBuff));
and set:
writeIdx =0;
Update 2: Ok something really weird is going on with my index variables. To test their sanity I changed getNetworkSpikePacket to:
void TetrodePlot::getNetworkSpikePacket(){
printf("Before:writeIdx:%d nspikes:%d totSpike:%d\n", writeIdx, nSpikes, totalSpikesRead);
spike_net_t s;
NetCom::rxSpike(net, &s);
// spikeBuff[writeIdx] = s;
writeIdx++;// = incrementIdx(writeIdx);
// if (writeIdx>=MAX_SPIKE_BUFF_SIZE)
// writeIdx = 0;
nSpikes += 1;
totalSpikesRead += 1;
printf("After:writeIdx:%d nspikes:%d totSpike:%d\n\n", writeIdx, nSpikes, totalSpikesRead);
}
And I get the following output to the console:
Before:writeIdx:0 nspikes:0 totSpike:0
After:writeIdx:1 nspikes:32763 totSpike:2053729378
Before:writeIdx:1 nspikes:32763 totSpike:2053729378
After:writeIdx:1 nspikes:0 totSpike:1
Before:writeIdx:1 nspikes:0 totSpike:1
After:writeIdx:32768 nspikes:32768 totSpike:260289889
Before:writeIdx:32768 nspikes:32768 totSpike:260289889
After:writeIdx:32768 nspikes:32768 totSpike:260289890
This method is the only method where I update their values (besides the constructor where I set them to 0). All other uses of these variables are read only.
I'm going to go on a limb here and say all your problems are caused by the zeroing out of the spike_net_t array.
In C++ you must not zero out objects with non-[insert word for 'struct-like' here] members. i.e. if you have an object that contains a complex object (a std string, a vector, etc. etc.) you cannot zero it out, as this destroys the initialization of the object done in the constructor.
This may be wrong but....
You seemed to move the wait loop logic out of the method and into the static wrapper. With nothing holding the worker thread open, perhaps that thread terminates after the first time you wait for a UDP packet, so second time around, sp in the static method now points to an instance that has left scope and been destructed?
Can you try to assert(sp) in the wrapper before trying to call its getNetworkSpikePacket()?
It looks like your reinterpret_cast might be causing some problems. When you call pthread_create, you are passing in "this" which is a SpikePlot*, but inside networkThreadFunc, you are casting it to a TetrodePlot*.
Are SpikePlot and TetrodePlot related? This isn't called out in what you've posted.
If you are allocating the spikeBuff array anywhere then make sure you are allocating sufficient storage so writeIdx is not an out-of-bounds index.
I'd also check that initNetworkRxThread is being called on an allocated instance of spikePlot object (and not on just a declared pointer).

how to write pthread_create on the same function?

Could someone please help with this? I have the following:
// part_1
if (pthread_create(&threadID, NULL, ThreadMain,
(void *) clientSocket) != 0) {
cerr << "Unable to create thread" << endl;
exit(1);
}
// part_2
void *ThreadMain(void *clientSocket) {
pthread_detach(pthread_self());
...
delete (TCPSocket *) clientSocket;
return NULL;
}
I would to have part_2 in part_1 ( I mean without calling TreadMain() function )
thanks for your replies
What if you could do this?
pthread_create() has to create a new stack for the new thread to use. If pthread_create() copied the existing thread's old stack into a separate block of memory to create a new stack, then what would happen to local variables that point to other local variables? The local variables on the new stack would point to the old stack. When the thread using the old stack (the one that called pthread_create()) returns or overwrites them, those variables start pointing to invalid data.
But what about fork()? Why doesn't fork() take a function pointer like pthread_create()? Well, unlike pthread_create(), the new thread of execution created by fork() doesn't have to live in the same address space as the old thread of execution, because they are in separate processes. fork() clones the parent process's virtual address space, stack, heap, and all. The child process's stack variables have the same virtual addresses as the corresponding variables in the parent process. So all of the pointers in the new child process continue to be valid*, no matter what the old parent process does with the memory.
* Nitpicker's corner: excluding pointers that were invalid to begin with, as well as memory that is deliberately shared
If all you want to do is simply move the function for part2 inside part1, you can create a local class inside of part1, with a static member function...
class LocalFunctor
{
public:
static void *ThreadFunc(void* clientSocket)
{
pthread_detach(pthread_self());
...
delete (TCPSocket *) clientSocket;
return NULL;
}
};
then call LocalFunctor::ThreadFunc within pthread_create
pthread_create(&threadID, NULL, LocalFunctor::ThreadFunc,(void *) clientSocket)
If you're going to do this more than once, look at boost::thread or wrap this up inside a template helper class.
You could get an Apple Macintosh computer with OS 10.6 and start programming with Grand Central Dispatch. Apple added some new C compiler features that do almost exactly what you seem to want. They're called Blocks.