Beispiel #1
0
        internal PdbEntry TaskStarted(TaskStartedEventArgs e)
        {
            PdbEntry taskSymbol = null;

            // We need to deal with 2 issues (a) batching (b) consecutive targets with same name (c) both
            // We will make a compromise here - in case of (c), we will have one symbol for the 1st task
            // and rest of symbols for the 2nd - irrespective of kind of combination we have for (c)
            // i.e. 3M M or 2M 2M or M 3M are all treated as M 3M
            string currentTaskName = projectStack.Peek().TargetStack.Peek().TargetSymbol.Children[projectStack.Peek().TargetStack.Peek().TaskNumber].Name;

            if (!string.Equals(e.TaskName, currentTaskName, StringComparison.OrdinalIgnoreCase))
            {
                taskSymbol = projectStack.Peek().TargetStack.Peek().TargetSymbol.Children[++projectStack.Peek().TargetStack.Peek().TaskNumber];
            }
            else
            {
                string nextTaskName = (projectStack.Peek().TargetStack.Peek().TaskNumber < (projectStack.Peek().TargetStack.Peek().TargetSymbol.Children.Count - 1)) ?
                                      projectStack.Peek().TargetStack.Peek().TargetSymbol.Children[projectStack.Peek().TargetStack.Peek().TaskNumber + 1].Name : null;

                if (string.Equals(e.TaskName, nextTaskName, StringComparison.OrdinalIgnoreCase))
                {
                    ++projectStack.Peek().TargetStack.Peek().TaskNumber;
                }

                taskSymbol = projectStack.Peek().TargetStack.Peek().TargetSymbol.Children[projectStack.Peek().TargetStack.Peek().TaskNumber];
            }

            // Return the symbol
            Debug.Assert(null != taskSymbol, "taskSymbol is null - this should never happen, we are going to crash!");
            return(taskSymbol);
        }
Beispiel #2
0
        internal PdbEntry TargetStarted(TargetStartedEventArgs e)
        {
            // Get the current target symbol
            PdbEntry targetSymbol = SymbolStore.Instance[e.TargetFile].TargetSymbolEntries[e.TargetName];

            // Create a stackframe
            projectStack.Peek().TargetStack.Push(new TargetStackFrame(targetSymbol));

            return(targetSymbol);
        }
Beispiel #3
0
        /// <summary>
        /// Target Started
        /// </summary>
        void eventSource_TargetStarted(object sender, TargetStartedEventArgs e)
        {
            // Load symbol information
            SymbolStore.Instance.LoadSymbols(e.TargetFile);

            // Create stack frame
            PdbEntry symbol = _contextCracker.TargetStarted(e);

            _callStack.Push(new StackFrame {
                ExecutablePath = e.TargetFile,
                TargetName     = e.TargetName,
                TaskName       = null,
                StartLocation  = symbol.StartLocation,
                EndLocation    = symbol.EndLocation
            });

            LogBuildEventArgs(e, "TargetStarted");

            _debuggerHost.DoExecutableBlockStarted(_callStack.ToArray());
        }
        internal BreakPoint BindBreakPoint(BreakPoint unboundBreakPoint)
        {
            BreakPoint boundBreakPoint = null;

            // Load the symbols, if not loaded already
            SymbolStore.Instance.LoadSymbols(unboundBreakPoint.ExecutablePath);

            PDB      pdb      = SymbolStore.Instance[unboundBreakPoint.ExecutablePath];
            PdbEntry bpSymbol = null;

            // First determine the target
            PdbEntry targetSymbol = null;

            PdbEntry[] targetSymbolEntries = pdb.TargetSymbolEntries.Values.ToArray();
            for (int i = 0; i < targetSymbolEntries.Length - 1; i++)
            {
                PdbEntry currEntry = targetSymbolEntries[i];
                PdbEntry nextEntry = targetSymbolEntries[i + 1];

                if (
                    currEntry.StartLocation.Y <= unboundBreakPoint.Location.Y &&
                    unboundBreakPoint.Location.Y < nextEntry.StartLocation.Y
                    )
                {
                    targetSymbol = currEntry;
                    break;
                }
            }

            // Project with no targets
            if (0 == targetSymbolEntries.Length)
            {
                targetSymbol = pdb.ProjectPdbEntry;
            }

            if ((0 != targetSymbolEntries.Length) && (null == targetSymbol))
            {
                // Ok so the break point is not between targets 1-2, 2-3, 3-4, 4-5
                // So it can be either before 1 or after 5
                // Before 1 => The BP is at project start
                // After 5 => BP at the last target
                if (targetSymbolEntries[0].StartLocation.Y >= unboundBreakPoint.Location.Y)
                {
                    targetSymbol = pdb.ProjectPdbEntry;
                }
                else
                {
                    targetSymbol = targetSymbolEntries[targetSymbolEntries.Length - 1];
                }
            }

            if (null == targetSymbol)
            {
                goto Done;
            }

            // Second determine the task
            PdbEntry taskSymbol = null;

            for (int i = 0; i < targetSymbol.Children.Count - 1; i++)
            {
                PdbEntry currEntry = targetSymbol.Children[i];
                PdbEntry nextEntry = targetSymbol.Children[i + 1];

                if (
                    currEntry.StartLocation.Y <= unboundBreakPoint.Location.Y &&
                    unboundBreakPoint.Location.Y < nextEntry.StartLocation.Y
                    )
                {
                    taskSymbol = currEntry;
                    break;
                }
            }

            if ((0 != targetSymbol.Children.Count) && (null == taskSymbol))
            {
                // Ok so the break point is not between tasks 1-2, 2-3, 3-4, 4-5
                // So it can be either before 1 or after 5
                // Before 1 => The BP is at target start
                // After 5 => BP at the last task
                // Take care of only 'after 5' case since not getting the symbol means 'before 1' case
                if (targetSymbol.Children[targetSymbol.Children.Count - 1].StartLocation.Y <= unboundBreakPoint.Location.Y)
                {
                    taskSymbol = targetSymbol.Children[targetSymbol.Children.Count - 1];
                }
            }

            // If we didnt get a task, no issues, set BP on the target
            bpSymbol = taskSymbol ?? targetSymbol;

            // Third create and note down the bound bp
            boundBreakPoint = _breakPoints.Find(bp => (bp.Location == bpSymbol.StartLocation));
            if (null == boundBreakPoint)
            {
                boundBreakPoint = new BreakPoint
                {
                    ExecutablePath = unboundBreakPoint.ExecutablePath,
                    Location       = bpSymbol.StartLocation
                };
                _breakPoints.Add(boundBreakPoint);
            }

Done:
            return(boundBreakPoint);
        }
