f



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?

{ 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! ]

0
allswellthatendswell
1/4/2016 6:55:58 AM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

3 Replies
567 Views

Similar Articles

[PageSpeed] 35

On 04/01/2016 12:55, allswellthatendswell wrote:
> { 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.
>

Well I note two things in the extern "c" function

1) Its return type is NOT void
2) There is no return type


If you expect others to wade through your code looking for causes you 
need first to provide code as specified.

Finally as you appear to be using a g++ extension you might get a more 
informed answer in a g++ forum

Francis


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

0
Francis
1/4/2016 10:08:40 AM
On 1/4/2016 7:55 AM, allswellthatendswell wrote:
> { 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

<snip code>

Normally a segfault on a function return means the stack has been
overwritten and the return address is bad.  It could be anything from a
buffer overrun to insufficient stack size (shouldn't be a problem
nowadays, but I don't know what you've allocated from the stack before
arriving here).  Looking through your code I don't see anything that
jumps out at me, but you've left out a lot of information.

Which compiler are you using?  What compiler options?  Do you have any
errors or warnings?

You didn't provide a compilable example (or even the header files), so
it's impossible for others to test.  All I can recommend is to comment
out all of the code in func() and try uncommenting a couple of lines at
a time until you get the error.

-- 
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================


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

0
Jerry
1/4/2016 11:22:41 AM
On Monday, January 4, 2016 at 1:00:18 PM UTC, allswellthatendswell wrote:
> 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.

Use valgrind.


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

0
marlow
1/12/2016 7:22:22 AM
Reply:

Similar Artilces:

ascii ?c "c"[0] "c".ord.chr question
I was curious why the prefix ? for ascii code was removed in 1.9.x? ~ On Dec 3, 2010, at 12:39 , Stu wrote: > I was curious why the prefix ? for ascii code was removed in 1.9.x? It wasn't removed, it just changed what it returns to work with = multibyte chars: > multiruby -e 'p ?c' >=20 > VERSION =3D 1.8.6-p399 > CMD =3D ~/.multiruby/install/1.8.6-p399/bin/ruby -e p ?c >=20 > 99 >=20 > RESULT =3D 0 >=20 > VERSION =3D 1.8.7-p302 > CMD =3D ~/.multiruby/install/1.8.7-p302/bin/ruby -e p ?c >=20 > 99 >=...

"exceptional c++", "c++ template programming"
Hello, I am looking for an example of a constructor, I think, which took the type itself for integral or floating types, and a const-ref for a user-defined non primitive type. I saw this in one of these books but I can't find it now: "Exceptional C++" "Exceptional C++ Style" "C++ template programming MPL" if anyone remembers this passage for these books? I found it. It was the MPL book, right before 4.1.2 "Hicham Mouline" <hicham@mouline.org> wrote in message news:49228a87$0$90275$14726298@news.sunsite.dk... > Hello, > I am loo...

What does "Standard C", "K&R C" , "ANSI C" mean?
I am just wondering what the following terms usually mean: 1) "Standard C" 2) "K&R C" 3) "ANSI C" I am pretty sure "ANSI C" usually refers to the C89 standard, but what about the other two? What is the "saying" for C99 standard? Thank you On 17 Jan 2005 21:26:42 -0800, "Luke Wu" <LookSkywalker@gmail.com> wrote in comp.lang.c: > I am just wondering what the following terms usually mean: > > 1) "Standard C" The current version of the C language standard. This is now known as "ISO/IEC 9899:19...

["a", "b", "c", "d"] to "a, b, c, d"?
I want to process each element of an array, but the last element should be handled special. Here is an example: def p_ary(ary) str = "" ary.each do |elem| str << elem << ", " end str.chomp!(", ") str end so p_ary(["a", "f", "x", "test"]) produces "a, f, x, test". The code works, but isn't there an easier and more general way for this behaviour? martinus On Tue, 06 Apr 2004 04:23:22 -0700, Martin wrote: > I want to process each element of an array, but the last ele...

extern "c" from c++ header files referenced in c files
Hi, I have a mixed c/c++ program, where there are a few .c files where I want to hook to .h files of .cpp files. For example, I have application.c which references an .h file for a ..cpp file (pingpong.h and pingpong.cpp) I've tried to declare c++ style features in my pingpong.h file but it seems that the pingpong.h file keeps on being read as a "C" file. in application.c #include "pingpong.h" in pingpong.h extern "C" { #include <iostream> using namespace std; typedef struct struct_app_pingping { int connectionId; etc.. .... } /*end of extern ...

