Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++.moderated > #7363

Why does the following C++ program , DataServer.cpp, throws a segmentation fault at the exit of the extern "C" function, void func(void) shown in the bottom of this question?

Message-ID <c3263db0-e355-434b-9d0d-baae8121cb97@googlegroups.com> (permalink)
Newsgroups comp.lang.c++.moderated
From allswellthatendswell <FrankChang91@googlemail.com>
Subject Why does the following C++ program , DataServer.cpp, throws a segmentation fault at the exit of the extern "C" function, void func(void) shown in the bottom of this question?
Organization unknown
Date 2016-01-04 06:55 -0600

Show all headers | View raw


{ edited by mod to shorten text lines to ~70 characters.  the source
  and command lines have not been edited. -mod }

The  following  C++  program , DataServer.cpp, throws  a segmentation
fault at the exit of  the extern "C" function,  void func(void) shown
in the bottom of this question. I  compiled  this program on Ubuntu
Linux 14.04 LTS with the g++ entry point feature.

 g++   -shared -g -fPIC -DLINUX -Wl,-soname,libdataserver.so -efunc  -I
/home/venkat/Downloads/waitForMultipleObjects -I
/home/venkat/developmentMono/SmartCamXi_Hybrid/Include  DataServer.cpp
DataServerLib.cpp DataTransferClient.cpp CWinEventHandle.cpp WinEvent.cpp
-lpthread -lrt

 When I  run gdb ./a.out  core,  I get the following output:
