Patches for .NET 2, beta 2 and race condition on termination of the socket listening thread

David Black <[email protected]> Tue, 10 May 2005 21:42:59 +0100
Newsgroups gmane.comp.windows.dotnet.nprof.devel
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------080008020503030508080205
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

I have been playing with NProf, I had to make a few changes to allow it 
to run under beta 2 of the .NET framework. ie Add stubs for 
ICorProfilerCallback2.

Also there was a race condition in ProfilerSocketServer, which caused 
the server thread to never terminate. I think I fixed this correctly(by 
creating a new stop event and using WaitAny()). It seems to work, but I 
have not done extensive testing.

I had to make a couple of other little changes to get the Hook DLL to 
compile under VS2005.

The patch removes the check for msvcr70.dl(in ProfilerForm)., I guess 
that was in there so the hook dll didnt fail when loaded, but it was 
causing me problems by triggering when it shouldnt. So I just commented 
it out.

The patch file, against latest CVS is attached.

Thanks,

David

--------------080008020503030508080205
Content-Type: text/plain;
 name="nprof.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="nprof.patch"

Index: NProf.GUI/ProfilerForm.cs
===================================================================
RCS file: /cvsroot/nprof/nprof/NProf.GUI/ProfilerForm.cs,v
retrieving revision 1.28
diff -u -r1.28 ProfilerForm.cs
--- NProf.GUI/ProfilerForm.cs	3 Oct 2004 15:58:42 -0000	1.28
+++ NProf.GUI/ProfilerForm.cs	10 May 2005 18:21:40 -0000
@@ -87,13 +87,13 @@
 			_p.Error += new Profiler.ErrorHandler( OnError );
 			_piInitialProject = null;
 			
-			string strDirectory = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
+			/*string strDirectory = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
 			string strDLL = Path.Combine( strDirectory, "msvcr70.dll" );
 			if ( LoadLibrary( strDLL ) == 0 )
-				throw new Win32Exception( Marshal.GetLastWin32Error(), "Failed to load msvcr10.dll" );
+				throw new Win32Exception( Marshal.GetLastWin32Error(), "Failed to load msvcr10.dll" );*/
 		}
 
- 		[DllImport("kernel32.dll", SetLastError=true)] static extern int LoadLibrary( string strLibFileName );
+ 		//[DllImport("kernel32.dll", SetLastError=true)] static extern int LoadLibrary( string strLibFileName );
 
 		/// <summary>
 		/// Clean up any resources being used.
Index: NProf.Glue/Profiler/Core/ProfilerSocketServer.cs
===================================================================
RCS file: /cvsroot/nprof/nprof/NProf.Glue/Profiler/Core/ProfilerSocketServer.cs,v
retrieving revision 1.10
diff -u -r1.10 ProfilerSocketServer.cs
--- NProf.Glue/Profiler/Core/ProfilerSocketServer.cs	2 Jul 2004 22:16:56 -0000	1.10
+++ NProf.Glue/Profiler/Core/ProfilerSocketServer.cs	10 May 2005 19:22:05 -0000
@@ -18,7 +18,8 @@
 		public ProfilerSocketServer( Project.Options po, Run run )
 		{
 			_run = run;
-			_nStopFlag = 0;
+			//_nStopFlag = 0;
+			_mreStop = new ManualResetEvent(false);
 			_po = po;
 			_bHasStopped = false;
 			_nCurrentApplicationID = 0;
@@ -37,8 +38,9 @@
 
 		public void Stop()
 		{
-			lock ( _s )
-				Interlocked.Increment( ref _nStopFlag );
+			_mreStop.Set();
+			_t.Join();
+
 			_s.Close();
 		}
 
@@ -64,11 +66,13 @@
 					while ( true )
 					{
 						_mreReceivedMessage.Reset();
-						lock ( _s )
-							if ( _nStopFlag == 1 )
-								break;
+
 						_s.BeginAccept( new AsyncCallback( AcceptConnection ), _s );
-						_mreReceivedMessage.WaitOne();
+
+						int waitIdx=ManualResetEvent.WaitAny(new WaitHandle[] { _mreStop, _mreReceivedMessage });
+						if (waitIdx == 0)
+							break;
+						
 					}
 				}
 			}
@@ -112,14 +116,6 @@
 
 		private void AcceptConnection( IAsyncResult ar )
 		{
-			lock ( _s )
-			{
-				if ( _nStopFlag == 1 )
-				{
-					_mreReceivedMessage.Set();
-					return;
-				}
-			}
 
 			// Note that this fails if you call EndAccept on a closed socket
 			Socket s = ( ( Socket )ar.AsyncState ).EndAccept( ar );
@@ -348,7 +344,8 @@
 		const int NETWORK_PROTOCOL_VERSION = 3;
 
 		private int						_nPort;
-		private int						_nStopFlag;
+		//private int						_nStopFlag;
+		private ManualResetEvent		_mreStop;
 		private int						_nCurrentApplicationID;
 		private int						_nProfileCount;
 		private ManualResetEvent		_mreStarted;
Index: NProf.Hook/NProfCORHook.h
===================================================================
RCS file: /cvsroot/nprof/nprof/NProf.Hook/NProfCORHook.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 NProfCORHook.h
--- NProf.Hook/NProfCORHook.h	9 Mar 2003 20:37:29 -0000	1.1.1.1
+++ NProf.Hook/NProfCORHook.h	10 May 2005 18:53:46 -0000
@@ -35,7 +35,7 @@
 ]
 class ATL_NO_VTABLE CNProfCORHook : 
   public INProfCORHook,
