怎么监视跟踪一个进程(Process)中的dll的详细性能(performance)【asp.net C#】

This tutorial will show how to instrument a unit test DLL for performance profiling. Visual Studio will allow you to do performance profiling on individual tests (i.e. functions) in a test suite. This can be done in the user interface (i.e. UI or IDE). However if you have a unit test DLL that contains lots of unit tests or test methods, it’s apparently not possible to do performance profiling in the IDE.

Here was my original question:

Question on MSDN forums

I have a MS Unit Test DLL written in C# that targets a C++/CLI managed assembly. I have roughly 60 unit tests in that unit test dll. What I would like to do is run all the unit tests under the performance profiler, in the IDE. That is using the performance explorer to run a performance session for all the unit tests in my test DLL. I know how to do this from the command line, but I feel that is a last resort. I’d like to do this in the IDE if possible. It is possible to create a performance session for one unit test in the unit test DLL. The steps are listed here: ms-help://MS.VSCC.v90/MS.MSDNQTR.v90.en/dv_vsetlt01/html/4cc514d2-47bd-4f1c-a039-5ffae7c68bf1.htm i.e. Right click over a test result, and select "Create Performance Session". Whereupon the Performance Explorer will show a new session based off of one unit test. That’s great, but I’ve got 60 unit tests in my DLL. I don’t want to have to create 60 performance sessions.

Preparation

Build the code that you will be testing. In my case it was the following DLL’s (Assuming a common root folder)


DLL name


Description

..\ManagedAPI\Win32\Debug\UnderstandWrapper.ManagedAPI.dl The DLL with the code I wanted to test
..\UnitTest\bin\x86\Debug\UnitTest.dll This DLL contains my unit tests

Then just to play it safe, run all the unit tests (This can be done in the IDE) in UnitTest.dll. It pays to be paranoid like this since if you want to detect bugs early and swiftly.

Now the strategy for profiling an entire DLL is to:

  • Instrument the DLL. This means to inject performance related commands into the code. Don’t worry it’s perfectly safe.

    • Turn on performance profiling via a global command.

      • Run your unit tests. Here is where the real work gets done.
    • Turn off performance profiling via a global command. (A results file gets saved somewhere).
  • Un-Instrument the DLL. This means restoring it to it’s original state. (i.e. Don’t ship a DLL with performance profiling enabled).

Instrument the Binaries

I instrument my DLL’s using the following batch script called: Instrument_ON.bat

  1. @echo off
  2. @echo Instrumenting Binary
  3. set VS90TEAMTOOLS="%VS90COMNTOOLS%..\..\Team Tools\Performance Tools\"
  4. %VS90TEAMTOOLS%\VSInstr.exe ..\ManagedAPI\Win32\Debug\UnderstandWrapper.ManagedAPI.dll
  5. %VS90TEAMTOOLS%\VSInstr.exe ..\UnitTest\bin\x86\Debug\UnitTest.dll
  6. pause
  7. @echo on

The results of instrumenting it looks like this:

Instrumenting Binary      Microsoft (R) VSInstr Post-Link Instrumentation 9.0.30729 x86       Copyright (C) Microsoft Corp. All rights reserved.

File to Process:         F:\CodePlex\UnderstandAPI\Managed\ManagedAPI\Win32\Debug\UnderstandWrapper.ManagedAPI.dll –> F:\CodePlex\UnderstandAPI\Managed\ManagedAPI\Win32\De       bug\UnderstandWrapper.ManagedAPI.dll       Original file backed up to F:\CodePlex\UnderstandAPI\Managed\ManagedAPI\Win32\Debug\UnderstandWrapper.ManagedAPI.dll.orig

Successfully instrumented file F:\CodePlex\UnderstandAPI\Managed\ManagedAPI\Win32\Debug\UnderstandWrapper.ManagedAPI.dll.      Warning VSP2013 : Instrumenting this image requires it to run as a 32-bit process.  The CLR header flags have been updated to reflect this.       Microsoft (R) VSInstr Post-Link Instrumentation 9.0.30729 x86       Copyright (C) Microsoft Corp. All rights reserved.

File to Process:         F:\CodePlex\UnderstandAPI\Managed\UnitTest\bin\x86\Debug\UnitTest.dll –> F:\CodePlex\UnderstandAPI\Managed\UnitTest\bin\x86\Debug\UnitTest.dll       Original file backed up to F:\CodePlex\UnderstandAPI\Managed\UnitTest\bin\x86\Debug\UnitTest.dll.orig

Successfully instrumented file F:\CodePlex\UnderstandAPI\Managed\UnitTest\bin\x86\Debug\UnitTest.dll.      Press any key to continue . . .

