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();
}
}