Beispiel #5
0
 internal TargetStackFrame(PdbEntry targetSymbol)
 {
     TargetSymbol = targetSymbol;
     TaskNumber   = 0;
 }
Beispiel #6
0
        private void PopulateSymbolInformation()
        {
            using (XmlTextReader reader = new XmlTextReader(ExecutablePath))
            {
                // Read into the Project Element
                do
                {
                    reader.Read();
                }while (!reader.Name.Equals("Project", StringComparison.OrdinalIgnoreCase));

                // Set the start location
                ProjectPdbEntry.StartLocation = new Point(reader.LinePosition, reader.LineNumber);
                if (reader.IsEmptyElement)
                {
                    ProjectPdbEntry.EndLocation = ProjectPdbEntry.StartLocation;
                }

                // Start traversing the XML
                int currentTask = -1;
                Stack <PdbEntry> contextStack = new Stack <PdbEntry>();
                while (reader.Read())
                {
                    // Not interested in things other than Elements
                    if ((XmlNodeType.Element != reader.NodeType) && (XmlNodeType.EndElement != reader.NodeType))
                    {
                        continue;
                    }

                    // If it is the </Project> tag, set the end location
                    if ((XmlNodeType.EndElement == reader.NodeType) && reader.Name.Equals("Project", StringComparison.OrdinalIgnoreCase))
                    {
                        ProjectPdbEntry.EndLocation = new Point(reader.LinePosition, reader.LineNumber);
                        continue;
                    }

                    // Ignore everything except a Target element or its children
                    if (0 == contextStack.Count)
                    {
                        if (!reader.Name.Equals("Target", StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }

                        // We have just entered a Target element
                        PdbEntry symEntry = new PdbEntry(reader["Name"], ExecutablePath);
                        symEntry.StartLocation = new Point(reader.LinePosition, reader.LineNumber);
                        TargetSymbolEntries[reader["Name"]] = symEntry;    // Note that this enables the 'oveerriding' behavior of MSBuild Targets
                        contextStack.Push(symEntry);

                        // Close this context if it is an empty element
                        if (reader.IsEmptyElement)
                        {
                            symEntry.EndLocation = new Point(reader.LinePosition, reader.LineNumber);
                            contextStack.Pop();
                        }

                        // Lets proceed
                        continue;
                    }

                    // We are now in one of the target's children or it closing element.

                    // Lets eat up the PropertyGroup and ItemGroups
                    if (
                        reader.Name.Equals("PropertyGroup", StringComparison.OrdinalIgnoreCase) ||
                        reader.Name.Equals("ItemGroup", StringComparison.OrdinalIgnoreCase)
                        )
                    {
                        if (!reader.IsEmptyElement)
                        {
                            // Eat up the non-empty node and all its childres - burrrp!
                            string name  = reader.Name;
                            int    depth = reader.Depth;
                            do
                            {
                                reader.Read();
                            }while ((XmlNodeType.EndElement != reader.NodeType) || !reader.Name.Equals(name, StringComparison.OrdinalIgnoreCase) || (reader.Depth != depth));
                        }

                        continue;
                    }

                    // We could now be on a Task
                    if (XmlNodeType.Element == reader.NodeType)
                    {
                        PdbEntry taskSymEntry = new PdbEntry(reader.Name, ExecutablePath);
                        taskSymEntry.StartLocation = new Point(reader.LinePosition, reader.LineNumber);
                        if (!reader.IsEmptyElement)
                        {
                            // Not an empty task element - has some child elements like <Output> - so eat up all children
                            string nodeName  = reader.Name;
                            int    currDepth = reader.Depth;
                            do
                            {
                                reader.Read();
                            }while ((XmlNodeType.EndElement != reader.NodeType) || !reader.Name.Equals(nodeName, StringComparison.OrdinalIgnoreCase) || (reader.Depth != currDepth));
                        }

                        taskSymEntry.EndLocation = new Point(reader.LinePosition, reader.LineNumber);
                        contextStack.Peek().Children.Add(taskSymEntry);
                        currentTask++;

                        continue;
                    }

                    // Consider EndElement
                    if ((XmlNodeType.EndElement == reader.NodeType))
                    {
                        // Now Name has to be "Target"
                        Debug.Assert(reader.Name.Equals("Target", StringComparison.OrdinalIgnoreCase));

                        contextStack.Peek().EndLocation = new Point(reader.LinePosition, reader.LineNumber);
                        contextStack.Pop();
                        currentTask = -1;

                        continue;
                    }
                }
            }
        }