:~/Downloads/DataServerLib$ gdb ./a.out

 Reading symbols from ./a.out...done.
      [New LWP 8538]
 Core was generated by `./a.out'.
 Program terminated with signal SIGSEGV, Segmentation fault.
 #0  0x0000000000000001 in ?? ()
 (gdb) bt
 #0  0x0000000000000001 in ?? ()
 #1  0x00007ffdab79f29e in ?? ()
 #2  0x0000000000000000 in ?? ()
 (gdb) where
 #0  0x0000000000000001 in ?? ()
 #1  0x00007ffdab79f29e in ?? ()
 #2  0x0000000000000000 in ?? ()
 (gdb) list
 1      #include <stdio.h>
 2      #ifndef LINUX 
 3      #include <aclapi.h>
 4      #else
 5      #include <errno.h>
 6      #endif
 7      #include "DataServer.h"
 8      #include "CameraControlDefs.h"
 9      #include <iostream>
 10      #include <unistd.h>

 I would like to find out the cause of the segmentation fault and how to
possibly fix it. I have already examined the  delete srv source code
line at the end of the extern "C" function , void func(void)  and the
CDataTransferServer destructor appears to function properly.
 Any help is greatly appreciated.






 #include <stdio.h>
 #ifndef LINUX 
 #include <aclapi.h>
 #else
 #include <errno.h>
 #endif
 #include "DataServer.h"
 #include "CameraControlDefs.h"
 #include <iostream>
 #include <unistd.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/types.h>
 #include <stdlib.h>
 #include <sys/stat.h>        /* For mode constants */
 #include <fcntl.h>           /* For O_* constants */
 #include <wchar.h>
 #include "winEmul.h"
 #ifdef LINUX
 #include <semaphore.h>
 #include <unistd.h>
 #endif
 //#include "SmartLog.h"
 #ifdef LINUX
 typedef void* PSECURITY_DESCRIPTOR;
 typedef unsigned int DWORD; 
 #endif

 #ifdef LINUX
 inline int memcpy_s(void* dest, size_t numberOfElements, const void *src,
size_t count)
 {
   memcpy(dest, src, count);
   return errno;
 }
 #endif

 #ifdef __LP64__
 const char service_interp[] __attribute__((section(".interp"))) =
"/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2";
 #else
 const char service_interp[] __attribute__((section(".interp"))) =
"/lib/ld-linux.so.2";
 #endif

 
////////////////////////////////////////////////////////////////////////////
//////////////////////
 // CDataTransferUser

 
//==========================================================================
======================
 CDataTransferUser::CDataTransferUser()
 {
       m_bInitialized = false;
       m_hSharedMemory = NULL;
       m_pControl = NULL;
       m_hMutexControl = NULL;
 }

 
//==========================================================================
======================
 CDataTransferUser::~CDataTransferUser()
 {
       if (m_pControl)
       {
 #ifndef LINUX
             ::UnmapViewOfFile(m_pControl);
 #else
             munmap(m_pControl,0);
 #endif
       }
       if (m_hSharedMemory)
             ::CloseHandle(m_hSharedMemory);
       if (m_hMutexControl)
             ::CloseHandle(m_hMutexControl);
 }

 // The following function initializes the supplied security descriptor
 // with a DACL that grants the Authenticated Users group GENERIC_READ,
 // GENERIC_WRITE, and GENERIC_EXECUTE access.
 // 
 // The function returns NULL if any of the access control APIs fail.
 // Otherwise, it returns a PVOID pointer that should be freed by calling
 // FreeRestrictedSD() after the security descriptor has been used to
 // create the object.
 #ifdef LINUX
 void* CDataTransferUser::BuildRestrictedSD(void* pSD)
 #else
 void* CDataTransferUser::BuildRestrictedSD(PSECURITY_DESCRIPTOR pSD)
 #endif
 {
 #ifdef LINUX
    return NULL;
 #else
    DWORD  dwAclLength;

    PSID   pAuthenticatedUsersSID = NULL;

    PACL   pDACL   = NULL;
    BOOL   bResult = FALSE;

    PACCESS_ALLOWED_ACE pACE = NULL;

    SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY;
    
    SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
    
    __try
    {
       // initialize the security descriptor
       if (!InitializeSecurityDescriptor(pSD, 
             SECURITY_DESCRIPTOR_REVISION))
         {
          printf("InitializeSecurityDescriptor() failed with error %d\n",
                GetLastError());
          __leave;
       }

       // obtain a sid for the Authenticated Users Group
       if (!AllocateAndInitializeSid(&siaNT, 1, 
             SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0, 
             &pAuthenticatedUsersSID))
         {
          printf("AllocateAndInitializeSid() failed with error %d\n",
                GetLastError());
          __leave;
       }

       // NOTE:
       // 
       // The Authenticated Users group includes all user accounts that
       // have been successfully authenticated by the system. If access
       // must be restricted to a specific user or group other than 
       // Authenticated Users, the SID can be constructed using the
       // LookupAccountSid() API based on a user or group name.

       // calculate the DACL length
       dwAclLength = sizeof(ACL)
             // add space for Authenticated Users group ACE
             + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)
             + GetLengthSid(pAuthenticatedUsersSID);

       // allocate memory for the DACL
       pDACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 
             dwAclLength);
       if (!pDACL)
         {
          printf("HeapAlloc() failed with error %d\n", GetLastError());
          __leave;
       }

       // initialize the DACL
       if (!InitializeAcl(pDACL, dwAclLength, ACL_REVISION))
         {
          printf("InitializeAcl() failed with error %d\n", 
                GetLastError());
          __leave;
       }
       
       // add the Authenticated Users group ACE to the DACL with
       // GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access
       if (!AddAccessAllowedAce(pDACL, ACL_REVISION,
             GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
             pAuthenticatedUsersSID))
         {
          printf("AddAccessAllowedAce() failed with error %d\n",
                GetLastError());
          __leave;
       }

       // set the DACL in the security descriptor
       if (!SetSecurityDescriptorDacl(pSD, TRUE, pDACL, FALSE))
         {
          printf("SetSecurityDescriptorDacl() failed with error %d\n",
                GetLastError());
          __leave;
       }

       bResult = TRUE;
      
    } __finally
    {
       if (pAuthenticatedUsersSID)
            FreeSid(pAuthenticatedUsersSID);
    }

    if (bResult == FALSE)
    {
       if (pDACL)
               HeapFree(GetProcessHeap(), 0, pDACL);
       pDACL = NULL;
    }

    return (void*) pDACL;
 #endif // ends Windows code 
  }

 // The following function frees memory allocated in the
 // BuildRestrictedSD() function
 void CDataTransferUser::FreeRestrictedSD(void* ptr)
 {
 #ifndef LINUX
    if (ptr)
          HeapFree(GetProcessHeap(), 0, ptr);
 #endif
    return;
 }


 
////////////////////////////////////////////////////////////////////////////
//////////////////////
 // CDataTransferServer

 
//==========================================================================
======================
 CDataTransferServer::CDataTransferServer()
 {
       m_nCameraID = 0;
       m_nFileMapSize = 0;
       m_nMaxFrames = 0;
       m_nMaxConfigSize = 0;
       m_nConfigBlocks = 0;
       m_bKeyBlock = false;
       m_nMaxDataSize = 0;
       m_nControlSize = 0;
       m_nUserReferenceCount = 0;
       m_szObjNameSuffix[0] = '\0';
       m_nLastSendTime = 0;
       m_nDistanceFromKeyData = 0;
       m_nLastErrorLoggedIgnoreFrames = 0;
       m_nPFramesIgnored = 0;
 #ifndef LINUX
       ::InitializeCriticalSectionAndSpinCount(&m_lockEvents, 0x80000400);
 #else
       pthread_mutexattr_t mutexattr;
         pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE_NP);
         pthread_mutex_init(&m_lockEvents,&mutexattr);
 #endif
 }

 
//==========================================================================
======================
 CDataTransferServer::~CDataTransferServer()
 {
       // Close all of the events
 #ifndef LINUX
       ::EnterCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_lock(&m_lockEvents);
 #endif
       while (m_mapUserEvents.size() > 0)
       {
             ::CloseHandle(m_mapUserEvents.begin()->second.hEvent);
                 printf("before m_mapUserEvents erase size() =
%d\n",m_mapUserEvents.size());
             m_mapUserEvents.erase(m_mapUserEvents.begin());
             printf("after m_mapUserEvents erase size() =
%d\n",m_mapUserEvents.size());
       }
 #ifndef LINUX
       ::LeaveCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_unlock(&m_lockEvents);
         printf("pthread_mutex_unlock\n");
 #endif
 #ifndef LINUX
       ::DeleteCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_destroy(&m_lockEvents);
         printf("pthread_mutex_destroy\n");
 #endif
 }

 
//==========================================================================
======================
 bool CDataTransferServer::AddUser(unsigned int nUserID, std::wstring&
strMemoryName,
                                                       std::wstring&
strMutexName, std::wstring& strEventName)
 {
         printf("AddUser\n");
 #ifndef LINUX
       ::EnterCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_lock(&m_lockEvents);
 #endif
       if (m_mapUserEvents.find(nUserID) == m_mapUserEvents.end())
       {

             ++m_nUserReferenceCount;
             UserEventInfo ei;
             ei.strEventName = L"Global\\SmartCamEvent";
 #ifdef LINUX
             wchar_t arg[512];
                 mbstowcs(arg,m_szObjNameSuffix,512);
                 ei.strEventName += arg;
 #else
             ei.strEventName += m_szObjNameSuffix;
 #endif
             printf("AddUser2\n");      
 #ifdef LINUX
             wchar_t szUserID[16];
             swprintf(szUserID, sizeof(szUserID) / sizeof(*szUserID) ,
L"_%x", nUserID);
             ei.strEventName += szUserID;
 #else
             TCHAR szUserID[16];
             wsprintf(szUserID, L"_%x", nUserID);
             ei.strEventName += szUserID;
 #endif
 #ifndef LINUX
             SECURITY_ATTRIBUTES sa;
             LPSECURITY_ATTRIBUTES lpEventAttributes = &sa;
             SECURITY_DESCRIPTOR sd;
             sa.nLength = sizeof sa;
             sa.bInheritHandle = FALSE;
             sa.lpSecurityDescriptor = &sd;
             void* pDACL = BuildRestrictedSD(&sd);
             if (pDACL == NULL)
                   lpEventAttributes = NULL;
                 ei.hEvent = CreateEvent(lpEventAttributes, FALSE, FALSE,
ei.strEventName.c_str());
 #else
             ei.hEvent = CreateEvent(NULL, false, false,
ei.strEventName.c_str());
                 printf("AddUser3\n");
 #endif
             ei.nLastEventConsumedTime = 0;

 #ifndef LINUX
             if (pDACL)
                   FreeRestrictedSD(pDACL);
 #endif

             m_mapUserEvents[nUserID] = ei;
       }

       strEventName = m_mapUserEvents[nUserID].strEventName;
       strMemoryName = m_strMemoryName;
       strMutexName = m_strMutexName;
         printf("AddUser4\n");
 #ifndef LINUX
       ::LeaveCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_unlock(&m_lockEvents);
 #endif
       return true;
 }

 
//==========================================================================
======================
 bool CDataTransferServer::RemoveUser(unsigned int nUserID)
 {
 #ifndef LINUX
       ::EnterCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_lock(&m_lockEvents);
 #endif

       CUserEventMap::iterator itEvent = m_mapUserEvents.find(nUserID);
       if (itEvent != m_mapUserEvents.end())
       {
             if (m_nUserReferenceCount > 0)
                   --m_nUserReferenceCount;

             ::CloseHandle(itEvent->second.hEvent);
             m_mapUserEvents.erase(itEvent);
       }

 #ifndef LINUX
       ::LeaveCriticalSection(&m_lockEvents);
 #else
       pthread_mutex_unlock(&m_lockEvents);
 #endif
       return true;

 }

 
//==========================================================================
======================
 bool CDataTransferServer::Initialize(int nCameraID, CC_SAMPLETYPE
nDataType,
                                                                   unsigned
int nImageWidth, unsigned int nImageHeight,
                                                                   unsigned
int nMaxFrames)
 {
       bool bOkay = true;
         char buffer[64] = {0};

       // This is going to be a problem if we try to re-initialize with a
different image size...
       if (m_bInitialized)
             return true;


       m_nCameraID = nCameraID;
       m_nMaxFrames = nMaxFrames;
       if (m_nMaxFrames < 2)
             m_nMaxFrames = 2;

       // Calculate how much space we need for the data and headers
       m_nMaxDataSize = 0;
       m_nMaxConfigSize = 0;
       m_nConfigBlocks = 0;
       if (((nDataType & CC_SAMPLETYPE_MPEG4) == CC_SAMPLETYPE_MPEG4) ||
((nDataType & CC_SAMPLETYPE_MPEG4AVC) == CC_SAMPLETYPE_MPEG4AVC))
       {
             m_nMaxDataSize = (nImageWidth * nImageHeight) + 1024; // for
VideoFrame size and motion data  
             m_nMaxConfigSize = 1024;
             m_nConfigBlocks = 1;
             m_bKeyBlock = true;
       }
       else if (nDataType == CC_SAMPLETYPE_UNCOMPRESSEDVIDEO_YUY2)
       {
             m_nMaxDataSize = (nImageWidth * nImageHeight * 2) + 1024; //
for VideoFrame size and motion data  
             m_nMaxConfigSize = 0;
       }
       else if (nDataType == CC_SAMPLETYPE_MJPEG)
       {
             m_nMaxDataSize = (nImageWidth * nImageHeight) + 1024; // for
VideoFrame size and motion data  
             m_nMaxConfigSize = 0;
       }

       m_nMaxFrames += m_bKeyBlock ? 1 : 0;
       m_nMaxDataSize += 4 + sizeof(uTypeSpecificSize);

       m_nControlSize = sizeof(CDataTransferControl);
// Control Block
       m_nControlSize += (m_nMaxFrames - 1) *
sizeof(CDataTransferBlockHeader);            // Data Block Headers
       if (m_nMaxConfigSize > 0)
             m_nControlSize += sizeof(CDataTransferBlockHeader);

       // Make sure the control size is DWORD-aligned
       while ((m_nControlSize & 0x03) != 0)
             ++m_nControlSize;

       m_nFileMapSize = m_nControlSize + m_nMaxFrames * m_nMaxDataSize;
// Data Blocks
       if (m_nMaxConfigSize > 0)
             m_nFileMapSize += m_nMaxConfigSize;
// Config Header & Config Data

       // Suffix for global objects (file map and sync objects) based on
camera ID and data type

 #ifdef LINUX
       sprintf(m_szObjNameSuffix, "_%x_%x", nCameraID, nDataType);
 #else
         ::swprintf_s(m_szObjNameSuffix, 31, L"_%x_%x", nCameraID,
nDataType);
 #endif

 #ifndef LINUX
       SECURITY_ATTRIBUTES sa;
       SECURITY_DESCRIPTOR sd;
       sa.nLength = sizeof sa;
       sa.bInheritHandle = FALSE;
       sa.lpSecurityDescriptor = &sd;
       void* pDACL = BuildRestrictedSD(&sd);
       if (pDACL == NULL)
             bOkay = false;
 #endif
       if (bOkay)
       {
             if (m_hMutexControl == NULL)
             {
                   m_strMutexName = L"Global\\SmartCamMutex";
 #ifdef LINUX
                         m_hMutexControl = sem_open(buffer, O_CREAT, 0600,
0);
 #else
                   m_hMutexControl = ::CreateMutex(&sa, TRUE,
m_strMutexName.c_str());
 #endif
                   if (m_hMutexControl == NULL)
                         bOkay = false;
             }
       }
 #ifdef LINUX
       if (bOkay)
       {
                 char buffer[256];
             wcstombs(buffer,m_strMemoryName.c_str(),256);
             FILE* stream = fopen(buffer, "rw");
             int fd = fileno(stream);
             m_pControl = (CDataTransferControl*)mmap(NULL,
m_nFileMapSize,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); 
                 if (m_pControl)
             {
                   memset(m_pControl, 0, m_nControlSize);
                   m_pControl->nConfigurationBlock = 0xffffffff;
                   m_pControl->nNewestKeyDataBlock = 0xffffffff;
                   m_pControl->nNewestDataBlock = 0xffffffff;
                   m_pControl->nBlockHeaders = m_nMaxFrames +
m_nConfigBlocks;
                   m_pControl->nTimeOfLastClientAccess = ::GetTickCount();
             }
             else
                   bOkay = false;
             
       }
 #else
       if (bOkay)
       {
             if (m_hSharedMemory == NULL || m_hSharedMemory ==
INVALID_HANDLE_VALUE)
             {
                   m_strMemoryName = L"Global\\SmartCamMem";
                   m_strMemoryName += m_szObjNameSuffix;
 #ifdef LINUX
                         m_hSharedMemory =
 #else
                   m_hSharedMemory =
::CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE,
 #endif
0,, m_strMemoryName.c_str());
                   if (m_hSharedMemory == NULL || m_hSharedMemory ==
INVALID_HANDLE_VALUE)
                         bOkay = false;
             }
       }
       if (bOkay)
       {
             if (m_pControl == NULL)
             {
                   m_pControl =
(CDataTransferControl*)::MapViewOfFile(m_hSharedMemory,
 
FILE_MAP_ALL_ACCESS, 0, 0, m_nFileMapSize);
                   if (m_pControl)
                   {
                         ::ZeroMemory(m_pControl, m_nControlSize);
                         m_pControl->nConfigurationBlock = 0xffffffff;
                         m_pControl->nNewestKeyDataBlock = 0xffffffff;
                         m_pControl->nNewestDataBlock = 0xffffffff;
                         m_pControl->nBlockHeaders = m_nMaxFrames +
m_nConfigBlocks;
                         m_pControl->nTimeOfLastClientAccess =
::GetTickCount();
                   }
                   else
                         bOkay = false;
             }
       }
 #endif

 #ifndef LINUX 
       if (pDACL)
             FreeRestrictedSD(pDACL);
 #endif
       if (m_hMutexControl)
 #ifndef LINUX
             ::ReleaseMutex(m_hMutexControl);
 #endif
       m_bInitialized = bOkay;

       return bOkay;
 }

 
//===========================================================:==============
=======================
 bool CDataTransferServer::SendData(CVideoFrame *frame)
 {
       bool bFrameSent = false;

       if (!m_bInitialized) return false;
       if(frame == NULL) return false;

       static DWORD dwWaitTime = 0;
       static DWORD dwFramesSent = 0;
       static DWORD dwFramesSkipped = 0;
       bool bShowStats = false;

       if (frame->GetSize() > m_nMaxDataSize)
       {
 #ifndef LINUX
             ::OutputDebugString(L"CDataTransferServer::SendData: Data
exceeds available size; data not posted to memory\n");
 #else
             cerr << "CDataTransferServer::SendData: Data exceeds available
size; data not posted to memory" << endl;
 #endif
                return false;
       }
       
       if (CheckPFrameCount(frame) == false)
             return false;

       // Wait for up to 25ms to lock the memory.  That's a little shorter
than 1/30th of a
       // second, which is our fastest video frame rate.
       DWORD dwTimeStart = ::GetTickCount();
       DWORD dwWait = ::WaitForSingleObject(m_hMutexControl, 25);
 #ifndef LINUX
       if (dwWait == WAIT_OBJECT_0 || dwWait == WAIT_ABANDONED)
 #else
         if (dwWait == WAIT_OBJECT_0)
 #endif
       {
             DWORD dwTimeNow = ::GetTickCount();
             dwWaitTime += dwTimeNow - dwTimeStart;
             ++dwFramesSent;
             bShowStats = (dwTimeNow - dwTimeStart != 0);
             unsigned long nBlock, nOffset;
             bool bOkayToSendFrame = true;
             unsigned long nNormalStartBlock = m_nConfigBlocks +
(m_bKeyBlock ? 1 : 0);
             bool bCurrentKeyBlock = false;

             // Wrap this section in try/except to handle exceptions thrown
by memory mapped file access
 #ifndef LINUX
             __try
 #else
                 try
 #endif
             {
                   if (frame->GetType() == CC_SAMPLETYPE_MPEG4_CONFIG ||
frame->GetType() == CC_SAMPLETYPE_MPEG4AVC_CONFIG)
                   {
                         // Configuration data is always in block 0
                         nBlock = 0;
                         nOffset = 0;
                         m_pControl->nConfigurationBlock = nBlock;
                   }
                   else if ((frame->GetType() == CC_SAMPLETYPE_MPEG4_IFRAME
|| frame->GetType() == CC_SAMPLETYPE_MPEG4AVC_IFRAME) && m_bKeyBlock)
                   {
                         // Key data is always in the block after the
configuration block
                         // This block will be overwritten even if somebody
is using it.  We should get
                         // key data infrequently enough so that this won't
be a problem.
                         bCurrentKeyBlock = true;
                         nBlock = m_nConfigBlocks;
                         nOffset = m_nMaxConfigSize + (nBlock -
m_nConfigBlocks) * m_nMaxDataSize;
                         m_pControl->nNewestKeyDataBlock = nBlock;
                         m_pControl->nNewestDataBlock = nBlock;
                         m_pControl->nTimeOfNewestKeyDataBlock = dwTimeNow;
                         m_pControl->nTimeOfNewestDataBlock = dwTimeNow;
                   }
                   else
                   {
                         // Normal data -- get the next block that is not
being read
                         bool bContinue = true;
                         nBlock = m_pControl->nNewestDataBlock;
                         unsigned long nStartBlock = nBlock;

                         do
                         {
                               if (m_pControl->nNewestDataBlock ==
0xffffffff)            // First block?
                               {
                                     nBlock = nNormalStartBlock;
                                     bContinue = false;
                               }
                               else
                               {
                                     ++nBlock;
                                     if (m_bKeyBlock && nBlock <
nNormalStartBlock || nBlock >= m_nMaxFrames + m_nConfigBlocks)
                                           nBlock = nNormalStartBlock;
                               }

                               if
(m_pControl->aBlockHeaders[nBlock].nReaderReferenceCount == 0)
                                     bContinue = false;
                               else
                               {
                                     // This block is being read.  Make sure
that the reader didn't timeout
                                     static const DWORD nReaderTimeout =
30000;
                                     DWORD dwElapsed;
                                     if (dwTimeNow >=
m_pControl->aBlockHeaders[nBlock].nTimeOfLastRead)
                                           dwElapsed = dwTimeNow -
m_pControl->aBlockHeaders[nBlock].nTimeOfLastRead;
                                     else
                                     {
                                           // The time wrapped around back
to 0.
                                           dwElapsed = 0xffffffff -
m_pControl->aBlockHeaders[nBlock].nTimeOfLastRead + dwTimeNow;
                                     }

                                     if (dwElapsed > nReaderTimeout)
                                     {
                                           // Read timed out, so we'll use
this block
 
m_pControl->aBlockHeaders[nBlock].nReaderReferenceCount = 0;
 #ifndef LINUX
 
::OutputDebugString(L"CDataTransferServer: Releasing a block that was locked
for too long.\n");
 #else
                                           cerr << "CDataTransferServer:
Releasing a block that was locked for too long." << endl;
 #endif      
                                     bContinue = false;
                                     }
                               }
                         } while (bContinue && nBlock != nStartBlock);

                         // Did we find a good destination?
                         nOffset = m_nMaxConfigSize + (nBlock -
m_nConfigBlocks) * m_nMaxDataSize;
                         if
(m_pControl->aBlockHeaders[nBlock].nReaderReferenceCount == 0)
                         {
                               m_pControl->nNewestDataBlock = nBlock;
                               m_pControl->nTimeOfNewestDataBlock =
dwTimeNow;
                         }
                         else
                               bOkayToSendFrame = false;
                   }

                   // actual frame sent here
                   if (bOkayToSendFrame)
                   {
                         // Set the frame type into DataTransferControl
                         m_pControl->nSampleType = frame->GetType();
                         m_pControl->nDistanceFromKeyData =
frame->m_nDistanceFromKeyData;
                         // Set the header info for this block
                         //DWORD dwTimeNow = ::GetTickCount();
                         if (m_bKeyBlock)
                         {
                               if ((bCurrentKeyBlock) || (nBlock ==
m_pControl->nConfigurationBlock))
                                     m_nDistanceFromKeyData = 0;
                               else
                                     ++m_nDistanceFromKeyData;
                         }
                         else
                         {      // MJPEG
                               m_nDistanceFromKeyData = 0;
                         }

                         nOffset += m_nControlSize;

 
m_pControl->aBlockHeaders[nBlock].nReaderReferenceCount = 0;
 
m_pControl->aBlockHeaders[nBlock].nDistanceFromKeyData =
m_nDistanceFromKeyData;
 
//m_pControl->aBlockHeaders[nBlock].nDistanceFromKeyData =
frame->m_nDistanceFromKeyData;
                         m_pControl->aBlockHeaders[nBlock].nDataOffset =
nOffset;
                         m_pControl->aBlockHeaders[nBlock].nDataType =
(unsigned long)frame->GetType();
                         m_pControl->aBlockHeaders[nBlock].nDataSize =
sizeof(DWORD) + frame->GetSize();
                         m_pControl->aBlockHeaders[nBlock].nTimeOfWrite =
dwTimeNow;
                         m_pControl->aBlockHeaders[nBlock].nTimeOfLastRead =
dwTimeNow;

                         // Write an offset to the real data -- 4 bytes
                         unsigned long nStartOfDataSize = 4;
                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &nStartOfDataSize, nStartOfDataSize);

                         nOffset += 4;

                         // write frame header
                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_type, sizeof(int)); // we have it header - send it
again anyway
                         nOffset += sizeof(int);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_width, sizeof(int));
                         nOffset += sizeof(int);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_height, sizeof(int));
                         nOffset += sizeof(int);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_dataLength, sizeof(long));
                         nOffset += sizeof(long);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_motionLength, sizeof(long));
                         nOffset += sizeof(long);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_motionWidth, sizeof(long));
                         nOffset += sizeof(long);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_motionHeight, sizeof(long));
                         nOffset += sizeof(long);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_record, sizeof(int));
                         nOffset += sizeof(int);

                         // write trigger
                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_trigger, sizeof(int));
                         nOffset += sizeof(int);

                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, &frame->m_time, sizeof(__int64));
                         nOffset += sizeof(__int64);

                         // write motion block
                         if(frame->m_motionLength > 0)
                         {
                               ::memcpy_s(((unsigned char*)m_pControl) +
nOffset, m_nMaxDataSize, frame->m_motion, frame->m_motionLength);
                               nOffset += frame->m_motionLength;
                         }

                         // write data
                         ::memcpy_s(((unsigned char*)m_pControl) + nOffset,
m_nMaxDataSize, frame->m_data, frame->m_dataLength);
                         nOffset += frame->m_dataLength;

                         // we done

                         bFrameSent = true;
                         m_nLastSendTime = dwTimeNow;
                   }
             }
 #ifndef LINUX
             __except (::GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR ?
                                     EXCEPTION_EXECUTE_HANDLER :
EXCEPTION_CONTINUE_SEARCH)
 #else
                 catch(std::exception& e)
 #endif
             {
                   // Access to memory mapped file caused an exception
             }

             // Updated data is ready for clients
             if (bFrameSent)
                   SetNewDataEvents();
 #ifndef LINUX 
             ::ReleaseMutex(m_hMutexControl);
 #else
                 sem_close(m_hMutexControl);
 #endif
       }
       else
       {
             ++dwFramesSkipped;
             bShowStats = true;
       }

       if (bShowStats)
       {
             wchar_t szMsg[128];
 #ifdef LINUX
             ::swprintf(szMsg, 128, L"DataServer: %d frames sent (wait=%0.2f
ms), %d frames skipped\n", dwFramesSent, dwWaitTime / (double)dwFramesSent,
dwFramesSkipped);
 #else
             ::swprintf_s(szMsg, L"DataServer: %d frames sent (wait=%0.2f
ms), %d frames skipped\n", dwFramesSent, dwWaitTime / (double)dwFramesSent,
dwFramesSkipped);
 #endif
 #ifndef LINUX 
             ::OutputDebugString(szMsg);
 #else
                 cerr << szMsg << endl;
 #endif
       }

       return bFrameSent;
 }

 bool CDataTransferServer::CheckPFrameCount(CVideoFrame *frame)
 {
       if ((frame->GetType() == CC_SAMPLETYPE_MPEG4_PFRAME) ||
(frame->GetType() == CC_SAMPLETYPE_MPEG4AVC_PFRAME))
       {
             if (frame->m_nDistanceFromKeyData > (m_nMaxFrames - 2))
// 2 = IFrame + Config Block
             {      // We received more P frames than we are expecting, 
 #ifndef LINUX
                   ::OutputDebugString(L"CDataTransferServer::SendData:
received more P frames than expected, ignoring the frames\n");
 #else
                   cerr << "CDataTransferServer::SendData: received more P
frames than expected, ignoring the frames" << endl;
 #endif 
                   m_nPFramesIgnored ++;

                   //DWORD dwNow = ::GetTickCount();
                   //if(dwNow - m_nLastErrorLoggedIgnoreFrames > 1000*60*60)
// don't log too often - once in hour
                   //{
                   //      m_nLastErrorLoggedIgnoreFrames = dwNow;

                   //      try
                   //      {
                   //            CLogFile* pLogFile = new
CLogFile(L"SmartCamXi_NVR_Recorder.log", TRUE);
                   //            if(pLogFile != NULL)
                   //            {
                   //                  TCHAR tmp[MAX_PATH];
                   //                  _stprintf(tmp, L"Ignoring P Frames -
I Frame Interval is not set correctly - CameraControlLib: Camera ID: %d,
Expected I Frame Interval: %d \n", m_nCameraID, m_nMaxFrames - 2);
                   //                  pLogFile->Write(tmp);
                   //                  delete pLogFile;
                   //            }
                   //      }
                   //      catch (...)
                   //      {
                   //      }

                   //      m_nPFramesIgnored = 0;
                   //}
                   return false;
             }
       }

       return true;
 }

 
//==========================================================================
======================
 void CDataTransferServer::SetNewDataEvents()
 {
       DWORD dwNow = ::GetTickCount();
       unsigned int nRemoveThisID = 0xffffffff;
 #ifndef LINUX
       ::EnterCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_lock(&m_lockEvents);
 #endif
       CUserEventMap::iterator itEvent = m_mapUserEvents.begin();
       while (itEvent != m_mapUserEvents.end())
       {
             // Check to see if the previous event has been consumed
             if (::WaitForSingleObject(itEvent->second.hEvent, 0) ==
WAIT_OBJECT_0)
             {
                   // It hasn't -- make sure it hasn't been inactive for too
long
                   DWORD dwElapsed;
                   if (itEvent->second.nLastEventConsumedTime == 0)
                   {
                         // This event hasn't been set yet, so don't try to
check the time
                         dwElapsed = 0;
                   }
                   else if (dwNow >= itEvent->second.nLastEventConsumedTime)
                         dwElapsed = dwNow -
itEvent->second.nLastEventConsumedTime;
                   else
                   {
                         // The time wrapped around back to 0.
                         dwElapsed = 0xffffffff -
itEvent->second.nLastEventConsumedTime + dwNow;
                   }

                   if (dwElapsed > 300000)            // 5 minute timeout
                         nRemoveThisID = itEvent->first;
             }
             else
                   itEvent->second.nLastEventConsumedTime = dwNow;

             ::SetEvent(itEvent->second.hEvent);
             ++itEvent;
       }

       // Remove one user if the event has timed out.  This will only remove
one user each
       // time in this function, but this is called frequently.
       if (nRemoveThisID != 0xffffffff)
             RemoveUser(nRemoveThisID);
 #ifndef LINUX
       ::LeaveCriticalSection(&m_lockEvents);
 #else
         pthread_mutex_lock(&m_lockEvents);
 #endif

 }





 extern "C" 
 {
 int func()  /* THIS IS WHERE THE PROBLEM IS */
 {
    wchar_t memoryName[256];
    wchar_t mutexName[256];
    wchar_t eventName[256];
    mbstowcs(memoryName, "MemoryName", 256);
    mbstowcs(mutexName, "MutexName", 256);
    mbstowcs(eventName, "EventName", 256);
    std::wstring memoryString(memoryName);
    std::wstring mutexString(mutexName);
    std::wstring eventString(eventName);
    CDataTransferServer *srv = new CDataTransferServer();
    srv->Initialize(1, CC_SAMPLETYPE_MPEG4,128,256,64);
    printf("Inside entry point tester 1\n");
    srv->AddUser(5, memoryString, mutexString, eventString);
    printf("Inside entry point tester 2\n");
    delete srv;
    printf("Exiting entry point tester \n");

        /* THIS IS WHERE THE PROBLEM IS */
             
 }
 } 


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

Back to comp.lang.c++.moderated | Previous | NextNext in thread | Find similar


Thread

Why does the  following  C++  program , DataServer.cpp, throws  a  segmentation fault at the exit of  the extern "C" function,  void func(void)  shown in the bottom of this question? allswellthatendswell <FrankChang91@googlemail.com> - 2016-01-04 06:55 -0600
  Re: Why does the following C++ program , DataServer.cpp, throws a  segmentation fault at the exit of the extern "C" function, void func(void)  shown in the bottom of this question? Francis Glassborow <francis.glassborow@btinternet.com> - 2016-01-04 10:08 -0600
  Re: Why does the following C++ program , DataServer.cpp, throws a  segmentation fault at the exit of the extern "C" function, void func(void)  shown in the bottom of this question? Jerry Stuckle <jstucklex@attglobal.net> - 2016-01-04 11:22 -0600
  Re: Why does the  following  C++  program , DataServer.cpp, throws a   segmentation fault at the exit of  the extern "C" function,  void func(void)   shown in the bottom of this question? marlow.agents@googlemail.com - 2016-01-12 07:22 -0600

csiph-web