Exemplo n.º 1
0
        public void PrintManagedCallStacks()
        {
            //Threads test, get info of all managed threads found in dump
            context.WriteInfo("--- Managed callstacks ---");
            if (context.Runtime != null)
            {
                foreach (ClrThread thread in context.Runtime.Threads)
                {
                    if (!thread.IsAlive)
                    {
                        continue;
                    }

                    context.WriteInfo("Thread        {0}, managed id: {1}:", thread.OSThreadId, thread.ManagedThreadId);
                    context.WriteInfo("GC mode:      {0} ", thread.GcMode);
                    context.WriteInfo("Thread type:  {0}", thread);
                    context.WriteInfo("Callstack: {0:X} - {1:X}", thread.StackBase, thread.StackLimit);

                    // get last thrown exception of thread
                    ClrException lastException = thread.CurrentException;
                    if (lastException != null)
                    {
                        this.PrintException(lastException);
                    }
                    // walk each stack frame
                    foreach (ClrStackFrame frame in thread.StackTrace)
                    {
                        SDFileAndLineNumber info = frame.GetSourceLocation();
                        context.WriteLine("{0,12:X} {1,12:X} {2} - {3}:{4}", frame.StackPointer, frame.InstructionPointer, frame.DisplayString, info.File, info.Line);
                    }
                    context.WriteLine(null);
                }
                context.WriteInfo("Total amount of all (managed) threads: " + context.Runtime.Threads.Count);
            }
        }
Exemplo n.º 2
0
        private async Task <Tuple <SDFileAndLineNumber, string> > Address2MethodSourceAsync(ulong instrPtr, SDCDModule module)
        {
            ulong relativeIp    = instrPtr;
            var   systemContext = (SDCDSystemContext)analysisResult.SystemContext;

            // Calculate the relative IP to the base module.
            // For this we must subtract the start address of the whole module from the IP
            // The module start address from the parameter is only the start address of the segment.
            // We get the real module start address by subtracting the page offset multiplied by the page size from the segment start.
            ulong moduleStartAddress = module.StartAddress - (module.Offset * (uint)systemContext.PageSize);

            relativeIp -= moduleStartAddress + 1;

            string output = await processHandler.ExecuteProcessAndGetOutputAsync("addr2line", $"-f -C -e {module.LocalPath} 0x{relativeIp.ToString("X")}");

            string[] lines = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            if (lines.Length < 2)
            {
                Console.WriteLine($"Output of addr2line is invalid ({lines.Length} lines)! First line: {lines?[0]}");
                return(Tuple.Create <SDFileAndLineNumber, string>(new SDFileAndLineNumber(), null));
            }
            string methodName = lines[0];
            string fileLine   = lines[1];
            SDFileAndLineNumber sourceInfo = RetrieveSourceInfo(fileLine);

            return(Tuple.Create(sourceInfo, methodName));
        }
Exemplo n.º 3
0
        private async Task <Tuple <SDFileAndLineNumber, string> > Address2MethodSourceAsync(ulong instrPtr, SDCDModule module)
        {
            ulong  relativeIp     = instrPtr;
            string mainExecutable = ((SDCDSystemContext)analysisResult.SystemContext).FileName;

            mainExecutable = Path.GetFileName(mainExecutable);
            if (mainExecutable != module.FileName)
            {
                // Subtract modules start address unless it's the main executable
                relativeIp -= module.StartAddress + 1;
            }
            string output = await processHandler.ExecuteProcessAndGetOutputAsync("addr2line", $"-f -C -e {module.LocalPath} 0x{relativeIp.ToString("X")}");

            string[] lines = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            if (lines.Length < 2)
            {
                Console.WriteLine($"Output of addr2line is invalid ({lines.Length} lines)! First line: {lines?[0]}");
                return(Tuple.Create <SDFileAndLineNumber, string>(new SDFileAndLineNumber(), null));
            }
            string methodName = lines[0];
            string fileLine   = lines[1];
            SDFileAndLineNumber sourceInfo = RetrieveSourceInfo(fileLine);

            return(Tuple.Create(sourceInfo, methodName));
        }
Exemplo n.º 4
0
        // source location support, not implemented yet!
        //public string SourceFileName { get; set; }
        //public uint SourceLineNumber { get; set; }
        //public uint SourceLineNumberEnd { get; set; }
        //public uint SourceColumnNumber { get; set; }
        //public uint SourceColumnNumberEnd { get; set; }

        /// <summary>
        /// Constructor for native frame
        /// </summary>
        /// <param name="frame"></param>
        /// <param name="debugSymbols"></param>
        public CombinedStackFrame(DEBUG_STACK_FRAME frame, IDebugSymbols3 debugSymbols)
        {
            Type = StackFrameType.Native;             //native frame
            InstructionPointer = frame.InstructionOffset;
            StackPointer       = frame.StackOffset;
            ReturnOffset       = frame.ReturnOffset;

            uint  moduleIndex;
            ulong dummy;

            //if no module is associated with this frame, the method is unknown, can happen with CLR-JIT code
            if (debugSymbols.GetModuleByOffset(InstructionPointer, 0, out moduleIndex, out dummy) != 0)
            {
                ModuleName = "UNKNOWN";
                MethodName = "UNKNOWN";
                return;                           //no more action needed
            }
            var   name = new StringBuilder(1024); //create buffer for storing method name
            ulong displacement;
            uint  nameSize;

            Utility.CheckHRESULT(debugSymbols.GetNameByOffset(InstructionPointer, name, name.Capacity, out nameSize, out displacement));
            OffsetInMethod = displacement;             //offset of InstructionPointer and base location of symbol, could be null

            //get module name and method name, example for name :
            string[] parts = name.ToString().Split('!');
            ModuleName = parts[0];             //module is the first part before '!'
            if (parts.Length > 1)
            {
                MethodName = parts[1];                 //second part, after the '!'
            }
            if (string.IsNullOrEmpty(ModuleName))
            {
                ModuleName = "UNKNOWN";
            }
            // check if method name was found or not
            if (string.IsNullOrEmpty(MethodName))
            {
                MethodName = "UNKNOWN";
            }

            // get source information
            uint line;
            var  fileBuffer = new StringBuilder(4 * 1024);
            uint fileSize;

            debugSymbols.GetLineByOffset(InstructionPointer, out line, fileBuffer, fileBuffer.Capacity, out fileSize, out displacement);
            if (fileSize > 0)
            {
                this.SourceInfo = new SDFileAndLineNumber {
                    File = fileBuffer.ToString(), Line = (int)line
                };
            }
        }
