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

Matthew Mastracci <[email protected]> Wed, 11 May 2005 13:36:52 -0600
Newsgroups gmane.comp.windows.dotnet.nprof.devel
Message-ID <[email protected]>
Not a problem...  my @canada.com address seems to be down and their 
support address is bouncing.  :/

When I have a chance I'll try compiling against .NET 2.0 and see if I 
can't get it working.  I've been waiting to get closer to the official 
.NET 2.0 release date to avoid people having to install an early .NET 
beta on their development machines.  Sounds like I can safely compile 
the native part of the "official release" against .NET 2.0 without any 
worries.

Thanks for patches anyways,
Matt.

David Black wrote:
> 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



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