Repository: xpbob/CrashAnalysis Branch: master Commit: 934510dea770 Files: 22 Total size: 24.8 KB Directory structure: gitextract_od_bwa0o/ ├── CrashAnalysis-1.0-SNAPSHOT.jar ├── README.md ├── pom.xml └── src/ └── main/ └── java/ └── com/ └── xp/ ├── Entry.java ├── GuiLayout.java ├── checker/ │ ├── CheckerInterface.java │ ├── CompileChecker.java │ ├── DefaultChecker.java │ ├── JVMChecker.java │ └── MemoryChecker.java ├── element/ │ ├── Frame.java │ ├── ProblemFrame.java │ ├── ProcessFrame.java │ ├── SystemFrame.java │ └── ThreadFrame.java ├── handler/ │ ├── CommonHandler.java │ ├── ProblemFrameHandler.java │ ├── ProcessFrameHandler.java │ ├── SystemFrameHandler.java │ └── ThreadFrameHandler.java └── util/ ├── Common.java └── ReaderUtil.java ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ # CrashAnalysis ## 功能介绍 这是一个jvm crash分析工具,主要分析jvm crash的原因,以及常见的解决手段。 ## 使用方式 java -jar CrashAnalysis-1.0-SNAPSHOT.jar ${hs_err_pid.log} ${hs_err_pid.log} 是jvm crash后生成的日志。 ## 效果 分析完成后会展示出来诊断信息,其他信息都是用来验证诊断信息的。 ================================================ FILE: pom.xml ================================================ 4.0.0 com.xp CrashAnalysis 1.0-SNAPSHOT 1.8 1.8 UTF-8 org.apache.maven.plugins maven-jar-plugin true lib/ com.xp.Entry ================================================ FILE: src/main/java/com/xp/Entry.java ================================================ package com.xp; import com.xp.checker.*; import com.xp.handler.*; import javax.swing.*; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class Entry { public static void main(String[] args) throws IOException { String filePath = args[0]; ReadFile(filePath, buildHandler()); showWithGui(getLayout(buildChecker())); } public static void showWithGui(GuiLayout guiLayout) { if (guiLayout == null) { guiLayout = new DefaultChecker().check(); } JFrame f =new JFrame (); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JTabbedPane tp = new JTabbedPane(); f.setLayout(null); { JPanel jPanel = new JPanel(); JTextArea show = new JTextArea (); show.setText(guiLayout.getAdvice()); show.setLineWrap(true); show.setEditable(false); show.setColumns(100); show.setAlignmentX(0); jPanel.add(show); tp.add(jPanel); tp.setTitleAt(0,"诊断信息"); } int count =1; List showList = guiLayout.getShowList(); for (com.xp.element.Frame frame : showList) { JPanel jPanel = new JPanel(); JTextArea tmp = new JTextArea (); tmp.setLineWrap(true); tmp.setEditable(false); tmp.setColumns(100); tmp.setRows(50); tmp.setAlignmentX(0); tmp.setText(frame.toString()); jPanel.add(tmp); tp.add(jPanel); tp.setTitleAt(count++,frame.getFrameInfo()); } f.setContentPane(tp); f.pack(); f.setVisible(true); } public static CommonHandler buildHandler() { ProblemFrameHandler problemFrameHandler = new ProblemFrameHandler(); ThreadFrameHandler threadFrameHandler = new ThreadFrameHandler(); SystemFrameHandler systemFrameHandler = new SystemFrameHandler(); ProcessFrameHandler processFrameHandler = new ProcessFrameHandler(); problemFrameHandler.setNext(threadFrameHandler); threadFrameHandler.setNext(processFrameHandler); processFrameHandler.setNext(systemFrameHandler); return problemFrameHandler; } public static List buildChecker() { List checkerLists = new ArrayList<>(); checkerLists.add(new MemoryChecker()); checkerLists.add(new CompileChecker()); checkerLists.add(new JVMChecker()); return checkerLists; } public static GuiLayout getLayout(List checkerLists) { GuiLayout guiLayout = null; for (CheckerInterface checkerList : checkerLists) { guiLayout = checkerList.check(); if (guiLayout != null) { return guiLayout; } } return guiLayout; } public static void ReadFile(String filePath, CommonHandler handler) throws IOException { try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { String line = null; while ((line = reader.readLine()) != null) { handler.getMessage(line, reader); } } } } ================================================ FILE: src/main/java/com/xp/GuiLayout.java ================================================ package com.xp; import com.xp.element.Frame; import java.util.List; public class GuiLayout { private String advice; private List showList; public String getAdvice() { return advice; } public void setAdvice(String advice) { this.advice = advice; } public List getShowList() { return showList; } public void setShowList(List showList) { this.showList = showList; } } ================================================ FILE: src/main/java/com/xp/checker/CheckerInterface.java ================================================ package com.xp.checker; import com.xp.GuiLayout; public interface CheckerInterface { public GuiLayout check(); } ================================================ FILE: src/main/java/com/xp/checker/CompileChecker.java ================================================ package com.xp.checker; import com.xp.GuiLayout; import com.xp.element.*; import com.xp.util.Common; import java.util.ArrayList; import java.util.List; public class CompileChecker implements CheckerInterface { @Override public GuiLayout check() { String problemInfo = ProblemFrame.frame.getProblemInfo(); if (problemInfo != null && (problemInfo.contains("0x00")||problemInfo.contains(" J "))) { return buildLayout(); } return null; } public GuiLayout buildLayout(){ StringBuilder sb =new StringBuilder(); sb.append("这是一个解释器的问题,就是jvm把字节码转化成机器码出错了。"); sb.append(Common.NEXT_LINE); sb.append("引起这种情况的原因有很多,一般都是jdk的bug"); sb.append(Common.NEXT_LINE); sb.append("可以更换不同的jvm模式"); sb.append(Common.NEXT_LINE); sb.append("例如-XInt,纯解释模式"); sb.append(Common.NEXT_LINE); sb.append("在运行过程信息中有编译情况,可以查看具体编译到谁出错了"); sb.append(Common.NEXT_LINE); sb.append("可以通过排除编译这些类来试试"); sb.append(Common.NEXT_LINE); GuiLayout layout =new GuiLayout(); layout.setAdvice(sb.toString()); List frameList=new ArrayList<>(); frameList.add(ProblemFrame.frame); frameList.add(ThreadFrame.frame); frameList.add(ProcessFrame.frame); frameList.add(SystemFrame.frame); layout.setShowList(frameList); return layout; } } ================================================ FILE: src/main/java/com/xp/checker/DefaultChecker.java ================================================ package com.xp.checker; import com.xp.GuiLayout; import com.xp.element.*; import java.util.ArrayList; import java.util.List; public class DefaultChecker implements CheckerInterface { @Override public GuiLayout check() { return buildLayout(); } public GuiLayout buildLayout(){ GuiLayout layout =new GuiLayout(); layout.setAdvice("程序没有判断出问题,请联系作者。"); List frameList=new ArrayList<>(); frameList.add(ProblemFrame.frame); frameList.add(ThreadFrame.frame); frameList.add(ProcessFrame.frame); frameList.add(SystemFrame.frame); layout.setShowList(frameList); return layout; } } ================================================ FILE: src/main/java/com/xp/checker/JVMChecker.java ================================================ package com.xp.checker; import com.xp.GuiLayout; import com.xp.element.*; import com.xp.util.Common; import java.util.ArrayList; import java.util.List; public class JVMChecker implements CheckerInterface { @Override public GuiLayout check() { String exceptionInfo = ProblemFrame.frame.getExceptionInfo(); if (exceptionInfo != null) { return buildLayout(); } return null; } public GuiLayout buildLayout() { StringBuilder sb =new StringBuilder(); sb.append("这是jvm的错误导致的问题"); sb.append(Common.NEXT_LINE); sb.append("请根据后面给的问题点来进行分析,需要根据openjdk的实现来帮助分析问题。"); sb.append(Common.NEXT_LINE); sb.append("线程信息中的上下文也会告诉你代码执行到什么地方出的错"); sb.append(Common.NEXT_LINE); sb.append("在运行过程信息栏目中查看内部错误信息。"); sb.append(Common.NEXT_LINE); sb.append("这种错误有两个大方向可以排查"); sb.append(Common.NEXT_LINE); sb.append(" 1,操作系统方面:是否是系统资源问题或者是参数问题导致"); sb.append(Common.NEXT_LINE); sb.append(" 2,有第三方动态库的调用,导致错误"); sb.append(Common.NEXT_LINE); sb.append("如果不是以上情况,有可能是jdk的bug,换个系统,或者换个jdk吧。"); sb.append(Common.NEXT_LINE); GuiLayout layout =new GuiLayout(); layout.setAdvice(sb.toString()); List frameList=new ArrayList<>(); frameList.add(ProblemFrame.frame); frameList.add(ThreadFrame.frame); frameList.add(ProcessFrame.frame); frameList.add(SystemFrame.frame); layout.setShowList(frameList); return layout; } } ================================================ FILE: src/main/java/com/xp/checker/MemoryChecker.java ================================================ package com.xp.checker; import com.xp.GuiLayout; import com.xp.element.Frame; import com.xp.element.ProblemFrame; import com.xp.element.SystemFrame; import com.xp.element.ThreadFrame; import com.xp.util.Common; import java.util.ArrayList; import java.util.List; public class MemoryChecker implements CheckerInterface { @Override public GuiLayout check() { String problemInfo = ProblemFrame.frame.getProblemInfo(); if(problemInfo.contains("Native memory allocation")){ return buildLayout(); } return null; } public GuiLayout buildLayout(){ StringBuilder sb=new StringBuilder(); sb.append("这是一个内存申请问题。"); sb.append(Common.NEXT_LINE); sb.append("jvm默认提供一些解决方案"); sb.append(Common.NEXT_LINE); sb.append(" Reduce memory load on the system"); sb.append(Common.NEXT_LINE); sb.append(" Increase physical memory or swap space"); sb.append(Common.NEXT_LINE); sb.append(" Check if swap backing store is full"); sb.append(Common.NEXT_LINE); sb.append(" Use 64 bit Java on a 64 bit OS"); sb.append(Common.NEXT_LINE); sb.append(" Decrease Java heap size (-Xmx/-Xms)"); sb.append(Common.NEXT_LINE); sb.append(" Decrease number of Java threads"); sb.append(Common.NEXT_LINE); sb.append(" Decrease Java thread stack sizes (-Xss)"); sb.append(Common.NEXT_LINE); sb.append(" Set larger code cache with -XX:ReservedCodeCacheSize="); sb.append(Common.NEXT_LINE); sb.append("可以根据这些手段进行排查,下面的模版会提供系统内存使用的情况,可以做参考。"); sb.append(Common.NEXT_LINE); sb.append("如果发现物理内存充足,swap也充足,那可能是系统的参数限制了内存申请。"); sb.append(Common.NEXT_LINE); sb.append("例如/proc/sys/vm/max_map_count"); sb.append(Common.NEXT_LINE); sb.append("也或者是jdk版本和系统版本不对,导致内存申请失败"); sb.append(Common.NEXT_LINE); sb.append("如果想查具体原因,需要根据jvm源码和下面的堆栈进行分析"); GuiLayout layout=new GuiLayout(); layout.setAdvice(sb.toString()); List frames=new ArrayList<>(); frames.add(ProblemFrame.frame); frames.add(SystemFrame.frame); frames.add(ThreadFrame.frame); layout.setShowList(frames); return layout; } } ================================================ FILE: src/main/java/com/xp/element/Frame.java ================================================ package com.xp.element; public interface Frame { String getFrameInfo(); } ================================================ FILE: src/main/java/com/xp/element/ProblemFrame.java ================================================ package com.xp.element; import com.xp.util.Common; public class ProblemFrame implements Frame{ public static ProblemFrame frame = new ProblemFrame(); private String problemInfo; private String exceptionInfo; private ProblemFrame() { } public void setProblemInfo(String problemInfo) { this.problemInfo = problemInfo; } public String getProblemInfo() { return problemInfo; } public String getExceptionInfo() { return exceptionInfo; } public void setExceptionInfo(String exceptionInfo) { this.exceptionInfo = exceptionInfo; } @Override public String toString() { StringBuilder sb=new StringBuilder(); if(problemInfo!=null){ sb.append("问题模块:"); sb.append(Common.NEXT_LINE); sb.append(problemInfo); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } if(exceptionInfo!=null){ sb.append("异常模块:"); sb.append(Common.NEXT_LINE); sb.append(exceptionInfo); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } return sb.toString(); } @Override public String getFrameInfo() { return "可能的问题点"; } } ================================================ FILE: src/main/java/com/xp/element/ProcessFrame.java ================================================ package com.xp.element; import com.xp.util.Common; public class ProcessFrame implements Frame { public static ProcessFrame frame = new ProcessFrame(); private String exceptions; private String compilation; private String events; private ProcessFrame() { } public String getExceptions() { return exceptions; } public void setExceptions(String exceptions) { this.exceptions = exceptions; } public String getCompilation() { return compilation; } public void setCompilation(String compilation) { this.compilation = compilation; } public String getEvents() { return events; } public void setEvents(String events) { this.events = events; } @Override public String toString() { StringBuilder sb = new StringBuilder(); if (exceptions != null) { sb.append("jvm异常信息:"); sb.append(Common.NEXT_LINE); sb.append(exceptions); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } if (compilation != null) { sb.append("编译事件:"); sb.append(Common.NEXT_LINE); sb.append(compilation); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } if (events != null) { sb.append("事件信息:"); sb.append(Common.NEXT_LINE); sb.append(events); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } return sb.toString(); } @Override public String getFrameInfo() { return "运行过程信息"; } } ================================================ FILE: src/main/java/com/xp/element/SystemFrame.java ================================================ package com.xp.element; import com.xp.util.Common; public class SystemFrame implements Frame { public static SystemFrame frame = new SystemFrame(); private String memory; private SystemFrame() { } public String getMemory() { return memory; } public void setMemory(String memory) { this.memory = memory; } @Override public String toString() { StringBuilder sb = new StringBuilder(); if (memory != null) { sb.append("机器内存信息:"); sb.append(Common.NEXT_LINE); sb.append(memory); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } return sb.toString(); } @Override public String getFrameInfo() { return "系统信息"; } } ================================================ FILE: src/main/java/com/xp/element/ThreadFrame.java ================================================ package com.xp.element; import com.xp.util.Common; public class ThreadFrame implements Frame { public static ThreadFrame frame = new ThreadFrame(); private String currrentTheadInfo; private String stack; private ThreadFrame() { } public String getCurrrentTheadInfo() { return currrentTheadInfo; } public void setCurrrentTheadInfo(String currrentTheadInfo) { this.currrentTheadInfo = currrentTheadInfo; } public String getStack() { return stack; } public void setStack(String stack) { this.stack = stack; } @Override public String toString() { StringBuilder sb = new StringBuilder(); if (currrentTheadInfo != null) { sb.append("正在执行的线程信息:"); sb.append(Common.NEXT_LINE); sb.append(currrentTheadInfo); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } if (stack != null) { sb.append("对应的堆栈信息:"); sb.append(Common.NEXT_LINE); sb.append(stack); sb.append(Common.NEXT_LINE); sb.append(Common.LINE); sb.append(Common.NEXT_LINE); } return sb.toString(); } @Override public String getFrameInfo() { return "线程信息"; } } ================================================ FILE: src/main/java/com/xp/handler/CommonHandler.java ================================================ package com.xp.handler; import java.io.BufferedReader; public abstract class CommonHandler { private CommonHandler next; public void getMessage(String info, BufferedReader reader){ info = getMessageFromFile(info,reader); if(next!=null){ next.getMessage(info, reader); } } protected abstract String getMessageFromFile(String info, BufferedReader reader); public CommonHandler getNext() { return next; } public void setNext(CommonHandler next) { this.next = next; } } ================================================ FILE: src/main/java/com/xp/handler/ProblemFrameHandler.java ================================================ package com.xp.handler; import com.xp.element.ProblemFrame; import com.xp.util.Common; import com.xp.util.ReaderUtil; import java.io.BufferedReader; import java.io.IOException; public class ProblemFrameHandler extends CommonHandler { private CommonHandler next; private static final String FLAG = "#"; @Override protected String getMessageFromFile(String info, BufferedReader reader) { if (info.contains(FLAG)) { try { do { if(info.startsWith(Common.END_FLAG)) { break; } if(info.contains("Native memory allocation")){ StringBuilder sb= new StringBuilder(info); sb.append(Common.NEXT_LINE); sb.append(ReaderUtil.readFrameEndWithBlankLine(reader)); ProblemFrame.frame.setProblemInfo(sb.toString()); } if(info.contains("An unexpected error")){ ProblemFrame.frame.setExceptionInfo(ReaderUtil.readFrameLineWithLength(4,reader)); info=reader.readLine(); } if(info.contains("A fatal error")){ ProblemFrame.frame.setExceptionInfo(ReaderUtil.readFrameLineWithLength(4,reader)); info=reader.readLine(); } if (info.contains("Problematic frame")) { ProblemFrame.frame.setProblemInfo(ReaderUtil.readFrameWithEnd("#", reader)); } } while ((info = reader.readLine()) != null); } catch (IOException e) { e.printStackTrace(); } } return info; } } ================================================ FILE: src/main/java/com/xp/handler/ProcessFrameHandler.java ================================================ package com.xp.handler; import com.xp.element.ProcessFrame; import com.xp.util.Common; import com.xp.util.ReaderUtil; import java.io.BufferedReader; import java.io.IOException; public class ProcessFrameHandler extends CommonHandler { @Override protected String getMessageFromFile(String info, BufferedReader reader) { if (info.contains("P R O C E S S")) { try { while ((info = reader.readLine()) != null) { if (info.startsWith("Compilation events")) { ProcessFrame.frame.setCompilation(ReaderUtil.readFrameEndWithBlankLine(reader)); info = reader.readLine(); } if (info.startsWith("Internal exceptions ")) { ProcessFrame.frame.setExceptions(ReaderUtil.readFrameEndWithBlankLine(reader)); info = reader.readLine(); } if (info.startsWith("Events")) { ProcessFrame.frame.setEvents(ReaderUtil.readFrameEndWithBlankLine(reader)); info = reader.readLine(); } if (info.startsWith(Common.END_FLAG)) { break; } } } catch (IOException e) { e.printStackTrace(); } } return info; } } ================================================ FILE: src/main/java/com/xp/handler/SystemFrameHandler.java ================================================ package com.xp.handler; import com.xp.element.SystemFrame; import com.xp.util.ReaderUtil; import java.io.BufferedReader; import java.io.IOException; public class SystemFrameHandler extends CommonHandler { @Override protected String getMessageFromFile(String info, BufferedReader reader) { if (info.contains("S Y S T E M")) { try { SystemFrame.frame.setMemory(ReaderUtil.readFrameContainsWord("Memory", reader)); info = reader.readLine(); } catch (IOException e) { e.printStackTrace(); } } return info; } } ================================================ FILE: src/main/java/com/xp/handler/ThreadFrameHandler.java ================================================ package com.xp.handler; import com.xp.element.ThreadFrame; import com.xp.util.Common; import com.xp.util.ReaderUtil; import java.io.BufferedReader; import java.io.IOException; public class ThreadFrameHandler extends CommonHandler { @Override protected String getMessageFromFile(String info, BufferedReader reader) { if (info.contains("T H R E A D")) { try { ThreadFrame.frame.setCurrrentTheadInfo(ReaderUtil.readFrameContainsWord("Current thread", reader)); info = reader.readLine(); do { if(info.startsWith(Common.END_FLAG)) { break; } if (info.startsWith("Stack")) { StringBuilder sb = new StringBuilder(); sb.append(info); sb.append(Common.NEXT_LINE); sb.append(ReaderUtil.readFrameWithBlankCount(2,reader)); ThreadFrame.frame.setStack(sb.toString()); } } while ((info = reader.readLine()) != null); } catch (IOException e) { e.printStackTrace(); } } return info; } } ================================================ FILE: src/main/java/com/xp/util/Common.java ================================================ package com.xp.util; public class Common { public static final String NEXT_LINE="\r\n"; public static final String LINE="-------------------------------------------------------"; public static final String END_FLAG="--"; } ================================================ FILE: src/main/java/com/xp/util/ReaderUtil.java ================================================ package com.xp.util; import java.io.BufferedReader; import java.io.IOException; public class ReaderUtil { public static String readFrameLineWithLength(int length, BufferedReader reader) throws IOException { StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { if (line.trim().length() > length) { sb.append(line); while ((line = reader.readLine()) != null) { if (line.trim().length() > length) { sb.append(line); }else { break; } } break; } } return sb.toString(); } public static String readFrameContainsWord(String word, BufferedReader reader) throws IOException { StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { if (line.contains(word)) { sb.append(line); sb.append(Common.NEXT_LINE); break; } } return sb.toString(); } public static String readFrameEndWithBlankLine(BufferedReader reader) throws IOException { StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { if (line.trim().equals("")) { break; } sb.append(line); sb.append(Common.NEXT_LINE); } return sb.toString(); } public static String readFrameWithEnd(String end, BufferedReader reader) throws IOException { StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { if (line.trim().equals(end)) { break; } sb.append(line); sb.append(Common.NEXT_LINE); } return sb.toString(); } public static String readFrameWithBlankCount(int count, BufferedReader reader) throws IOException { StringBuilder sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { if (line.trim().equals("")) { count--; if(count==0){ break; } } sb.append(line); sb.append(Common.NEXT_LINE); } return sb.toString(); } }