"C" Callbacks: Static method vs. extern "C"
Hi. I need to write a C++ callback function and register it with a C program. I've read that this can be done if the callback function is a static method. I've also read that I should use a global function with the extern "C" prefix. I was leaning toward using the static method approach until I saw a posting that said compatibility between static C++ functions and C is not guaranteed in the respective language standards. This made me start to favor the extern C approach. Any thoughts? Thanks! Ken kk_oop@yahoo.com wrote: > Hi. I need to write a C++ callback funct...

Is C# really "better" than C++ or C++0x? How about objective-C?
Microsoft thinks C++ is obsolete and C# is "the future". Apple thinks the same for Objective-C. IMO this is all nonsense. What do you think about this? How "better" really they are? And what about C++0x? On Sun, 17 Apr 2011 16:58:37 +0200, "A" <a@a.a> wrote: >Microsoft thinks C++ is obsolete and C# is "the future". Apple thinks the >same for Objective-C. > >IMO this is all nonsense. I agree. > >What do you think about this? How "better" really they are? And what about >C++0x? > Companies like Microsoft ...

ActiveState vs. "C:\Program Files\" and "C:\Progra~1\"
note: this post started off as a question, but turned into a blog and eventually became an answer. I just hate to have anyone else go through all this nonsense, so I figured I'd post it as an example of "when in doubt, google it out". I successfully installed ActiveState 5.8.8 (after uninstalling 5.6.something) on an XP laptop. I installed it to "C:\Program FIles \Activestate.com\Perl". After the install, I changed the "Program files" part of the ActiveState dirs in my PATH env var from long DOS format to 8.3 format: "C:\Program Files\ActiveState.c...

extern "C" and C++ files
These are the "restrictions" I have come accross when "wrapping up" all function declarations in a header with extern "C": i). Inability to overload functions in exposed API ii). Inability to include (template?) classes (e.g. string) in exposed API Are there other ex/implicit restrictions I may have missed ? Gray Alien wrote: > These are the "restrictions" I have come accross when "wrapping up" all > function declarations in a header with extern "C": > > i). Inability to overload functions in exposed API > ii). In...

Forte C++ and extern "C"
I'm not sure why I'm running into this, I've done it a number of times before. I'm trying to compile a shared library that will be dynamically loaded with dlopen(). The library implements a C++ class which is accessed by means of a factory function declared extern "C". The compiler is exiting with the error "Linkage specifications are allowed only at file level." In a small test program, the line referenced is extern "C" Test *makeTest() {return new Test;} The only thing above this is a line including Test.h which declares the class. I'v...

new URL("c:/dir/file") OR new URL("c:\dir\file") OR new URL("file://c:/dir/file")
new URL("c:/dir/file") OR new URL("c:\dir\file") OR new URL("file://c:/dir/file") What is the correct syntax ? Is it the same as a new File ?FileDialog send: "c:\Program Files\dir\file". I have the feeling that different classes (File, URL, URl) have the different syntax. Please say a), b) or c) and answer me does it is same for all java classes which ask for a file path? FreeStyler =E3=81=AE=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8: > new URL("c:/dir/file") OR new URL("c:\dir\file") OR new > URL("file://c:/dir/fil...

What is the difference between "Borland C++" and "Turbo C++"?
...

"Memory as a Programming Concept in C and C++"
I have just found a very interesting book: "Memory as a Programming Concept in C and C++" Frantisek Franek 2004 >http://www.amazon.com/exec/obidos/tg/detail/-/0521520436/qid=1102475743/sr=1-1/ref=sr_1_1/104-6753470-7335150?v=glance&s=books In switching some code from Java to C++ for efficiency considerations -- the main challenge is in moving from a garbage collector to your own memory management! Every mixed language/C++ programmer worth his/her pepper, should get this book! It's nothing to Sneeze At! -- Regards, Casey ...

"Memory as a Programming Concept in C and C++"
I have just found a very interesting book: "Memory as a Programming Concept in C and C++" Frantisek Franek 2004 >http://www.amazon.com/exec/obidos/tg/detail/-/0521520436/qid=1102475743/sr=1-1/ref=sr_1_1/104-6753470-7335150?v=glance&s=books In switching some code from Java to C++ for efficiency considerations -- the main challenge is in moving from a garbage collector to your own memory management! Every C++ programmer worth his/her pepper, should get this book! It's nothing to Sneeze At! -- Regards, Casey [ See http://www.gotw.ca/resources/clcm.htm for info ...

Web resources about - 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? - comp.lang.c++.moderated

Resources last updated: 1/24/2016 7:27:27 PM