CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16
  1. #1
    Join Date
    Jul 2003
    Posts
    79

    AfxBeginThread throws exception

    The Document in my SDI application owns an object that takes care of some seriall communication the class is called CSerComm.

    In Document .h file
    CSerComm m_SerCommObj;

    Since the worker thread should be created at start up a function in the Document is called in InitInstance which will create the thread. The Document function is called StartThread()

    In InitInstance function
    Code:
    //Get Document pointer
    POSITION pos = this->GetFirstDocTemplatePosition();
    CGsdoc_b1Doc* pDoc = (CGsdoc_b1Doc*)this->GetNextDocTemplate(pos);
    //Open the document
    if(!((CDocTemplate*)pDocTemplate)->OpenDocumentFile(docFile))
    {
      pDoc->OnSaveDocument(docFile);
      pDoc->OnOpenDocument(docFile);
    }//create file if application run first time
    
    m_pMainWnd->ShowWindow(SW_SHOW);
    m_pMainWnd->UpdateWindow();
    
    // Enable drag/drop open
    m_pMainWnd->DragAcceptFiles();
    //Signal to Document to create the thread
    pDoc->StartThread();
    In StartThread a CSerComm function is called that the StartThread
    Code:
    m_SerCommObj.CreateThread(); //start communication
    
    In CreateThread() function AfxBeginThread is called
    
    m_pThread = AfxBeginThread(ThreadFunc, this);
    But an exception is thrown when AfxBeginThread is called.
    Why is that?

    It works better if I let the Application class own the CSerrComm object or if the m_SerCommObj.CreateThread() is called in the OnNewDocument function in the Document. But this does'nt suite other requierments.


    [Andreas]: Added code tags...
    Last edited by Andreas Masur; March 6th, 2004 at 05:29 AM.

  2. #2
    Join Date
    Sep 2002
    Location
    Maryland - Fear The Turtle!
    Posts
    7,537
    which exception? run your code under a debugger...

  3. #3
    Join Date
    Nov 2003
    Posts
    2,185
    the function you call... is it declared as the following:
    at your .h
    Code:
    static UINT Function(LPVOID parameter);
    at your .ccp
    Code:
    UINT CDlg::Function(LPVOID parameter)
    {
           return 1;
    }

  4. #4
    Join Date
    Feb 2002
    Posts
    5,757
    Interesting.

    First call GetLastError(). Post the interface of the thread's callback function.

    Kuphryn

  5. #5
    Join Date
    Jul 2003
    Posts
    79
    Ok here comes the the thread controlling function. After that the StartThread function.
    Code:
    //Thread controlling function implementation
    //Seriall communication read/write is done in this function
    UINT CSerComm :: ThreadFunc(LPVOID pvParam)
    {	
       COMMTIMEOUTS myCommTimeouts;
       int addr = 1;
       DCB my_dcb = {0};
       HANDLE Port;
       DWORD error;
       POSITION appPos, docPos;
       int comPort = 0;
       CString comStr = "Com1";
       MSG msg;
       CWinApp* theApp;
       CDocTemplate* docTemplate;
       CGsdoc_b1Doc* pDoc;
       bool portSetFlag = false;
       CString strWrite;
       int i = 0;
       int grytAdresser[110]; //Innehåller adresser (ID) till grytorna 
    
       for(i=0; i<110; i++)
       {
    	grytAdresser[i] = 0;
       }//Initiera gytadress vektorn till 0 
    
       while(1)
       {    
                 if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ))
                 {
    		if( msg.message == UM_SET_PORT)
    		{
    		            //Set port settings			                            theApp = AfxGetApp(); 
    		            appPos = theApp-                                            >GetFirstDocTemplatePosition();
    	                           error = GetLastError();
    	                           docTemplate = theApp-                                           >GetNextDocTemplate(appPos);
    	                           docPos = docTemplate-                                           >GetFirstDocPosition();
    	                           pDoc = (CGsdoc_b1Doc*)docTemplate-                                           >GetNextDoc(docPos);
    	                           comPort = pDoc->GetComPort();
    				
    		           if(portSetFlag == true)
    			CloseHandle(Port);
                                                    //If same com port is picked by user
                                      comStr.Format("%s%d", "Com", comPort); 	
                                     Port = CreateFile(comStr,
    	                 GENERIC_READ | GENERIC_WRITE,
                                              0, 		   '\0',
                                     OPEN_EXISTING,	   0,
    				   '\0');
    
    		 portSetFlag = true;
    
                	                 if(Port == INVALID_HANDLE_VALUE)
    		{
            		    AfxMessageBox("Could not create port");
    		    return 1;
    		} // error opening port; abort
    
                	                if(!GetCommState(Port, &my_dcb))
    		{
            		   AfxMessageBox("Didn't Get DCB");
    	        	   error = GetLastError();
    	                   //error getting comm state
    		}
    
                                   my_dcb.BaudRate = CBR_9600;
                                   my_dcb.fParity = 0;
                                   my_dcb.fOutxCtsFlow = false;
                                   my_dcb.fOutxDsrFlow = false;
                                   my_dcb.fDtrControl = DTR_CONTROL_DISABLE;
                                   my_dcb.fDsrSensitivity = false;
                                   my_dcb.fOutX = false;
                                   my_dcb.fInX = false;
                                   my_dcb.fRtsControl = RTS_CONTROL_DISABLE;
                                   my_dcb.ByteSize = 8;
                                   my_dcb.Parity = NOPARITY;
                                   my_dcb.StopBits = ONESTOPBIT;
                 	    //Set timeout structure
                	    myCommTimeouts.ReadIntervalTimeout = 0;
                        myCommTimeouts.ReadTotalTimeoutMultiplier  = 0;
                        myCommTimeouts.ReadTotalTimeoutConstant = 500; 
                        myCommTimeouts.WriteTotalTimeoutMultiplier = 0;
                        myCommTimeouts.WriteTotalTimeoutConstant = 0;
    
                	     if(!SetCommTimeouts(Port, &myCommTimeouts))
                 		AfxMessageBox("failed to set Com timeout");
    
                         if(!SetCommState(Port, &my_dcb))
    	    {
                           AfxMessageBox("Failed to set up Com port");
                           error = GetLastError();
                           return(0);
    	    }
    				
    	}//Set port
    	else if(msg.message == UM_FINISH_THREAD)
    	{
    	    ExitThread(1);
    	}//Exit thread
    	else if(msg.message == UM_POT_ADDED)
    	{
    	  theApp = AfxGetApp(); 
    	  appPos = theApp->GetFirstDocTemplatePosition();
    	  error = GetLastError();
                     docTemplate = theApp->GetNextDocTemplate(appPos);
    	  docPos = docTemplate->GetFirstDocPosition();
              pDoc=(CGsdoc_b1Doc*)docTemplate->GetNextDoc(docPos);
    	
                       for(i=0; i<(pDoc->m_PotKeyArr.GetSize()); i++)
    	  {
    	    grytAdresser[i] = pDoc->m_PotKeyArr[i];
    	  }
                    } 
    	
    	else if(msg.message == UM_SEND)
    	{
    	   addr = 1;
    	   StartJadekCom(Port, addr, ComReadTempLogg);
    	   strWrite.Format("%s%d", "Meddelande av ", addr);
                       AfxMessageBox(strWrite);
    
    	   /* JADEK har ändrat */
    	   GetJadekCom(Port, addr, ComReadTempLogg);
    	   if(TempLogg.ComStatus == 0 ){
    	      StartJadekCom(Port, addr, ComReadTempLogg);
    	      strWrite = "Ack skickad!";
    	      AfxMessageBox(strWrite);
    	   } 
                       else {
    	     switch( TempLogg.ComStatus ){
    	     case ComErrStartBit:
    	     strWrite.Format("%s", "Error: Startbit");
    	     break;
    	     case ComErrAdress:
    	     strWrite.Format("%s", "Error: Adress");
    	     break;
    	     case ComErrMedTyp:
    	     strWrite.Format("%s", "Error: Meddelandetyp");
    	     break;
    	     case ComErrCheckSum:
    	     strWrite.Format("%s", "Error: Checksumma");
    	     break;
    	     default:
    	     strWrite.Format("%s", "Error: Okänd" );
    	     break;
    	   }
    	   AfxMessageBox(strWrite);
    	}
    
        	::Sleep(10);
    	}
    
                  }
    
    AfxMessageBox("return 0");
    return 0;
    }
    The StartHandler declaration in the Document .h file
    Code:
    void StartThread();
    StartHandler in the Document .cpp file
    Code:
    void CGsdoc_b1Doc::StartThread()
    {	
    	m_SerCommObj.CreateThread(); //start communication
    	//Set port message
    	::PostThreadMessage(m_SerCommObj.GetThreadId(),   UM_SET_PORT, 0, 0);
    }
    Sorry for the poor indention I hope it's readable.



    [Andreas]: Added code tags...
    Last edited by Andreas Masur; March 6th, 2004 at 05:29 AM.

  6. #6
    Join Date
    Jul 2003
    Posts
    79
    By the way ThreadFunc is declared
    static UINT

  7. #7
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    You did not answer the question "which exception". The original post of this thread should have specified what the exception is; just saying "an exception is thrown" is inadequate. The question is probably meaningless without specifying the exception and what line of your source code gets the exception.

    Please use the code tags for your source code. It is very easy to do. Also, when using the code tags, ensure that the lines are not too wide; you can split lines one way or another to make them not too wide.

    I think I see the problem but if I do then you would also see the problem if you simply look at the call stack when the exception occurs.
    "Signature":
    My web site is Simple Samples.
    C# Corner Editor

  8. #8
    Join Date
    Jul 2003
    Posts
    79
    The dialog box that pops up saya that I don't handle the exception and that it is an
    "Access violation"
    exception.

    I don't know how to look at the call stack.

  9. #9
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    You must know how to look at the call stack. It is a critical debugging tool. So when you get the dialog box saying you have an exception, click the button to debug. Then in the menus select "View | Debug Windows | Call Stack". The Call Stack will then be shown. In the call stack there is one line for each function called. The top line is the function called most recently and is where the exception occured. However it is usually in MFC code or Windows code that the error occurs. So we need to go down to the topmost line for a fuction in our code. That is the line in our program that is getting the error. Often the problem is obvious as soon as we see the line in our program that is getting a problem.
    "Signature":
    My web site is Simple Samples.
    C# Corner Editor

  10. #10
    Join Date
    Jul 2003
    Posts
    79
    Thanks for helping me out here.
    In the call stack I see

    CSerComm::CreateThread() line 78 + 28 bytes
    CGsdoc_b1Doc::StartThread() line 609
    CGsdoc_b1App::InitInstance() line 156
    AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001327b2, int 1) line 39 + 11 bytes
    WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x001327b2, int 1) line 30
    WinMainCRTStartup() line 330 + 54 bytes
    KERNEL32! 7c5987e7()

    So the error occured in the CSerComm::CreateThread() on line 78. This where AfxBeginThread is called.

    CreateThread looks like

    bool CSerComm :: CreateThread()
    {
    CWnd* p_wnd = AfxGetMainWnd();
    m_pThread = AfxBeginThread(ThreadFunc, this);

    if(!m_pThread)
    {
    // Could not create thread
    return false;
    }
    m_pThread->m_bAutoDelete = true;
    m_ThreadID = m_pThread->m_nThreadID;
    return true;
    }

  11. #11
    Join Date
    Sep 2002
    Location
    14° 39'19.65"N / 121° 1'44.34"E
    Posts
    9,815
    Originally posted by Sam Hobbs
    Please use the code tags for your source code. It is very easy to do.

  12. #12
    Join Date
    May 1999
    Location
    Southern California
    Posts
    12,266
    I forgot to mention that if you double-click on a lin in the call stack, you will be shown the source code line corresponding to that line.

    I don't know why the AfxBeginThread function would get an exception.

    Note that in CSerComm :: ThreadFunc the variable theApp is used without being initialized. It is set later, but not initially. That is nearly guranteed to be an error, but I assume it would show in the call stack. I assume the debugger would show the call stack for the thread, but perhaps there is something more that needs to be done when debugging threads.

    You can put a breakpoint at the beginning of CSerComm :: ThreadFunc to see if it is executed. If you reach the breakpoint then you know the problem is nearly certainly the uninitialized theApp. You can single-step to see if execution does in fact get to the first line that uses theApp. You can do all this without recompiling. It would be a useful way to learn about debugging.

    Also, you can edit your previous posts and add &#091;Code&#093; and &#091;/Code&#093; tags.
    "Signature":
    My web site is Simple Samples.
    C# Corner Editor

  13. #13
    Join Date
    Sep 2002
    Location
    Maryland - Fear The Turtle!
    Posts
    7,537
    No you'll get the thread context/stack in the stack view (well most debuggers if not all will show it) the IDE (along with others) you can switch to threads and view the stack of the current thread. You should easily be able to tell which * is causing the problem by just clicking on the line in the stack trace.

  14. #14
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    [Moved thread]

  15. #15
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652
    Originally posted by martenbengtsson
    The dialog box that pops up saya that I don't handle the exception and that it is an
    "Access violation"
    exception.
    Well...an access violation is different from a thrown exception...it looks like you are trying to access any window etc. from your thread before it is created...

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured