Did you know that Visual Studio 2010 Profiler allows you to profile your Silverlight 4 applications? You didn’t? It does.
This feature, however, is only partially integrated with Visual Studio UI, and you need to use command line tools to collect the data. After that, you can open the resulting .VSP file in Visual Studio as you normally do after other types of profiling, and enjoy rich visualization experience while investigating your performance problems.
Yes, we know it is not as cool as clicking VS buttons. We are working on a better experience. Yet I thought it is worth to emphasize that there is a way to use command line tools for customers that seek performance improvement in their Silverlight applications.
Let assume you develop an application like Breakout Game.
You compile it inside VS2010, run it, and want to profiler it. Performance Wizard tells you that this project can not be launched by the profiler. Alas. Time to go to the command line tools. Click you Start button, go to All Programs and find there Microsoft Visual Studio 2010. There, go to Visual Studio Tools and launch a Visual Studio Command Prompt (2010).
This command line window has predefined PATH that includes profiler command line tools:
Now go to the directory where your Silverlight binaries are compiled:
We are ready to start our profiling session.
Steps above require some explanation. In 1 – you prepare environment that is needed for Silverlight profiling, and in 2 you start your hosting process (iexplore.exe, in our example) within that environment. This is essential, as if you start IE by clicking an icon on your desktop, you will get no Silverlight profiling data at the end. Step 3 starts profiler in Sampling mode, and attaches it to the process of your choice. Keep in mind that you might have multiple IE processes running, so you need to choose one that runs your code. If you are not completely sure which one is it, or if your code runs in several IE processes – well, attach to all of them! You can do it either running “VSPerfCmd /attach:<PidN>” several times, or enumerating all PIDs in a single command: “VSPerfCmd /attach:PID1,PID2,PID3”. After profiler is attached, you run your scenario in step 4, and detach profiler from all target processes in step 5. Detaching is not enough, as you need to shutdown the profiler in order to finalize your result file (step 6). Step 7 cancels changes of the environment that are made in step 1.
It could be that you need to profile your application from the very beginning. In this case steps 2 and 3 can be combined into one, where you launch IE under profiler:
VSPerfCmd /start:sample /output:MyFile /launch:"c:\Program Files (x86)\Internet Explorer\iexplore.exe" /args:”C:\Breakout\Breakout\Bin\Release\TestPage.html“
The caveat here is that if IE process spawns a child process that will run your application, the profiler will be still attached to the “father” IE process, as it doesn’t re-attach itself automatically to spawned processes. You may, however, eliminate creation of child processes by IE8 through the registry, modifying TabProcGrowth value.
Please make sure that you run all the above steps from the directory where your binaries are located. Until we complete the integration of this feature with VS, your function names will not be properly resolved otherwise.
You can kill you IE process now. Open the MyFile.VSP in VS2010 as you would do normally for profiling results.
Formally, that would conclude an official support of Silverlight profiling in VS2010 – Sampling mode through command line tools.
However, if you want to try .NET memory or concurrency resource contention profiling of your Silverlight application – I won’t stop you. This is not currently supported and tested modes of work, but they might work for you and help you to see your performance problems from a different angle.
For .NET memory profiling, use “VSPerfClrEnv /samplegc” or “VSPerfClrEnv /samplegclife” in your step 1 to get either allocation profiling or allocation and lifetime profiling.
For concurrency resource contention – use “/start":concurrency,ResourceOnly” in the step 3 above.
Oren Nachman from Sliverlight team is another excellent source for Silverlight profiling information. In his great article he provides several additional tricks and options that you can find quite useful.
I have followed your directions with your Breakout source code and I cannot produce a profile that contains samples from the Breakout code. I see a similar call tree to your final graphic but it stops at Draw with no System.Windows.dll samples.
Can you think of any reason why I would not get any samples below agcore.dll?
Looks symbols for silverlight 4 are not publically available, when will it become available? its much needed and we have waited more than a year now.
Thanks miteshyh. I retried with a Release build and I now see the symbols.
I'll repeat your question, too. When will we see debug symbols MS?
Hi MarkRi and Miteshyh, The SL4 team member reply to your question is "the debug symbols will only apply to debug builds (chk). Since we only release ret builds, and only publish ret symbols, I’m not sure what the question is about. The ret symbols give you all the information you would want to have…". Saying that, as I am not Silverlight developer myself, may I suggest that you ask this question on forums on silverlight.net? There are many SL developers trolling those forums, so you might get an answer there. Thanks!
This doesn't work for me, no matter what I've tried. Basically, the vsp file is created, but it doesn't have any of the symbols for the user code. I even grabbed your breakout solution, put it in c:\code\Breakout..., changed dir to that Release dir, rebuilt the project, etc. I can successfully attach, run the app, and close, but I don't even see agcore.dll in my call tree. I'm running VS and the cmd window as admin, too. Any ideas on what's missing?
@Chuck - which install of VS and Silverlight are you running? Is it possible that you are running a version of Silverlight for which MS has not shared symbols for like an RC or Beta, etc?
When you run "VSPerfClrEnv /sampleon", a number of environment variables are set. Two of them are of the most importance for SL4 profiling -
Can you please double check that all of the below is valid in your case:
1. You use latest available version of Silverlight 4 and VS2010 (as MarkRi noticed).
2. You run your scenario from the directory where you SL4 binaries are located.
3. You use IE8 and you start it from the prepared environment, not by clicking an IE icon.
4. You attach to either all IE8 processes, or to the process that runs your SL code.
5. You have CORECLR_ENABLE_PROFILING and CORECLR_PROFILER environment variables set in your target process
6. You see VSPerfCorProf.dll is loaded into your target process.
Did you disable IE multi tab TabProcGrowth registry setting? Without this you will be attaching to the IE container as opposed to the tab process and will not see agcore.dll.
Do you have the SL4 dev tools installed - or are you using a stock install of VS2010 RTM to build the project and run it under the SL4 plugin? If so, can you install the SL4 dev tools from http://www.silverlight.net/getstarted/ and retry?
Just a note that profiling of the standard install of the SL4 plugin is not supported (you need the dev install to wire up the extra registry settings / files). Regardless, you should always see agcore.dll in your profiles though (regardless of version) as it is native, there just won't be any symbols underneath it.
I have the release of SL4 in VS2010 on a Win7 x64 box. Using IE8 and using cmd lines as posted above.
Thanks for the tips, I'll try this stuff out and get back to y'all hopefully before the end of today :)
Hi, I can get the SL4 profiler to work only if the IE loads HTML page, but if using aspx pages, I cannot see my own dll in the module list. Any idea?
Ah, got it. I used ProcExp to help me ensure I had the VSPerfCorProf.dll loaded within the process I was trying to profile, and that was the missing piece. Apparently orena's comment holds true, I was essentially profiling the wrong process. That also means the cmd that combines steps 2 and 3 didn't work for me because I didn't disable TabProcGrowth in the registry.
Hope all this helps others.
Chuck - great to hear that you got it solved! :)
Xsun - there is no difference from Silverlight's point of view if it is being loaded from aspx or html (it's all html in the end). I imagine that you are launching IE in slightly different ways each time:
1. Are you always launching IE from the Visual Studio command prompt?
2. Have you disabled TabProcGrowth in the registry? (set to 0)
Chuck - glad it worked out for you! Yes, you can combine steps 2 and 3 into launch of IE only if it will not spawn a new IE process. If your scenario allows you to attach and doesn't require launch, you can attach to any IE process later, or to all of them (if you are not sure which one of them is the right process).
Xsun - as Orena says, can you please make sure that you profiler the process that runs your code? There is a list of check points I provided for Chuck - can you please go through them and see if everything is in order?
1. Yes, always launching IE from VS prompt.
2. Yes, TabProcGrowth = 0.
I can see the VSPerfCorProf.dll loaded. I tried to use VS test Web service, which didn't sample anything. And I installed in IIS, the profiler captured something. But the result is different if I change the directory in the VS prompt. I can see the System.Windows.dll, and unkown under agcore.
What else can I try?
It sounds like you are actually getting agcore in the modules list - all you are missing is the symbols. You need to enable the Microsoft Symbol Server under Tools -> Options -> Debugging -> Symbols. Also make sure that you have the directory to your pdbs in the same list, so that you get the correct managed symbols.