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

David Black <[email protected]> Tue, 10 May 2005 22:27:03 +0100
Newsgroups gmane.comp.windows.dotnet.nprof.devel
Message-ID <[email protected]>
Hi,

OK.

I, David Black, assign the copyright for any code contributed by myself 
to the nprof project to Matthew Mastracci and affirm that I may legally 
do so.

Not sure how legally binging an email is, but you have my word that I 
will not, and have no intention of pursueing any copyright issues in 
relation to code I conribute to nprof.

As for conditional compilation, I am not sure I would approach it that 
way. I would probably go with two 
ICorProfilerCallback/ICorProfilerCallback2 objects in the hook dll. Then 
selecting the appropiate GUID at runtime in the main application.

However, until functionality from ICorProfilerCallback2 is used, no 
changes are necasery. ie I dont see why a version compiled with .NET 
beta 2 wouldnt work on earlier version(at runtime, not compile time). 
Since ICorProfilerCallback2 inherits from ICorProfiler.

Incidentally, I commented out disabling of inlining in the initialize 
method. I think that was skewing some of my results(ie small methods 
taking a disproportionate amount of time), but havnt been able to verify 
that for certain yet.

David

PS, Your email address was not working, "User Unknown". So I am sending 
this back via the list, hope that is OK.

Matthew Mastracci wrote:

> Thanks for the patches.  I'll have to look into how I can 
> conditionally compile nprof for 1.x/2.x before I commit these, but 
> they will likely be a start.  I may release nprof 0.9 again with some 
> of these fixes, since it seems like it is pretty non-functional for a 
> lot of users.
>
> Before I commit these, I was wondering if you could reply with a 
> copyright assignment note.  I ask that contributers assign copyright 
> to myself to ensure that I can legally pursue copyright violations 
> (like the recent inclusion of nprof code into Jetbrains .NET profiler) 
> and enjoy all the other glories of a single-copyright project.  ;)
>
> Something along the lines of this will do:
>
> I, ____, assign the copyright for any code contributed by myself to 
> the nprof project to Matthew Mastracci and affirm that I may legally 
> do so.
> Thanks!
> Matt.
>
> David Black wrote:
>
>> 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
>>
>> ------------------------------------------------------------------------
>>
>> 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"
>>
>>  
>>
>



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