Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / May 2006

Tip: Looking for answers? Try searching our database.

"invalid handle", sockets, threads and garbage collector

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jan Waga - 31 Mar 2006 14:03 GMT
Hello,

I'm working on two bugs in my app. They seemed unrelated at first glance,
but after some testing and searching the web for clues I am now sure they
are somehow connected. The two pieces of code execute frequently, at regular
intervals (this is a monitoring app) and sometimes - just sometimes, and I
do mean seldom:) - exceptions are thrown.

1. Invalid handle problem

I have a typical unmanaged resource wrapper class which handles serial
communication. I use p/invoke calls Create~ Read~ and WriteFile, I store
handle to port in IntPtr member. It has destructor which closes the handle.
It is disposable. Nothing out of ordinary. I check handles and status codes
returned from those calls and when something goes wrong, I throw my
exception with errcode from GetLastError() and formatted system error
message. Typical.

The code looks a bit like this:

using (MyPInvokeSerialPort p = new MyPInvokeSerialPort))
{
string s1 = p.Read(); // sometimes ex thrown here
p.Write("sth"); // ...sometimes here
string s2 = p.Read(); // ...and here

// like i've said in most cases ex is not thrown at all
}

The exception contains "invalid handle" message.

2. Socket constructor problem

In this case it's all NET. I sometimes ping somebody:)

using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.Icmp))
{
// the exception is thrown in constructor!
s.WhateverFunc1();
s.WhateverFunc2();
}

The exception contains: "Socket operation on nonsocket"... which, I think,
is socket's way of saying "invalid handle" :) I've read that Net.Sockets are
mostly implemented by p/invoke over winsock2. These are two reasons I think
the problems are connected.

Then I've read also one or two articles about wierd - at first glance - GC
behavior. It is also described in MSDN under "GC.KeepAlive" entry. So I've
learned that when GC occurs and a local variable is no longer referenced in
code, the object referenced by this variable MAY be freed (in my case
finalized) by CG EVEN if the execution flow didn't leave current block. So
for example:

using (SomeDisposableAndFinalizableClass o = new
SomeDisposableAndFinalizableClass())
{
o.Whatever();
// o can be finalized here!
SomeInstructionWithoutO();
SomeOtherInstructionWithoutO();
// o is already finalized
}

In case of my wrapper and I strongly suppose in case of a socket,
finalization means closing the handle to resource. Any call to those objects
would result in "invalid handle" exception.

That is why I put GC.KeepAlive(p or socket) before end of using block in my
code.
I don't know if it fixed the problems yet. I don't suppose so. Because each
piece of my code DOES REFERENCE the port or the socket almost to the end of
using block. So GC should not mark my objects for cleanup. Also - the
exception in socket's case is thrown in constructor!

It's a long post, but a question is simple...anyone knows what may cause
those problems?

Thanks for all your help
Jan
Jan Waga - 31 Mar 2006 14:38 GMT
A forgot to add, may be helpful:

- those pieces of code are placed in System.Timers.Timer Elapsed handlers

- my application works on Windows XPSP2, NET1.1SP1, pentium 4 HT
Ben Voigt - 12 May 2006 23:52 GMT
> Hello,
>
[quoted text clipped - 16 lines]
> exception with errcode from GetLastError() and formatted system error
> message. Typical.

I suspect a buffer overflow trampling your handle storage.

Can you log the handle value after each CreateFile and before each
CloseHandle?  Then also print the handle value which caused the failure
result.  The data also, are the failures common (but perhaps not consistent)
to a certain data coming?

Any reason you aren't using Microsoft.Win32.SafeHandles?  Maybe sometimes
your IntPtr value happens to coincide with a reference.  Maybe when this
happens and the garbage collector moves the managed object, it adjusts your
handle.  Although I think IntPtrs aren't adjusted and you would need to use
pinning to use them with a managed reference.

> The code looks a bit like this:
>
[quoted text clipped - 51 lines]
> objects
> would result in "invalid handle" exception.

The end of the using block should reference o.Dispose(), so I think it can't
be collected.

> That is why I put GC.KeepAlive(p or socket) before end of using block in
> my
[quoted text clipped - 11 lines]
> Thanks for all your help
> Jan

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.