From: neilsolent on 16 Sep 2009 03:54 My app is crashing with the following pop-up in a certain situation: Socket Notification Sink Blah blah write at 0x00000004 Unhandled exception MFCN42D.DLL 0xc0000005 (access violation) The app listens on a TCP port using instances of a CAsyncSocket- derived class. When a connection is accepted but later rejected (if SSL handshake failed for example) the socket is closed. After this point, the listening loop is posted a message which seems to lead to the crash: MSG msg; while (GetMessage(&msg, NULL, 0, 0) == TRUE) { LOGWARN "Received msg: [message=%u, hwnd=%d, wParam=%u, lParam=%u, x=%u, y=%u]", msg.message, msg.hwnd, msg.wParam, msg.lParam, msg.pt.x, msg.pt.y); .. .. TranslateMessage(&msg); DispatchMessage(&msg); // <- Line 2688 } The last message received before the crash is logged as: Received msg: [message=883, hwnd=2556196, wParam=524, lParam=32, x=869, y=828] The stack backtrace shows: MFCN42D! 5f6052b8() MFCN42D! 5f605ab6() MFCN42D! 5f60633f() MFC42D! 5f43177c() MFC42D! 5f4310b8() MFC42D! 5f42ec09() MFC42D! 5f42f0f5() MFC42D! 5f49265d() USER32! 7739c3b7() USER32! 7739c484() USER32! 7739c73c() USER32! 7738e406() _tcomx(void * 0x001d011a) line 2688 + 12 bytes KERNEL32! 77e66063() I don't *know* what message 883 (0x0373) is - I have not posted it myself, and it is not mentioned in any header files I can find. I *assume* it is how the callbacks like CAsyncSocket::OnReceive() are implemented. Hence - the crash is probably because I am processing a callback on a socket that has already been deleted. Question is - how can I fix the code? I assume the callback messages were already in the queue before I deleted the socket.. I could do some lookup using the wParam member of the MSG (which seems to match the socket handle) - seems a bit messy though. Hopefully someone has already got round this in a neater way ..
From: Stephen Myers on 16 Sep 2009 13:46 neilsolent wrote: > My app is crashing with the following pop-up in a certain situation: > > Socket Notification Sink > Blah blah write at 0x00000004 > Unhandled exception MFCN42D.DLL 0xc0000005 (access violation) > > The app listens on a TCP port using instances of a CAsyncSocket- > derived class. When a connection is accepted > but later rejected (if SSL handshake failed for example) the socket is > closed. After this point, the listening > loop is posted a message which seems to lead to the crash: > > MSG msg; > while (GetMessage(&msg, NULL, 0, 0) == TRUE) > { > LOGWARN "Received msg: [message=%u, hwnd=%d, wParam=%u, lParam=%u, > x=%u, y=%u]", > msg.message, msg.hwnd, msg.wParam, msg.lParam, msg.pt.x, > msg.pt.y); > .. > .. > > TranslateMessage(&msg); > DispatchMessage(&msg); // <- Line 2688 > } > > The last message received before the crash is logged as: > > Received msg: [message=883, hwnd=2556196, wParam=524, lParam=32, > x=869, y=828] > > The stack backtrace shows: > > MFCN42D! 5f6052b8() > MFCN42D! 5f605ab6() > MFCN42D! 5f60633f() > MFC42D! 5f43177c() > MFC42D! 5f4310b8() > MFC42D! 5f42ec09() > MFC42D! 5f42f0f5() > MFC42D! 5f49265d() > USER32! 7739c3b7() > USER32! 7739c484() > USER32! 7739c73c() > USER32! 7738e406() > _tcomx(void * 0x001d011a) line 2688 + 12 bytes > KERNEL32! 77e66063() > > I don't *know* what message 883 (0x0373) is - I have not posted it > myself, and it is not mentioned in any header files I can find. I > *assume* it is how the callbacks like CAsyncSocket::OnReceive() are > implemented. > Hence - the crash is probably because I am processing a callback on a > socket that has already been deleted. Question is - how can I fix the > code? I assume the callback messages were already in the queue before > I deleted the socket.. > I could do some lookup using the wParam member of the MSG (which seems > to match the socket handle) - seems a bit messy though. Hopefully > someone has already got round this in a neater way .. You are correct, 0x373 is a private message used by the MFC socket handling. wParam indicates the socket and lParam is a bit mask indicating the cause (Read, Accept, Close etc). FD_CLOSE is the message, so handling OnClose before deletion should do it. Steve
From: neilsolent on 17 Sep 2009 04:08 > You are correct, 0x373 is a private message used by the MFC socket > handling. wParam indicates the socket and lParam is a bit mask > indicating the cause (Read, Accept, Close etc). FD_CLOSE is the > message, so handling OnClose before deletion should do it. Thanks for the info. In my case I can't rely on OnClose() arriving. Sometimes I want to delete a socket for some other reason than Windows telling me to! I have got this working now - these are my tips to avoid this problem: 1. First call AsyncSelect(0) on any CAsyncSocket that is to be deleted. This quiesces it (prevents any more callbacks being queued). 2. Right after the AsyncSelect(0), post a message to the queue of the thread that owns the socket, instructing it to delete the socket. This will ensure that no callback messages are received after the socket has been deleted. 3. (Obviously) add code to handle the DELETE_SOCKET message you posted 4. Do not call Close() on any socket before the CAsyncSocket destructor is called - to ensure the handle is not reused before the old CAsyncSocket has been destroyed.
From: Joseph M. Newcomer on 20 Sep 2009 12:54 See below... On Wed, 16 Sep 2009 00:54:51 -0700 (PDT), neilsolent <n(a)solenttechnology.co.uk> wrote: >My app is crashing with the following pop-up in a certain situation: > >Socket Notification Sink >Blah blah write at 0x00000004 >Unhandled exception MFCN42D.DLL 0xc0000005 (access violation) **** This is probably caused by the fact that you have received a notification after managing to get a slock deleted from the handle map. ***** > >The app listens on a TCP port using instances of a CAsyncSocket- >derived class. When a connection is accepted >but later rejected (if SSL handshake failed for example) the socket is >closed. After this point, the listening >loop is posted a message which seems to lead to the crash: **** Sounds about right. Where, exactly is this code? I cannot find these lines anywhere in the MFC runtime. I specifically looked in the VS98 MFC source directory and could not find them. Note that if this is your code, then your code is erroneous, because it should not have anything like this in it. You say it is line 2688. I am having an error line 207 in my code, what's wrong with it? Sorry, but a line number without a file name is pretty useless, particularly when the code is not part of the MFC library. ***** > > MSG msg; > while (GetMessage(&msg, NULL, 0, 0) == TRUE) > { > LOGWARN "Received msg: [message=%u, hwnd=%d, wParam=%u, lParam=%u, >x=%u, y=%u]", > msg.message, msg.hwnd, msg.wParam, msg.lParam, msg.pt.x, >msg.pt.y); > .. > .. > > TranslateMessage(&msg); > DispatchMessage(&msg); // <- Line 2688 > } > >The last message received before the crash is logged as: > >Received msg: [message=883, hwnd=2556196, wParam=524, lParam=32, >x=869, y=828] > >The stack backtrace shows: > >MFCN42D! 5f6052b8() >MFCN42D! 5f605ab6() >MFCN42D! 5f60633f() >MFC42D! 5f43177c() >MFC42D! 5f4310b8() >MFC42D! 5f42ec09() >MFC42D! 5f42f0f5() >MFC42D! 5f49265d() >USER32! 7739c3b7() >USER32! 7739c484() >USER32! 7739c73c() >USER32! 7738e406() >_tcomx(void * 0x001d011a) line 2688 + 12 bytes >KERNEL32! 77e66063() > >I don't *know* what message 883 (0x0373) is - I have not posted it >myself, and it is not mentioned in any header files I can find. I >*assume* it is how the callbacks like CAsyncSocket::OnReceive() are >implemented. >Hence - the crash is probably because I am processing a callback on a >socket that has already been deleted. Question is - how can I fix the >code? I assume the callback messages were already in the queue before >I deleted the socket.. >I could do some lookup using the wParam member of the MSG (which seems >to match the socket handle) - seems a bit messy though. Hopefully >someone has already got round this in a neater way .. Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: neilsolent on 21 Sep 2009 09:35
> Sounds about right. Where, exactly is this code? I cannot find these lines anywhere in > the MFC runtime. I specifically looked in the VS98 MFC source directory and could not > find them. Joseph, The code was in the first post, line 2688 was clearly marked: MSG msg; while (GetMessage(&msg, NULL, 0, 0) == TRUE) { LOGWARN "Received msg: [message=%u, hwnd=%d, wParam=%u, lParam=%u, x=%u, y=%u]", msg.message, msg.hwnd, msg.wParam, msg.lParam, msg.pt.x, msg.pt.y); .. .. TranslateMessage(&msg); DispatchMessage(&msg); // <- Line 2688 } ... hence the last call from my code is DispatchMessage() - after that the code is in Microsoft's libraries. > Note that if this is your code, then your code is erroneous, because it should not have > anything like this in it. Shouldn't have anything like what in it? Are you saying I shouldn't use DispatchMessage()? Why not, and how else do the MFC callbacks get processed ? |