Question

I'm following the Profiling Tutorial here: http://msdn.microsoft.com/en-us/magazine/cc337887.aspx

I've tried to profile the project by using CPU sampling.

MSDN Results:

MSDN Profiling

My Results:

VS 2012 Profiling

I'm expecting to see System.Drawing.Bitmap.SetPixel instead of the [System.Drawing.ni.dll].

As recommended by this post, I have:

  • Clicked the "Show All Code" link
  • Disabled "Just My Code"
  • Checked "Microsoft Symbol Serves" in Tools > Options > Debugging > Symbols, restarted visual studio and ran the report again.

Output (after following above steps):

Failed to load symbols for C:\Windows\assembly\NativeImages_v2.0.50727_64\System.Drawing\8b88ae6d063a9d8ffc2f312af5d40ce5\System.Drawing.ni.dll
Loaded symbols from report for C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Loaded symbols from report for C:\Windows\WinSxS\amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.9200.16518_none_726fbfe0cc22f012\GdiPlus.dll
Loaded symbols from report for C:\Windows\System32\ntdll.dll
Loaded symbols from report for C:\Windows\System32\KernelBase.dll
Loaded symbols from report for C:\Windows\System32\msvcrt.dll
Failed to load symbols for C:\Windows\assembly\NativeImages_v2.0.50727_64\mscorlib\061d0414114241f4f2fe0908bf53b076\mscorlib.ni.dll
Failed to load symbols for C:\Windows\assembly\NativeImages_v2.0.50727_64\System.Windows.Forms\01a89d2c3499af1e3378797d51eec364\System.Windows.Forms.ni.dll
Loaded symbols from report for C:\Windows\System32\user32.dll
Loaded symbols from report for C:\Windows\System32\gdi32.dll
Loaded symbols from report for C:\Windows\System32\kernel32.dll
Loaded symbols from report for C:\Windows\System32\uxtheme.dll
Loaded symbols from report for C:\Users\user\Desktop\VSTSProfiler\bin\Debug\Mandel.exe
Symbol information saved to report.

(The source code can be donwloaded from here: http://download.microsoft.com/download/f/2/7/f279e71e-efb0-4155-873d-5554a0608523/MSDNMag2008_03.exe

After extracting, it will be in a folder called: VSTSProfiler. Regardless, here is the pasted source code in case it goes down:)

using System;
using System.Xml;
using System.Xml.Serialization;
using System.Diagnostics;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Threading;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;
using System.Collections.Generic;

