From: neilsolent on
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
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

> 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
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

> 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 ?