Turn on Monitor

I then turn on performance profiling using the following batch script called: Performance_ON.bat       

  1. @echo off
  2. @echo Turning ON performance coverage session recorder
  3. set VS90TEAMTOOLS="%VS90COMNTOOLS%..\..\Team Tools\Performance Tools"
  4. %VS90TEAMTOOLS%\VsPerfCmd /start:trace /output:ManagedAPI.vsp
  5. pause
  6. @echo on

The results of this batch scripts looks like this:

Turning ON performance coverage session recorder      Microsoft (R) VSPerf Command Version 9.0.30729 x86       Copyright (C) Microsoft Corp. All rights reserved.

Press any key to continue . . .

The results of this script is it starts another process that will monitor any application that happens to be instrumented with performance profiling, or code coverage profiling. In our case it started a process called VsPerfMon.exe:

Run Unit Tests

I then run all the unit tests in my DLL using another batch script. Now I have two build configurations (debug and release) so I have two batch scripts to run those: Run_Tests_Debug.bat and Run_Tests_Release.bat. Here is one of them:

  1. @echo off
  2. color 16
  3. @echo Running Unit Tests
  4. call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Team Tools\Performance Tools\VsPerfCLREnv" /traceon
  5. call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat";
  6. mstest /testcontainer:%CD%\UnitTest\bin\x86\Debug\UnitTest.dll > results.txt
  7. pause
  8. @echo on

Notice there the actual call to mstest.exe is what runs the unit tests. Notice that I piped the results of running the actual unit tests into a text file (i.e. results.txt). I did this because it gives me a more permanent record of how my unit tests did.

The mstest.exe file resides on my computer at:

"C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\MSTest.exe"

The output, to the console window, of this script on my looks like the following:

Running Unit Tests      Enabling VSPerf Trace Profiling of managed applications (excluding allocation profiling).

Current Profiling Environment variables are:      COR_ENABLE_PROFILING=1       COR_PROFILER={6468ec6c-94bd-40d3-bd93-4414565dafbf}       COR_LINE_PROFILING=0       COR_GC_PROFILING=0       Setting environment for using Microsoft Visual Studio 2008 x86 tools.       Press any key to continue . . .

Noticed I redirected the standard output (standard out) to a text file. The results.txt file looks like this:

Microsoft (R) Test Execution Command Line Tool Version 9.0.30729.1      Copyright (c) Microsoft Corporation. All rights reserved.       Loading F:\CodePlex\UnderstandAPI\Managed\UnitTest\bin\x86\Debug\UnitTest.dll…       Starting execution…

Results               Top Level Tests      ——-               —————       Passed                UnitTest.DatabaseTest.DatabaseTest_GetAllEntities       Passed                UnitTest.DatabaseTest.DatabaseTest_GetFileEntities       Passed                UnitTest.DatabaseTest.DatabaseTest_LookupEntity       Passed                UnitTest.DatabaseTest.DatabaseTest_LookupEntitybyReference       Passed                UnitTest.DatabaseTest.DatabaseTest_LookupEntityUnique       Passed                UnitTest.DatabaseTest.DatabaseTest_LookupFile       Passed                UnitTest.DatabaseTest.DatabaseTest_Misc       Passed                UnitTest.DatabaseTest.DatabaseTest_OpenClose       Passed                UnitTest.Derived.ClassTypeTest.TestClassNests       Passed                UnitTest.Derived.ClassTypeTest.TestClassType       Passed                UnitTest.Derived.ClassTypeTest.TestClassTypeDerivedFrom       Passed                UnitTest.Derived.ClassTypeTest.TestClassTypeEnums       Passed                UnitTest.Derived.ClassTypeTest.TestClassTypeFields       Passed                UnitTest.Derived.ClassTypeTest.TestClassTypeInheritance       Passed                UnitTest.Derived.ClassTypeTest.TestClassTypeTemplates       Passed                UnitTest.Derived.ClassTypeTest.TestClassTypeUnions       Passed                UnitTest.Derived.ClassTypeTest.TestGetDefinedMethods       Passed                UnitTest.Derived.ClassTypeTest.TestGetMethods       Passed                UnitTest.Derived.EnumTypeTest.EnumTest_Enumerators       Passed                UnitTest.Derived.EnumTypeTest.EnumTest_Type       Passed                UnitTest.Derived.FileEntityTest.TestFileEntity       Passed                UnitTest.Derived.FileEntityTest.TestFileEntity_base_h       Passed                UnitTest.Derived.FileEntityTest.TestFileEntity_classes_h       Passed                UnitTest.Derived.FileEntityTest.TestFileEntityClassTypes       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Constructor       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Inline       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Inline_B       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_LexerStuff       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Member_A       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Member_B       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Member_C       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Member_D       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Member_E       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Member_F       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_MemberBlank       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Overrides       Passed                UnitTest.Derived.MethodTypeTest.MethodTest_Pure       Passed                UnitTest.EntityTest.EntityTest_Basic       Passed                UnitTest.EntityTest.EntityTest_Comments       Passed                UnitTest.EntityTest.EntityTest_Comments_Enums       Passed                UnitTest.EntityTest.EntityTest_Comments_FunctionDeclarations       Passed                UnitTest.EntityTest.EntityTest_Comments_FunctionDefinitions       Passed                UnitTest.EntityTest.EntityTest_Comments_Typedefs       Passed                UnitTest.EntityTest.EntityTest_FileReference       Passed                UnitTest.EntityTest.EntityTest_LineNumbers       Passed                UnitTest.EntityTest.EntityTest_LineNumbers_FunctionDeclarations       Passed                UnitTest.EntityTest.EntityTest_LineNumbers_FunctionDefinitions       Passed                UnitTest.EntityTest.EntityTest_LineNumbers_UnresolvedMethods       Passed                UnitTest.EntityTest.EntityTest_Refs       Passed                UnitTest.EntityTest.EntityTest_Types       Passed                UnitTest.KindTest.KindTest_Basic       Passed                UnitTest.LexerTest.Lexer_Test       Passed                UnitTest.LexerTest.Lexer_Test_GetLexeme       Passed                UnitTest.LexerTest.Lexer_Test_Next       Passed                UnitTest.LexerTest.Lexer_Test_Previous       Passed                UnitTest.LexerTest.Lexer_Test_Ref       Passed                UnitTest.ReferenceTest.ReferencesTest_Basic       Passed                UnitTest.ReferenceTest.ReferencesTest_Copying       58/58 test(s) Passed