Exemplo n.º 5
0
 public SDCombinedStackFrame(StackFrameType type, string moduleName, string methodName, ulong offsetInMethod, ulong ip, ulong sp, ulong returnOffset, ulong spOffset, SDFileAndLineNumber sourceInfo)
 {
     this.Type               = type;
     this.ModuleName         = moduleName;
     this.MethodName         = methodName;
     this.OffsetInMethod     = offsetInMethod;
     this.InstructionPointer = ip;
     this.StackPointer       = sp;
     this.ReturnOffset       = returnOffset;
     this.LinkedStackFrame   = null;
     this.StackPointerOffset = spOffset;
     this.SourceInfo         = sourceInfo;
 }
Exemplo n.º 6
0
        private SDFileAndLineNumber RetrieveSourceInfo(string output)
        {
            Match match = addr2lineRegex.Match(output);

            if (match.Success)
            {
                SDFileAndLineNumber sourceInfo = new SDFileAndLineNumber()
                {
                    File = match.Groups[1].Value,
                    Line = int.Parse(match.Groups[2].Value)
                };
                return(sourceInfo);
            }
            return(new SDFileAndLineNumber());
        }
Exemplo n.º 7
0
        private async Task AddSourceInfoAsync(SDCombinedStackFrame stackFrame, SDCDModule module)
        {
            Tuple <SDFileAndLineNumber, string> methodSource = await Address2MethodSourceAsync(stackFrame.InstructionPointer, module);

            SDFileAndLineNumber sourceInfo = methodSource.Item1;
            string methodName = methodSource.Item2;

            if (methodName != "??")
            {
                stackFrame.MethodName = methodName;
                if (sourceInfo.File != null && sourceInfo.File != "??")
                {
                    stackFrame.SourceInfo = sourceInfo;
                }
            }
        }
Exemplo n.º 8
0
        private static SDFileAndLineNumber FindNearestLine(PdbFunction function, int ilOffset)
        {
            int distance = int.MaxValue;
            var nearest  = new SDFileAndLineNumber();

            foreach (PdbSequencePointCollection sequenceCollection in function.SequencePoints)
            {
                foreach (PdbSequencePoint point in sequenceCollection.Lines)
                {
                    int dist = (int)Math.Abs(point.Offset - ilOffset);
                    if (dist < distance)
                    {
                        nearest.File = sequenceCollection.File.Name;
                        nearest.Line = (int)point.LineBegin;
                    }
                }
            }

            return(nearest);
        }
Exemplo n.º 9
0
        private async Task <Tuple <SDFileAndLineNumber, string> > Address2MethodSourceAsync(ulong instrPtr, SDCDModule module)
        {
            ulong relativeIp = instrPtr;

            if (module.DebugSymbolPath != null && module.DebugSymbolPath != "")
            {
                // If there is a debug file, link it (required for addr2line to find the dbg file)
                LinkDebugFile(module.LocalPath, module.DebugSymbolPath);
            }
            string output = await processHandler.ExecuteProcessAndGetOutputAsync("addr2line", $"-f -C -e {module.LocalPath} 0x{relativeIp.ToString("X")}");

            string[] lines = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            if (lines.Length < 2)
            {
                Console.WriteLine($"Output of addr2line is invalid ({lines.Length} lines)! First line: {lines?[0]}");
                return(Tuple.Create <SDFileAndLineNumber, string>(new SDFileAndLineNumber(), null));
            }
            string methodName = lines[0];
            string fileLine   = lines[1];
            SDFileAndLineNumber sourceInfo = RetrieveSourceInfo(fileLine);

            return(Tuple.Create(sourceInfo, methodName));
        }
Exemplo n.º 10
0
        public CombinedStackFrame(ClrStackFrame frame)
        {
            if (frame.Kind == ClrStackFrameType.ManagedMethod)
            {
                Type = StackFrameType.Managed;
            }
            if (frame.Kind == ClrStackFrameType.Runtime)
            {
                Type = StackFrameType.Special;
            }

            InstructionPointer = frame.InstructionPointer;
            StackPointer       = frame.StackPointer;

            if (frame.Method == null)
            {
                MethodName = frame.DisplayString;                 //for example GCFrame
                return;
            }

            MethodName = frame.Method.GetFullSignature();
            if (frame.Method.Type != null)
            {
                ModuleName = Path.GetFileNameWithoutExtension(frame.Method.Type.Module.Name);
                if (string.IsNullOrEmpty(ModuleName))
                {
                    ModuleName = "UNKNOWN";
                }
            }

            // calculate IL offset with instruction pointer of frame and instruction pointer
            // in the target dump file of the start of the method's assembly
            OffsetInMethod = InstructionPointer - frame.Method.NativeCode;

            this.SourceInfo = frame.GetSourceLocation();
        }