堆栈调试工具

一、背景

在开发过程中经常遇到一条打印触发了之后,不知道这条打印具体是哪条函数触发的,并且是从哪调用过来的。使用断点的话会把整个进程卡主,并且无法往回跳断点,因此做出这个堆栈查看工具。

二、工具功能

1.调试过程中选中打印可以显示这个打印的堆栈到一个工具上。

2.可以在真机调试的时候,也可以通过局域网调试和查看堆栈。

3.可以对打印进行分类,避免打印报错时,打印过多把打印刷掉。

4.工具可以支持任意软件开发、任意语言开发,接入即可使用。

三、工具开发

1.使用C# Winform实现工具界面。

2.开发代码实现TCP连接堆栈调试工具。

3.开发代码实现打印触发时发送堆栈数据。

4.java堆栈获取代码

@SneakyThrows
    public String format(LoggingEvent event) {
        if(!AppConfig.isOpenConsole)
            return super.format(event);
        String msg = msgFormat(event);
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
 
        traceDataList.clear();
        TraceData data = null;
        boolean isAdd=false;
        for (int i = 0; i < stackTrace.length; i++) {
            StackTraceElement stackTraceElement = stackTrace[i];
            String className = stackTraceElement.getClassName();
            String classPath = Paths.get(rootPath, className.replace(".", "/") + ".java").toString();
            String packageName = className.replace(".", "/") + ".class";
            URL url = Thread.currentThread().getContextClassLoader().getResource(packageName);
 
 
            if (url != null && "jar".equals(url.getProtocol())) {
                String jarPath = url.getPath();
                jarPath = jarPath.replace("%20", " ");
                jarPath = jarPath.substring(6, jarPath.lastIndexOf('!'));
                jarPath = jarPath.replace("/", "\");
                classPath = Paths.get(jarExportPath, className.replace(".", "/") + ".java").toString();
                classPath = String.format("%s*%s*%s", jarPath, jarExportPath, classPath);
                //String path = Thread.currentThread().getContextClassLoader().getResource("").toString() ;
//                System.out.println("---------------");
//
//                System.out.println(packageName);
//                System.out.println(classPath);
//                System.out.println("---------------");
            }
 
            TraceData traceData = new TraceData(classPath, stackTraceElement.getLineNumber(), stackTraceElement.getMethodName());
            traceDataList.add(traceData.GetJsonObject());
            if(isAdd){
                isAdd=false;
                data = traceData;
            }
            if ((stackTraceElement.getMethodName().equals("info")
                    || stackTraceElement.getMethodName().equals("debug"))) {
                isAdd=true;
 
            }
 
        }
 
        if (data != null) {
            JSONArray jsonArray = new JSONArray(traceDataList);
            NetLogMgr.SendData(msg, data.getPath(), data.getLine(), data.getFuncName(), jsonArray, 1);
        } else {
            StackTraceElement element = stackTrace[0];
            String className = element.getClassName();
            String classPath = Paths.get(rootPath, className.replace(".", "/") + ".java").toString();
            JSONArray jsonArray = new JSONArray(traceDataList);
            NetLogMgr.SendData(msg, classPath, element.getLineNumber(), element.getMethodName(), jsonArray, 1);
 
        }
        if (msg.contains(closeString)) {
            Net.Close();
        }
 
        return super.format(event);
    }

5.C#堆栈获取

public static void Print(string message)
{
           
            StackTrace stacktrace = new StackTrace(true);
            traceArr.Clear();
            MsgData data = new MsgData();
            for (int i = 0; i < stacktrace.FrameCount; i++)
            {
                StackFrame stackFrame = stacktrace.GetFrame(i);
                MsgData msgData = new MsgData();
                msgData.path = stackFrame.GetFileName();
                msgData.line = stackFrame.GetFileLineNumber();
                msgData.funcName = stackFrame.GetMethod().Name;
                traceArr.Add(msgData.GetJsonObject());
                if (i == 4)
                {
                    data = msgData;
                }
            }
            if(stacktrace.FrameCount!=0)
                Net.SendMsg(GetJsonString(message, data.path, data.line, data.funcName, traceArr));
            else
            {
                Net.SendMsg(GetJsonString(message, "", 0, "", traceArr));
            }
}

四、工具成品

以网页开发为例(IDEA)

1.打印展示

堆栈调试工具

  1. 打印过滤
堆栈调试工具

  1. 堆栈展示
堆栈调试工具

4.点击IDE跳转

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章