-  public ICorProfilerCallback
+  public ICorProfilerCallback2
 {
 public:
   CNProfCORHook()
@@ -82,7 +82,7 @@
       cout << "Initializing event masks..." << endl;
       pProfilerInfo->SetEventMask( 
         COR_PRF_MONITOR_THREADS	|
-        COR_PRF_DISABLE_INLINING |
+      //  COR_PRF_DISABLE_INLINING |
         COR_PRF_MONITOR_SUSPENDS |    
         COR_PRF_MONITOR_ENTERLEAVE |
         COR_PRF_MONITOR_EXCEPTIONS |  
@@ -395,6 +395,67 @@
   {
     return E_NOTIMPL;
   }
+
+  		//ICorProfilerCallback2 methods
+
+  STDMETHOD(ThreadNameChanged)( 
+            /* [in] */ ThreadID threadId,
+            /* [in] */ ULONG cchName,
+            /* [in] */ WCHAR name[  ])
+			  {
+    return E_NOTIMPL;
+  }
+        
+  STDMETHOD(GarbageCollectionStarted)( 
+            /* [in] */ int cGenerations,
+            /* [length_is][size_is][in] */ BOOL generationCollected[  ],
+            /* [in] */ COR_PRF_GC_REASON reason)
+			  {
+    return E_NOTIMPL;
+  }
+        
+  STDMETHOD(SurvivingReferences)( 
+            /* [in] */ ULONG cSurvivingObjectIDRanges,
+            /* [size_is][in] */ ObjectID objectIDRangeStart[  ],
+            /* [size_is][in] */ ULONG cObjectIDRangeLength[  ])
+			  {
+    return E_NOTIMPL;
+  }
+        
+  STDMETHOD(GarbageCollectionFinished)( void)
+	    {
+    return E_NOTIMPL;
+  }
+
+  STDMETHOD(FinalizeableObjectQueued)( 
+            /* [in] */ DWORD finalizerFlags,
+            /* [in] */ ObjectID objectID)
+			  {
+    return E_NOTIMPL;
+  }
+        
+  STDMETHOD(RootReferences2)( 
+            /* [in] */ ULONG cRootRefs,
+            /* [size_is][in] */ ObjectID rootRefIds[  ],
+            /* [size_is][in] */ COR_PRF_GC_ROOT_KIND rootKinds[  ],
+            /* [size_is][in] */ COR_PRF_GC_ROOT_FLAGS rootFlags[  ],
+            /* [size_is][in] */ UINT_PTR rootIds[  ])
+			  {
+    return E_NOTIMPL;
+  }
+        
+  STDMETHOD(HandleCreated)( 
+            /* [in] */ GCHandleID handleId,
+            /* [in] */ ObjectID initialObjectId)
+			  {
+    return E_NOTIMPL;
+  }
+        
+  STDMETHOD(HandleDestroyed)( 
+            /* [in] */ GCHandleID handleId)
+			  {
+    return E_NOTIMPL;
+  }
 };
 
 void __stdcall EnterStub( FunctionID fid )
@@ -458,4 +519,6 @@
         pop eax
         ret 4
     }  
+
+
 }
Index: NProf.Hook/profiler_helper.cpp
===================================================================
RCS file: /cvsroot/nprof/nprof/NProf.Hook/profiler_helper.cpp,v
retrieving revision 1.2
diff -u -r1.2 profiler_helper.cpp
--- NProf.Hook/profiler_helper.cpp	30 Dec 2003 04:18:26 -0000	1.2
+++ NProf.Hook/profiler_helper.cpp	10 May 2005 18:17:13 -0000
@@ -431,12 +431,12 @@
 						numlower = CorSigUncompressData( signature );	
 						if ( numlower <= rank )
 						{
-							for ( i = 0; i < numlower; i++)	
+							for (ULONG i = 0; i < numlower; i++)	
 								lower[i] = CorSigUncompressData( signature ); 
 							
                             
 							strcat( buffer, "[" );	
-							for ( i = 0; i < rank; i++ )	
+							for (ULONG i = 0; i < rank; i++ )	
 							{	
 								if ( (sizes[i] != 0) && (lower[i] != 0) )	
 								{	
Index: NProf.Hook/stdafx.h
===================================================================
RCS file: /cvsroot/nprof/nprof/NProf.Hook/stdafx.h,v
retrieving revision 1.3
diff -u -r1.3 stdafx.h
--- NProf.Hook/stdafx.h	30 Dec 2003 04:18:26 -0000	1.3
+++ NProf.Hook/stdafx.h	10 May 2005 18:14:56 -0000
@@ -67,7 +67,7 @@
 
 #include "corsym.h"
 #include "corpub.h"
-#include "corsvc.h"
+//#include "corsvc.h"
 #include "corprof.h"
 //#include "cordebug.h"
 

--------------080008020503030508080205--


-------------------------------------------------------
This SF.Net email is sponsored by Oracle Space Sweepstakes
Want to be the first software developer in space?
Enter now for the Oracle Space Sweepstakes!
http://ads.osdn.com/?ad_id=7393&alloc_id=16281&op=click