Summary      ——-       Test Run Completed.         Passed  58         ———-         Total   58       Results file:      F:\CodePlex\UnderstandAPI\Managed\TestResults\Chris Johnson_CHRISJOHNSON-PC 2010-02-17 23_38_54.trx       Run Configuration: Default Run Configuration

Feels good to see all the unit tests pass. But now I have to save out the results of the performance profiling. And to do this, I now have to turn off the VsPerfMon.exe process that is running, and was running when I ran my unit tests.

Turn off Monitor

I have a batch script that turns off monitoring and saves out a results file containing all the profiling goodness. Performance_OFF.bat

  1. @echo off
  2. @echo Turning off performance coverage session recorder
  3. set VS90TEAMTOOLS="%VS90COMNTOOLS%..\..\Team Tools\Performance Tools"
  4. %VS90TEAMTOOLS%\VSPerfCmd /shutdown
  5. pause
  6. @echo on

The results of this batch script looks like this:

Turning off performance coverage session recorder      Microsoft (R) VSPerf Command Version 9.0.30729 x86       Copyright (C) Microsoft Corp. All rights reserved.

Shutting down the Profile Monitor      ————————————————————       Press any key to continue . . .

Now a new file is saved out to my computer:

F:\CodePlex\UnderstandAPI\Managed\Performance\ManagedAPI.vsp

Notice the name: ManagedAPI.vsp. This is the same name I passed in when I turned on the Performance Monitor. Remember this?

from: Performance_ON.bat

VsPerfCmd /start:trace /output:ManagedAPI.vsp

Now at this point, you can do two things:

  1. Examine your performance results. This is done by double clicking the ManagedAPI.vsp file. This will just launch visual studio, and display the results of your tests:
  2. Or Uninstrument your DLL’s. It’s never a good idea to ship DLL’s with instrumentation in them.

Un-Instrument the Binaries

I have a script that does this for me: Instrument_OFF.bat

  1. @echo off
  2. @echo Removing Instrumented Files
  3. pushd ..\ManagedAPI\Win32\Debug
  4. if exist UnderstandWrapper.ManagedAPI.instr.pdb (
  5. del UnderstandWrapper.ManagedAPI.instr.pdb
  6. del UnderstandWrapper.ManagedAPI.dll
  7. rename UnderstandWrapper.ManagedAPI.dll.orig UnderstandWrapper.ManagedAPI.dll
  8. )
  9. popd
  10. pushd ..\UnitTest\bin\x86\Debug
  11. if exist UnitTest.instr.pdb (
  12. del UnitTest.instr.pdb
  13. del UnitTest.dll
  14. rename UnitTest.dll.orig UnitTest.dll
  15. )
  16. popd
  17. pause
  18. @echo on

When I run this, I get the following results in the command window:

Removing Instrumented Files      Press any key to continue . . .

