crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/files/SummaryFile.java
changeset 4 615035072f7e
parent 0 5ad7ad99af01
child 16 72f198be1c1d
equal deleted inserted replaced
3:431bbaccaec8 4:615035072f7e
    21 import java.io.*;
    21 import java.io.*;
    22 import javax.xml.parsers.*;
    22 import javax.xml.parsers.*;
    23 import org.eclipse.jface.resource.ImageDescriptor;
    23 import org.eclipse.jface.resource.ImageDescriptor;
    24 import org.eclipse.ui.*;
    24 import org.eclipse.ui.*;
    25 import org.w3c.dom.*;
    25 import org.w3c.dom.*;
       
    26 
       
    27 import com.nokia.s60tools.crashanalyser.containers.OstTrace;
    26 import com.nokia.s60tools.crashanalyser.containers.RegisterDetails;
    28 import com.nokia.s60tools.crashanalyser.containers.RegisterDetails;
    27 import com.nokia.s60tools.crashanalyser.containers.CodeSegment;
    29 import com.nokia.s60tools.crashanalyser.containers.CodeSegment;
    28 import com.nokia.s60tools.crashanalyser.containers.Message;
    30 import com.nokia.s60tools.crashanalyser.containers.Message;
    29 import com.nokia.s60tools.crashanalyser.containers.EventLog;
    31 import com.nokia.s60tools.crashanalyser.containers.EventLog;
    30 import com.nokia.s60tools.crashanalyser.containers.Process;
    32 import com.nokia.s60tools.crashanalyser.containers.Process;
    42  * A summary file is a crash file which has not been fully decoded.
    44  * A summary file is a crash file which has not been fully decoded.
    43  * A summary file has been decoded without symbol information and it therefore
    45  * A summary file has been decoded without symbol information and it therefore
    44  * does not contain stack information. A summary file is a base class for CrashFile. 
    46  * does not contain stack information. A summary file is a base class for CrashFile. 
    45  *
    47  *
    46  */
    48  */
    47 public class SummaryFile extends CrashAnalyserFile implements IEditorInput {
    49 public class SummaryFile extends CrashAnalyserFile implements IEditorInput, Cloneable {
       
    50 
       
    51 	public enum ContentType {CRASH, REGMSG, REPORT};
    48 
    52 
    49 	// XML tags
    53 	// XML tags
    50 	public static final String TAG_SYMBOL_SET = "symbol_set";
    54 	public static final String TAG_SYMBOL_SET = "symbol_set";
    51 	public static final String TAG_SYMBOL = "symbol";
    55 	public static final String TAG_SYMBOL = "symbol";
    52 	public static final String TAG_SOURCE = "source";
    56 	public static final String TAG_SOURCE = "source";
    57 	public static final String TAG_ID = "id";
    61 	public static final String TAG_ID = "id";
    58 	public static final String TAG_STACK_ENTRY = "stack_entry";
    62 	public static final String TAG_STACK_ENTRY = "stack_entry";
    59 	public static final String TAG_CODESEG = "codeseg";
    63 	public static final String TAG_CODESEG = "codeseg";
    60 	public static final String TAG_REGISTER_SET = "register_set";
    64 	public static final String TAG_REGISTER_SET = "register_set";
    61 	public static final String TAG_SEG_EVENT_LOG = "seg_event_log";
    65 	public static final String TAG_SEG_EVENT_LOG = "seg_event_log";
       
    66 	public static final String TAG_SEG_TRACES = "seg_traces";
    62 	public static final String TAG_MESSAGE = "message";
    67 	public static final String TAG_MESSAGE = "message";
    63 	public static final String TAG_VI_ENTRY = "vi_entry";
    68 	public static final String TAG_VI_ENTRY = "vi_entry";
    64 	public static final String TAG_SOURCE_INFO = "source_info";
    69 	public static final String TAG_SOURCE_INFO = "source_info";
    65 	public static final String TAG_TYPE = "type";
    70 	public static final String TAG_TYPE = "type";
    66 	public static final String TAG_SEGMENT = "segment";
    71 	public static final String TAG_SEGMENT = "segment";
    72 	protected Map<Integer, Message> messages = null;
    77 	protected Map<Integer, Message> messages = null;
    73 	protected Map<Integer, Stack> stacks = null;
    78 	protected Map<Integer, Stack> stacks = null;
    74 	protected Map<Integer, RegisterSet> registerSets = null;
    79 	protected Map<Integer, RegisterSet> registerSets = null;
    75 	protected List<RegisterDetails> registerDetails = null;
    80 	protected List<RegisterDetails> registerDetails = null;
    76 	protected EventLog eventLog = null;
    81 	protected EventLog eventLog = null;
       
    82 	protected OstTrace ostTrace = null;
    77 	protected Summary crashSummary = null;
    83 	protected Summary crashSummary = null;
    78 	protected String sourceFileType = "";
    84 	protected String sourceFileType = "";
    79 	protected String sourceFileName = "";
    85 	protected String sourceFileName = "";
    80 	protected String sourceFilePath = "";
    86 	protected String sourceFilePath = "";
    81 
    87 
       
    88 	
    82 	/**
    89 	/**
    83 	 * Constructor
    90 	 * Constructor
    84 	 * @param filePath file path to this crash file
    91 	 * @param filePath file path to this crash file
    85 	 * @param library error library
    92 	 * @param library error library
    86 	 */
    93 	 */
    87 	protected SummaryFile(String filePath, ErrorLibrary library) {
    94 	protected SummaryFile(String filePath, ErrorLibrary library) {
    88 		super(filePath, library);
    95 		super(filePath, library);
    89 	}
    96 	}
    90 	
    97 	
    91 	/**
    98 	/**
       
    99 	 * Constructor
       
   100 	 * @param filePath file path to this crash file
       
   101 	 * @param library error library
       
   102 	 */
       
   103 	protected SummaryFile(String filePath, ErrorLibrary library, Thread thread) {
       
   104 		super(filePath, library);
       
   105 		threadInfo = thread;
       
   106 	}
       
   107 
       
   108 	public Object clone() {
       
   109 		SummaryFile newSummaryFile = null;
       
   110 		try {
       
   111 			// Just shallow copy (i.e. no need to read information from file)
       
   112 			newSummaryFile = (SummaryFile) super.clone();
       
   113 		} catch (CloneNotSupportedException ex) {
       
   114 			// ignore
       
   115 		}
       
   116 		return newSummaryFile;
       
   117 	}
       
   118 	
       
   119 	
       
   120 
       
   121 	/**
    92 	 * Returns the file type of this crash file.
   122 	 * Returns the file type of this crash file.
    93 	 * @return "Decoded File"
   123 	 * @return "Decoded File"
    94 	 */
   124 	 */
    95 	public String getFileType() {
   125 	public String getFileType() {
    96 		return "Partially Decoded File";
   126 		return "Partially Decoded File";
   104 		return sourceFileName;
   134 		return sourceFileName;
   105 	}
   135 	}
   106 	
   136 	
   107 	public String getSourceFilePath() {
   137 	public String getSourceFilePath() {
   108 		return sourceFilePath;
   138 		return sourceFilePath;
       
   139 	}
       
   140 	
       
   141 	
       
   142 	public void setThread(Thread thread) {
       
   143 		threadInfo = thread;
       
   144 		panicCategory = threadInfo.getExitCategory();
       
   145 		panicCode = threadInfo.getExitReason();
       
   146 		threadName = threadInfo.getFullName();
   109 	}
   147 	}
   110 	
   148 	
   111 	public List<Stack> getStandAloneStacks() {
   149 	public List<Stack> getStandAloneStacks() {
   112 		if (stacks != null && !stacks.isEmpty()) {
   150 		if (stacks != null && !stacks.isEmpty()) {
   113 			return new ArrayList<Stack>(stacks.values());
   151 			return new ArrayList<Stack>(stacks.values());
   139 		}
   177 		}
   140 		return false;
   178 		return false;
   141 	}
   179 	}
   142 	
   180 	
   143 	/**
   181 	/**
       
   182 	 * Returns the content type of the file.
       
   183 	 * @return Returns crash/registration/report. If not found returns crash. 
       
   184 	 */
       
   185 	public ContentType getContentType() {
       
   186 		List<Message> msgs = getMessages();
       
   187 		if (msgs != null && !msgs.isEmpty()) {
       
   188 			for (int i = 0; i < msgs.size(); i++) {
       
   189 				if (Message.MessageTypes.MESSAGE.equals(msgs.get(i).getMessageType()) &&
       
   190 						msgs.get(i).getTitle().equals("MobileCrash content type")) {
       
   191 					if(msgs.get(i).getMessage().equals("registration")) 
       
   192 						return ContentType.REGMSG;
       
   193 					else if (msgs.get(i).getMessage().equals("report")) 
       
   194 						return ContentType.REPORT;
       
   195 				}
       
   196 			}
       
   197 		}
       
   198 		// Returns crash by default.
       
   199 		return ContentType.CRASH; 
       
   200 	}
       
   201 
       
   202 	/**
   144 	 * Returns all messages
   203 	 * Returns all messages
   145 	 * @return all messages
   204 	 * @return all messages
   146 	 */
   205 	 */
   147 	public List<Message> getMessages() {
   206 	public List<Message> getMessages() {
   148 		List<Message> msgs = new ArrayList<Message>();
   207 		List<Message> msgs = new ArrayList<Message>();
   182 		file.doRead();
   241 		file.doRead();
   183 		return file;
   242 		return file;
   184 	}
   243 	}
   185 
   244 
   186 	/**
   245 	/**
       
   246 	 * Reads crash file
       
   247 	 * @param folder where xml file is
       
   248 	 * @param library error library
       
   249 	 * @param thread thread
       
   250 	 * @return read crash file or null
       
   251 	 */
       
   252 	public static SummaryFile read(String folder, ErrorLibrary library, Thread thread) {
       
   253 		String summaryFile = findFile(folder,"xml");
       
   254 		
       
   255 		// summary file doesn't exist
       
   256 		if (summaryFile == null)
       
   257 			return null;
       
   258 		
       
   259 		SummaryFile file = new SummaryFile(summaryFile, library, thread);
       
   260 		file.doRead();
       
   261 		return file;
       
   262 	}
       
   263 	
       
   264 		/**
   187 	 * Writes crash file into text or html file
   265 	 * Writes crash file into text or html file
   188 	 * @param filePathWithoutFileName file path where file is to be written to
   266 	 * @param filePathWithoutFileName file path where file is to be written to
   189 	 * @param html if false a .txt file is created. if true a .html file is created
   267 	 * @param html if false a .txt file is created. if true a .html file is created
   190 	 */
   268 	 */
   191 	public void writeTo(String filePathWithoutFileName, boolean html) {
   269 	public void writeTo(String filePathWithoutFileName, boolean html) {
   241 							writeLine(out, "Stack Pointer", thread.getStackPointer());
   319 							writeLine(out, "Stack Pointer", thread.getStackPointer());
   242 							writeLine(out, "Link Register", thread.getLinkRegister());
   320 							writeLine(out, "Link Register", thread.getLinkRegister());
   243 							writeLine(out, "Program Counter", thread.getProgramCounter());
   321 							writeLine(out, "Program Counter", thread.getProgramCounter());
   244 							panicDescription = thread.getPanicDescription();
   322 							panicDescription = thread.getPanicDescription();
   245 						}
   323 						}
       
   324 					} else if (threadInfo != null) {
       
   325 						Process threadProcess = getProcessByThread(threadInfo.getId());
       
   326 						
       
   327 						if (threadProcess != null)
       
   328 							writeLine(out, "Process", threadProcess.getName());
       
   329 						
       
   330 						writeLine(out, "Thread", threadInfo.getFullName());
       
   331 						writeLine(out, "Stack Pointer", threadInfo.getStackPointer());
       
   332 						writeLine(out, "Link Register", threadInfo.getLinkRegister());
       
   333 						writeLine(out, "Program Counter", threadInfo.getProgramCounter());
       
   334 						panicDescription = threadInfo.getPanicDescription();						
   246 					}
   335 					}
   247 					
   336 					
   248 					// write crash summary to file
   337 					// write crash summary to file
   249 					if (crashSummary != null) {
   338 					if (crashSummary != null) {
   250 						crashSummary.writeTo(out);
   339 						crashSummary.writeTo(out);
   273 					
   362 					
   274 					// write event log to file
   363 					// write event log to file
   275 					if (eventLog != null)
   364 					if (eventLog != null)
   276 						eventLog.writeTo(out);					
   365 						eventLog.writeTo(out);					
   277 						
   366 						
       
   367 					// write OST trace to file
       
   368 					if (ostTrace != null)
       
   369 						ostTrace.writeTo(out);					
       
   370 
   278 					// write process data to file
   371 					// write process data to file
   279 					if (process != null) {
   372 					if (process != null) {
   280 						process.writeTo(out, Process.StackItems.ALL, html);
   373 						process.writeTo(out, Process.StackItems.ALL, html);
   281 						out.newLine();
   374 						out.newLine();
   282 					}
   375 					}
   450 			nl = docEle.getElementsByTagName(TAG_SEG_EVENT_LOG);
   543 			nl = docEle.getElementsByTagName(TAG_SEG_EVENT_LOG);
   451 			if (nl != null && nl.getLength() > 0) {
   544 			if (nl != null && nl.getLength() > 0) {
   452 				eventLog = EventLog.read((Element)nl.item(0));
   545 				eventLog = EventLog.read((Element)nl.item(0));
   453 			}
   546 			}
   454 			
   547 			
       
   548 			// read OST traces
       
   549 			nl = docEle.getElementsByTagName(TAG_SEG_TRACES);
       
   550 			if (nl != null && nl.getLength() > 0) {
       
   551 				ostTrace = OstTrace.read((Element)nl.item(0));
       
   552 			}
       
   553 
   455 			// read messages from xml
   554 			// read messages from xml
   456 			nl = docEle.getElementsByTagName(TAG_MESSAGE);
   555 			nl = docEle.getElementsByTagName(TAG_MESSAGE);
   457 			if (nl != null && nl.getLength() > 0) {
   556 			if (nl != null && nl.getLength() > 0) {
   458 				for (int i = 0; i < nl.getLength(); i++) {
   557 				for (int i = 0; i < nl.getLength(); i++) {
   459 					Element el = (Element)nl.item(i);
   558 					Element el = (Element)nl.item(i);
   590 			if (!"".equals(crashSummary.getCrashDate()) && !"".equals(crashSummary.getCrashTime()))
   689 			if (!"".equals(crashSummary.getCrashDate()) && !"".equals(crashSummary.getCrashTime()))
   591 				time = crashSummary.getCrashDate() + " " + crashSummary.getCrashTime();
   690 				time = crashSummary.getCrashDate() + " " + crashSummary.getCrashTime();
   592 			
   691 			
   593 			// set panic data
   692 			// set panic data
   594 			Process process = getCrashedProcess();
   693 			Process process = getCrashedProcess();
       
   694 			processCount = getProcessCount();
   595 			if (process != null) {
   695 			if (process != null) {
   596 				Thread firstThread = process.getFirstThread();
   696 				Thread firstThread = process.getFirstThread();
   597 				if (firstThread != null) {
   697 				if (firstThread != null) {
   598 					panicCategory = firstThread.getExitCategory();
   698 					panicCategory = firstThread.getExitCategory();
   599 					panicCode = firstThread.getExitReason();
   699 					panicCode = firstThread.getExitReason();
   600 					threadName = firstThread.getFullName();
   700 					threadName = firstThread.getFullName();
   601 				}
   701 				}
       
   702 			} else if (threadInfo != null) {
       
   703 				panicCategory = threadInfo.getExitCategory();
       
   704 				panicCode = threadInfo.getExitReason();
       
   705 				threadName = threadInfo.getFullName();
   602 			}
   706 			}
   603 
   707 
   604 			formatDescription();
   708 			formatDescription();
   605 		}catch(Exception e) {
   709 		}catch(Exception e) {
   606 			e.printStackTrace();
   710 			e.printStackTrace();
   608 	}
   712 	}
   609 
   713 
   610 	/**
   714 	/**
   611 	 * Formats a description for this crash. 
   715 	 * Formats a description for this crash. 
   612 	 */
   716 	 */
   613 	void formatDescription() {
   717 	public void formatDescription() {
   614 		Thread thread = null;
   718 		Thread thread = null;
   615 		
   719 		
       
   720 		if (threadInfo != null) {
       
   721 			thread = threadInfo;
       
   722 		}
   616 		// get the first thread of the first process
   723 		// get the first thread of the first process
   617 		if (processes != null && !processes.isEmpty()) {
   724 		else if (processes != null && !processes.isEmpty()) {
   618 			Process[] processesArray = processes.values().toArray(new Process[processes.values().size()]);
   725 			thread = getCrashedThread();
   619 			Process process = processesArray[0];
   726 		}
   620 			thread = process.getFirstThread();
   727 
   621 		}
   728 		if (thread != null) {
   622 		
   729 			description = HtmlFormatter.formatCrashFileDescription(crashSummary, getMessages(), thread);
   623 		description = HtmlFormatter.formatCrashFileDescription(crashSummary, getMessages(), thread);
   730 			shortDescription = HtmlFormatter.formatCrashFileDescription(crashSummary, null, thread);
   624 		shortDescription = HtmlFormatter.formatCrashFileDescription(crashSummary, null, thread);
   731 		}
   625 	}
   732 	}
   626 	
   733 	
   627 	public Summary getSummary() {
   734 	public Summary getSummary() {
   628 		return crashSummary;
   735 		return crashSummary;
   629 	}
   736 	}
   632 	 * Get crashed process
   739 	 * Get crashed process
   633 	 * 
   740 	 * 
   634 	 * @return first process or null
   741 	 * @return first process or null
   635 	 */
   742 	 */
   636 	public Process getCrashedProcess() {
   743 	public Process getCrashedProcess() {
       
   744 		if (threadInfo != null) {
       
   745 			return null;
       
   746 		}
       
   747 		
   637 		Process crashedProcess = null;
   748 		Process crashedProcess = null;
   638 		if (processes != null && !processes.isEmpty()) {
   749 		if (processes != null && !processes.isEmpty()) {
   639 			Process[] processesArray = processes.values().toArray(new Process[processes.values().size()]);
   750 			Process[] processesArray = processes.values().toArray(new Process[processes.values().size()]);
   640 			for (Process process : processesArray) {
   751 			for (Process process : processesArray) {
   641 				for (Thread thread : process.getThreads()) {
   752 				for (Thread thread : process.getThreads()) {
   648 			}
   759 			}
   649 		}
   760 		}
   650 		return crashedProcess;
   761 		return crashedProcess;
   651 	}
   762 	}
   652 	
   763 	
       
   764 	/**
       
   765 	 * Get crashed process
       
   766 	 * 
       
   767 	 * @return first crashed thread
       
   768 	 */
       
   769 	public Thread getCrashedThread() {
       
   770 		if (threadInfo != null) {
       
   771 			return null;
       
   772 		}
       
   773 		
       
   774 		Thread crashedThread = null;
       
   775 		if (processes != null && !processes.isEmpty()) {
       
   776 			Process[] processesArray = processes.values().toArray(new Process[processes.values().size()]);
       
   777 			for (Process process : processesArray) {
       
   778 				for (Thread thread : process.getThreads()) {
       
   779 					String exitType = thread.getExitType();
       
   780 					if (exitType.equalsIgnoreCase("Panic") || exitType.equalsIgnoreCase("Exception")) {
       
   781 						crashedThread = thread;
       
   782 						break;
       
   783 					}					
       
   784 				}
       
   785 			}
       
   786 		}
       
   787 		return crashedThread;
       
   788 	}
       
   789 
       
   790 	/**
       
   791 	 * Get process by thread id
       
   792 	 * 
       
   793 	 * @return Found process or null
       
   794 	 */
       
   795 	public Process getProcessByThread(int threadId) {
       
   796 		
       
   797 		Process threadProcess = null;
       
   798 		if (processes != null && !processes.isEmpty()) {
       
   799 			Process[] processesArray = processes.values().toArray(new Process[processes.values().size()]);
       
   800 			for (Process process : processesArray) {
       
   801 				for (Thread thread : process.getThreads()) {
       
   802 					//String exitType = thread.getExitType();
       
   803 					if (thread.getId() == threadId) {
       
   804 						threadProcess = process;
       
   805 						break;
       
   806 					}					
       
   807 				}
       
   808 			}
       
   809 		}
       
   810 		return threadProcess;
       
   811 	}
       
   812 	
       
   813 	/**
       
   814 	 * Get process count
       
   815 	 * 
       
   816 	 * @return the number of processes or -1 if not available
       
   817 	 */
       
   818 	public int getProcessCount()
       
   819 	{
       
   820 		if (processes == null) {
       
   821 			processCount = -1;
       
   822 		}
       
   823 		else {
       
   824 			processCount = processes.size();
       
   825 		}
       
   826 		return processCount;
       
   827 	}
       
   828 	
       
   829 	/**
       
   830 	 * Get process count
       
   831 	 * 
       
   832 	 * @return the number of threads or -1 if not available
       
   833 	 */
       
   834 	public int getTotalThreadCount()
       
   835 	{
       
   836 		totalThreadCount = 0;
       
   837 		if (processes == null) {
       
   838 			return  -1;
       
   839 		}
       
   840 		for(Process process : processes.values()) {
       
   841 			totalThreadCount += process.getThreads().size();
       
   842 		}
       
   843 		return totalThreadCount;
       
   844 	}
       
   845 	
       
   846 	/**
       
   847 	 * Returns all threads
       
   848 	 * 
       
   849 	 * @return all threads in all processes
       
   850 	 */
       
   851 	public List<Thread> getThreads() {
       
   852 		List<Thread> allThreads = new ArrayList<Thread>();
       
   853 		for(Process process : processes.values()) {
       
   854 			allThreads.addAll(process.getThreads());
       
   855 		}
       
   856 		return allThreads;
       
   857 	}
       
   858 
   653 	public EventLog getEventLog() {
   859 	public EventLog getEventLog() {
   654 		return eventLog;
   860 		return eventLog;
   655 	}
   861 	}
   656 	
   862 	
       
   863 	public OstTrace getOstTrace() {
       
   864 		return ostTrace;
       
   865 	}
       
   866 
   657 	public List<RegisterDetails> getRegisterDetails() {
   867 	public List<RegisterDetails> getRegisterDetails() {
   658 		return registerDetails;
   868 		return registerDetails;
   659 	}
   869 	}
   660 	
   870 	
   661 	public boolean exists() {
   871 	public boolean exists() {