Esempio n. 1
0
        private static RaygunStackTraceFrame[] BuildNativeStackTrace(Dictionary <IntPtr, RaygunImageInfo> images, Exception exception)
        {
            var lines = new List <RaygunStackTraceFrame>();

            var stackTrace = new StackTrace(exception, true);
            var frames     = stackTrace.GetFrames();

            foreach (StackFrame frame in frames)
            {
                if (frame.HasNativeImage())
                {
                    IntPtr nativeIP        = frame.GetNativeIP();
                    IntPtr nativeImageBase = frame.GetNativeImageBase();

                    if (!images.ContainsKey(nativeImageBase))
                    {
                        RaygunImageInfo imageInfo = ReadImage(nativeImageBase);
                        images[nativeImageBase] = imageInfo;
                    }

                    var line = new RaygunStackTraceFrame
                    {
                        IP        = nativeIP.ToInt64(),
                        ImageBase = nativeImageBase.ToInt64(),
                        Raw       = frame.ToString()
                    };

                    ParseRawStackTraceLine(line);

                    lines.Add(line);
                }
            }

            return(lines.Count == 0 ? null : lines.ToArray());
        }
Esempio n. 2
0
        private static RaygunStackTraceFrame[] BuildStackTrace(Exception exception)
        {
            var lines = new List <RaygunStackTraceFrame>();

            if (exception.StackTrace != null)
            {
                char[] separators = { '\r', '\n' };
                var    frames     = exception.StackTrace.Split(separators, StringSplitOptions.RemoveEmptyEntries);
                foreach (string line in frames)
                {
                    // Trim the stack trace line
                    string stackTraceLine = line.Trim();
                    if (stackTraceLine.StartsWith(CLASS_NAME_PREFIX))
                    {
                        stackTraceLine = stackTraceLine.Substring(CLASS_NAME_PREFIX.Length);
                    }

                    RaygunStackTraceFrame stackTraceFrame = new RaygunStackTraceFrame
                    {
                        Raw = stackTraceLine
                    };

                    ParseRawStackTraceLine(stackTraceFrame);

                    lines.Add(stackTraceFrame);
                }
            }

            return(lines.Count == 0 ? null : lines.ToArray());
        }
Esempio n. 3
0
        private static void ParseRawStackTraceLine(RaygunStackTraceFrame stackTraceFrame)
        {
            if (!string.IsNullOrWhiteSpace(stackTraceFrame.Raw))
            {
                string stackTraceLine = stackTraceFrame.Raw;

                // Find the separation between class name and method name:
                int methodNameIndex = stackTraceLine.IndexOf("(");
                if (methodNameIndex > 0)
                {
                    if (stackTraceLine[methodNameIndex - 1] == '>')
                    {
                        // The method has generic parameters, so we need to do a little more work to find the separation between class and method names

                        methodNameIndex -= 2; // start before the angle bracket we just found
                        int angleBracketPairing = 1;
                        while (methodNameIndex > 0 && angleBracketPairing != 0)
                        {
                            char c = stackTraceLine[methodNameIndex];
                            if (c == '>')
                            {
                                angleBracketPairing++;
                            }
                            else if (c == '<')
                            {
                                angleBracketPairing--;
                            }

                            methodNameIndex--;
                        }
                    }

                    methodNameIndex = stackTraceLine.LastIndexOf(METHOD_NAME_PREFIX, methodNameIndex);
                    if (methodNameIndex > 0)
                    {
                        // After finding the separation between class name and method name, the class name is the first part of the string:
                        stackTraceFrame.ClassName = stackTraceLine.Substring(0, methodNameIndex);

                        // Find the separation between method name and file name:
                        methodNameIndex += METHOD_NAME_PREFIX.Length;
                        int fileNameIndex = stackTraceLine.IndexOf(FILE_NAME_PREFIX, methodNameIndex);
                        if (fileNameIndex > 0)
                        {
                            stackTraceFrame.MethodName = stackTraceLine.Substring(methodNameIndex, fileNameIndex - methodNameIndex);

                            // Find the separation between file name and line number:
                            fileNameIndex += FILE_NAME_PREFIX.Length;
                            int lineNumberIndex = stackTraceLine.IndexOf(LINE_NUMBER_PREFIX, fileNameIndex);
                            if (lineNumberIndex > 0)
                            {
                                stackTraceFrame.FileName = stackTraceLine.Substring(fileNameIndex, lineNumberIndex - fileNameIndex);

                                // Parse the line number:
                                lineNumberIndex += LINE_NUMBER_PREFIX.Length;
                                string lineNumberStr = stackTraceLine.Substring(lineNumberIndex);

                                if (int.TryParse(lineNumberStr, out var lineNumber))
                                {
                                    stackTraceFrame.LineNumber = lineNumber;
                                }
                            }
                            else
                            {
                                // In this case, the frame does not have a line number:
                                stackTraceFrame.FileName = stackTraceLine.Substring(fileNameIndex);
                            }
                        }
                        else
                        {
                            // In this case, the frame only has method and class names:
                            stackTraceFrame.MethodName = stackTraceLine.Substring(methodNameIndex);
                        }
                    }
                }
            }
        }