However, sometimes I do this only after I reviewed my performance results. Since the performance results display in visual studio may be dependent on the instrumented binaries to properly display its data.

View Results

Now that you have your .vsp file it is time to open it. The file ManagedAPI.vsp shows the following in visual studio:

From there you can analyze the results and find your performance bottlenecks.

时间: 2024-10-27 16:46:36

怎么监视跟踪一个进程(Process)中的dll的详细性能(performance)【asp.net C#】的相关文章

python 进程Process模块(40)

进程Process是对各种资源管理的集合,包含对各种资源的调用.内存的管理.网络接口的调用:一个进程Process可以包含多个子进程,启动一个进程的时候会自动创建一个线程,进程里的第一个线程就是主线程(即python __name__ == ‘__main__’): 二.进程Process模块 对于线程操作可以用threading模块,那么对于进程的创建python同样也提供了Process模块,创建进程时需要导入该模块,语法如下: # 导入进程模块 from multiprocessing i

如何在 Linux 中统计一个进程的线程数

编译自:http://ask.xmodulo.com/number-of-threads-process-linux.html作者: Dan Nanni原创:LCTT https://linux.cn/article-6240-1.html译者: strugglingyouth本文地址:https://linux.cn/article-6240-1.html 2015-9-17 10:29    收藏: 5 问题: 我正在运行一个程序,它在运行时会派生出多个线程.我想知道程序在运行时会有多少线程

在程序中使用命令打开一个进程和记录该进程执行日志

//在需要的程序中调用ExcutedCmd函数来打开执行dos命令 //cmd 命令  args 命令参数 private static void ExcutedCmd(string cmd, string args) { using (Process p = new Process()) { ProcessStartInfo psi = new ProcessStartInfo(cmd, args); psi.CreateNoWindow = true; psi.UseShellExecute

实现同一个脚本多次运行,系统中只有一个进程

编写脚本,实现同一个脚本多次运行,系统中只有一个进程 [email protected] scripts]#cat pid.sh #!/bin/sh pidpath=/tmp/a.pid if [ -f "$pidpath" ]   then     kill `cat $pidpath` >/dev/null 2>&1     rm -f $pidpath fi echo $$ >$pidpath sleep 300 测试如下 [email protecte

java代码中获取进程process id(转)

另一方面,线程ID=进程ID+内部线程对象ID并不成立,    参考: blog.csdn.net/heyetina/article/details/6633901     如何在java代码中获取进程process id, 实现方法如下所示:    参考: rednaxelafx.iteye.com/blog/716918 http://www.cnblogs.com/mumuxinfei/p/3678854.html

计算机必知必会:进程process与线程thread 进程定义为一个正在运行的程序的实例

http://www.nowamagic.net/librarys/veda/detail/1741进程和线程这对概念的理解也是很难的,至今网络上可查的资料对其的理解出入都挺大,在不同的操作系统中,如linux和windows中,其概念和实现都是有出入的.因此,我在这里结合我自己的理解谈下这两个概念,讲的都是一般性的概念,并且主要是基以WINDOWS的. 一般将进程定义为一个正在运行的程序的实例.我们在任务管理器重所看到的每一项,就可以理解为一个进程,每个进程都有一个地址空间,这个地址空间里有可

在GNU Linux中怎样得到一个进程当前的流量

/*********************************************************************  * Author  : Samson  * Date    : 11/19/2014  * Test platform:  *              3.13.0-24-generic  *              GNU bash, 4.3.11(1)-release  * ************************************

学习笔记之卸载远程目标进程中的DLL模块(转)

学习笔记之卸载远程目标进程中的DLL模块 (2007-07-23 23:51:02) 转载▼ 学习笔记之卸载远程目标进程中的DLL模块2007/7/231.首先得把DLL模块中的线程结束使用CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);创建系统线程的快照然后用Thread32First()和Thread32Next()遍历系统中所有线程.将遍历到的线程保存到THREADENTRY32结构,然后判断结构中的th32OwnerProcessID成员是否与

你知道进程(Process)是什么吗?

对应用程序来说,进程就像一个大容器.在应用程序被运行后,就相当于将应用程序装进容器里了,你可以往容器里加其他东西(如:应用程序在运行时所需的变量数据.需要引用的DLL文件等),当应用程序被运行两次时,容器里的东西并不会被倒掉,系统会找一个新的进程容器来容纳它.一个进程可以包含若干线程(Thread),线程可以帮助应用程序同时做几件事(比如一个线程向磁盘写入文件,另一个则接收用户的按键操作并及时做出反应,互相不干扰),在程序被运行后中,系统首先要做的就是为该程序进程建立一个默认线程,然后程序可以根