namespace Mandel
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        #region Auto
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(392, 266);
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Mandel - Drawing...";
            this.WindowState = System.Windows.Forms.FormWindowState.Maximized;
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }
        #endregion

        Thread drawingThread = null;
        double xLowBound = -2.1;
        double yLowBound = -1.3;
        double xUpperBound = 1;
        double yUpperBound = 1.3;
        string colorsMap = "Green.Map";
        const bool COLOR = false;
        //This timer will check whether the drawing thread is still working
        //and update the title after it finishes:
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();

        private void Form1_Load(object sender, System.EventArgs e)
        {
            //Setup the timer and hook to it
            timer.Interval = 200;
            timer.Tick += OnTimer;
            //Initialize and start the drawing thread:
            this.drawingThread = new Thread(new ThreadStart(this.DrawMandel));
            this.drawingThread.Start();
            timer.Start();
        }

        private void OnTimer(object sender, EventArgs args)
        {
            if (this.drawingThread.IsAlive)
            {
                this.Text = "Mandel - Generating Fractal...";
            }
            else
            {
                timer.Stop();
                this.Text = "Mandel - Ready";
            }
        }

        private void DrawMandel()
        {
            for (int i = 0; i < 5; i++)
            { //This loop was added purposely to slow the program down to measure performance.

                Color[] colors = ReadColorsMap(colorsMap);
                Bitmap bitmap = new Bitmap(Width, Height);

                //Uncomment the block below to avoid Bitmap.SetPixel:
                //BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, bitmap.PixelFormat);
                //IntPtr ptr = bmpData.Scan0;
                //int pixels = bitmap.Width * bitmap.Height;
                //Int32[] rgbValues = new Int32[pixels];

                double xStart = xLowBound;
                double yStart = yLowBound;
                double xEnd = xUpperBound;
                double yEnd = yUpperBound;
                double deltaX = (xEnd - xStart) / Width;
                double deltaY = (yEnd - yStart) / Height;
                double x = xStart;
                double y = yStart;

                for (int column = 1; column < Width; column++)
                {
                    y = yStart;
                    for (int row = 1; row < Height; row++)
                    {
                        double x1 = 0;
                        double y1 = 0;
                        int color = 0;
                        int dept = 0;
                        do
                        {
                            dept++;
                            double temp = (x1 * x1) - (y1 * y1) + x;
                            y1 = 2 * x1 * y1 + y;
                            x1 = temp;
                            double percentFactor = dept / (100.0);
                            color = ((int)(percentFactor * 255));
                        }
                        while (dept < 100 && Math.Sqrt((x1 * x1) + (y1 * y1)) < 2);
                        //Comment this line to avoid calling Bitmap.SetPixel:
                        bitmap.SetPixel(column, row, colors[color]);
                        //Uncomment the block below to avoid Bitmap.SetPixel:
                        //rgbValues[row * Width + column] = colors[color].ToArgb();

                        y += deltaY;
                    }
                    x += deltaX;
                }


                //Uncomment the block below to avoid Bitmap.SetPixel:
                //Marshal.Copy(rgbValues, 0, ptr, pixels);
                //bitmap.UnlockBits(bmpData);

                BackgroundImage = (Image)bitmap;
            }
        }


        private Color[] ReadColorsMap(string Path)
        {
            try
            {
                Color[] colors = new Color[256];
                List<string> colorLines = new List<string>();

                //Read the color definitions:
                using (StreamReader sr = new StreamReader(Path))
                {
                    while (!sr.EndOfStream)
                    {
                        string s = sr.ReadLine();
                        if (!String.IsNullOrEmpty(s))
                        {
                            colorLines.Add(s.Trim());
                        }
                    }
                }

                //Parse the definitions and store them in "colors" array
                if (colorLines.Count > colors.Length)
                {
                    throw new Exception(string.Format("Too many colors"));
                }

                int colorIndex = 0;
                foreach(string color in colorLines)
                {
                    string[] values = color.Split(' ');
                    if (values.Length != 3)
                    {
                        throw new Exception(string.Format("Map line: '{0}'", color));
                    }

                    int red = int.Parse(values[0]);
                    int green = int.Parse(values[1]);
                    int blue = int.Parse(values[2]);
                    colors[colorIndex++] = Color.FromArgb(red, green, blue);
                }

                //Set the rest to black:
                for (; colorIndex < colors.Length; colorIndex++)
                {
                    colors[colorIndex] = Color.Black;
                }

                return colors;
            }
            catch(Exception ex)
            {
                throw new Exception("Invalid ColorMap file.", ex);
            }
        }
    }
}
Was it helpful?

Solution

Found out how:

  • Run the version of NGEN.exe from the same version of .NET you are compiling for. Example: C:\Windows\Microsoft.NET\Framework64\v4.0.30319
  • Give it the parameter createpdb
  • Specify the full path of the DLL you need to PDB for Specify the path of your assembly cache. Example: ngen.exe createpdb C:\windows\pathtoassembly.dll C:\SymbolCache

Final command that worked. I reloaded Visual Studio and was succesful after that. I used the same link Hans Passant posted incidentally.

C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC>ngen createpdb "C:\Window
s\assembly\NativeImages_v4.0.30319_32\System.Drawing\ee1e19e1282f67f0466e281b535
69cd7\System.Drawing.ni.dll" C:\SymbolCache
Microsoft (R) CLR Native Image Generator - Version 4.0.30319.17929
Copyright (c) Microsoft Corporation.  All rights reserved.
Successfully generated PDB for native assembly 'C:\Windows\assembly\NativeImages
_v4.0.30319_32\System.Drawing\ee1e19e1282f67f0466e281b53569cd7\System.Drawing.ni
.dll'.
PDB generated in directory C:\SymbolCache\System.Drawing.ni.pdb\ee1e19e1282f67f0
466e281b53569cd71\
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top