16 */ |
16 */ |
17 |
17 |
18 package com.nokia.s60tools.crashanalyser.ui.editors; |
18 package com.nokia.s60tools.crashanalyser.ui.editors; |
19 |
19 |
20 import org.eclipse.swt.events.SelectionEvent; |
20 import org.eclipse.swt.events.SelectionEvent; |
21 import org.eclipse.swt.events.SelectionListener; |
|
22 import org.eclipse.swt.layout.GridData; |
21 import org.eclipse.swt.layout.GridData; |
23 import org.eclipse.swt.SWT; |
22 import org.eclipse.swt.SWT; |
24 import org.eclipse.swt.layout.GridLayout; |
23 import org.eclipse.swt.layout.GridLayout; |
25 import org.eclipse.swt.widgets.*; |
24 import org.eclipse.swt.widgets.*; |
26 import org.eclipse.swt.browser.*; |
25 import org.eclipse.swt.browser.*; |
27 import org.eclipse.swt.graphics.Color; |
|
28 import org.eclipse.swt.custom.SashForm; |
26 import org.eclipse.swt.custom.SashForm; |
|
27 import org.eclipse.swt.custom.TableCursor; |
29 import org.eclipse.ui.PlatformUI; |
28 import org.eclipse.ui.PlatformUI; |
30 |
29 |
31 import com.nokia.s60tools.crashanalyser.files.*; |
30 import com.nokia.s60tools.crashanalyser.files.*; |
|
31 import com.nokia.s60tools.crashanalyser.files.SummaryFile.ContentType; |
32 import com.nokia.s60tools.crashanalyser.model.HtmlFormatter; |
32 import com.nokia.s60tools.crashanalyser.model.HtmlFormatter; |
33 import com.nokia.s60tools.crashanalyser.containers.Summary; |
33 import com.nokia.s60tools.crashanalyser.containers.Summary; |
34 import com.nokia.s60tools.crashanalyser.containers.Process; |
34 import com.nokia.s60tools.crashanalyser.containers.Process; |
35 import com.nokia.s60tools.crashanalyser.containers.Thread; |
35 import com.nokia.s60tools.crashanalyser.containers.Thread; |
36 import com.nokia.s60tools.crashanalyser.containers.Stack; |
36 import com.nokia.s60tools.crashanalyser.containers.Stack; |
37 import com.nokia.s60tools.crashanalyser.containers.StackEntry; |
|
38 import com.nokia.s60tools.crashanalyser.containers.RegisterSet; |
37 import com.nokia.s60tools.crashanalyser.containers.RegisterSet; |
39 import com.nokia.s60tools.crashanalyser.resources.HelpContextIDs; |
38 import com.nokia.s60tools.crashanalyser.resources.HelpContextIDs; |
40 import com.nokia.s60tools.crashanalyser.ui.viewers.*; |
39 |
41 import com.nokia.s60tools.crashanalyser.ui.views.*; |
|
42 import java.util.List; |
40 import java.util.List; |
43 import org.eclipse.jface.resource.FontRegistry; |
41 import org.eclipse.jface.resource.FontRegistry; |
44 import org.eclipse.swt.graphics.FontData; |
42 import org.eclipse.swt.graphics.FontData; |
45 |
43 |
46 /** |
44 /** |
47 * Crash Data page in Crash Visualiser editor. |
45 * Crash Data page in Crash Visualiser editor. |
48 * |
46 * |
49 */ |
47 */ |
50 public class SummaryPage implements SelectionListener { |
48 public class SummaryPage { |
51 |
49 |
52 // summary group UI items |
50 // summary group UI items |
53 Table tableSummary; |
51 Table tableSummary; |
54 |
52 |
55 // exit info group UI items |
53 // exit info group UI items |
56 Label labelExitType; |
54 Label labelExitType; |
57 Label labelPanicSummary; |
55 Label labelPanicSummary; |
58 Browser browserPanicDescription; |
56 Browser browserPanicDescription; |
59 |
57 |
60 // call stack group UI items |
|
61 Combo comboCallStack; |
|
62 Label labelStackWarning; |
|
63 Button buttonDecodeFile; |
|
64 Table tableCallStack; |
|
65 CallStackTableViewer tableViewerCallStack; |
|
66 Button buttonAllStackEntries; |
|
67 Button buttonSymbolStackEntries; |
|
68 |
|
69 SummaryFile crashFile = null; |
58 SummaryFile crashFile = null; |
70 FontRegistry fontRegistry; |
59 FontRegistry fontRegistry; |
71 Thread selectedThread = null; |
60 Thread selectedThread = null; |
72 |
61 |
73 /** |
62 /** |
119 parent.setLayoutData(new GridData(GridData.FILL_BOTH)); |
107 parent.setLayoutData(new GridData(GridData.FILL_BOTH)); |
120 fontRegistry = new FontRegistry(Display.getCurrent()); |
108 fontRegistry = new FontRegistry(Display.getCurrent()); |
121 fontRegistry.put("monospace", new FontData[]{new FontData("Courier", 8, SWT.NORMAL)}); |
109 fontRegistry.put("monospace", new FontData[]{new FontData("Courier", 8, SWT.NORMAL)}); |
122 SashForm sashFormMain = new SashForm(parent, SWT.VERTICAL); |
110 SashForm sashFormMain = new SashForm(parent, SWT.VERTICAL); |
123 sashFormMain.setLayoutData(new GridData(GridData.FILL_BOTH)); |
111 sashFormMain.setLayoutData(new GridData(GridData.FILL_BOTH)); |
124 SashForm sashFormTop = new SashForm(sashFormMain, SWT.HORIZONTAL); |
112 createSummaryGroup(sashFormMain); |
125 createSummaryGroup(sashFormTop); |
113 createExitInfoGroup(sashFormMain); |
126 createExitInfoGroup(sashFormTop); |
|
127 createCallStackGroup(sashFormMain); |
|
128 |
|
129 sashFormMain.setWeights(new int[] {1,2}); |
|
130 |
114 |
131 setHelps(); |
115 setHelps(); |
132 |
116 |
133 return parent; |
117 return parent; |
134 } |
118 } |
140 void createSummaryGroup(Composite parent) { |
124 void createSummaryGroup(Composite parent) { |
141 Group groupSummary = new Group(parent, SWT.NONE); |
125 Group groupSummary = new Group(parent, SWT.NONE); |
142 GridLayout layout = new GridLayout(); |
126 GridLayout layout = new GridLayout(); |
143 layout.numColumns = 1; |
127 layout.numColumns = 1; |
144 groupSummary.setLayout(layout); |
128 groupSummary.setLayout(layout); |
145 groupSummary.setText("Summary"); |
129 groupSummary.setText("General"); |
146 GridData groupGD = new GridData(GridData.FILL_HORIZONTAL); |
130 GridData groupGD = new GridData(GridData.FILL_HORIZONTAL); |
147 groupGD.heightHint = 200; |
131 groupGD.heightHint = 200; |
148 groupSummary.setLayoutData(groupGD); |
132 groupSummary.setLayoutData(groupGD); |
149 |
133 |
150 tableSummary = new Table(groupSummary, SWT.BORDER); |
134 tableSummary = new Table(groupSummary, SWT.BORDER | SWT.FULL_SELECTION | |
|
135 SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY ); |
151 tableSummary.setHeaderVisible(true); |
136 tableSummary.setHeaderVisible(true); |
152 tableSummary.setLinesVisible(true); |
137 tableSummary.setLinesVisible(true); |
153 TableColumn col1 = new TableColumn(tableSummary, SWT.LEFT); |
138 TableColumn col1 = new TableColumn(tableSummary, SWT.LEFT); |
154 col1.setWidth(130); |
139 col1.setWidth(130); |
155 TableColumn col2 = new TableColumn(tableSummary, SWT.LEFT); |
140 TableColumn col2 = new TableColumn(tableSummary, SWT.LEFT); |
156 col2.setWidth(300); |
141 col2.setWidth(300); |
157 tableSummary.setLayoutData(new GridData(GridData.FILL_BOTH)); |
142 tableSummary.setLayoutData(new GridData(GridData.FILL_BOTH)); |
158 |
143 |
159 tableSummary.setFont(fontRegistry.get("monospace")); |
144 tableSummary.setFont(fontRegistry.get("monospace")); |
160 |
145 |
|
146 |
|
147 final TableCursor cursor = new TableCursor(tableSummary, SWT.NONE); |
|
148 TableKeyListener keyListener = new TableKeyListener(tableSummary, cursor); |
|
149 tableSummary.addKeyListener(keyListener); |
|
150 cursor.addKeyListener(keyListener); |
|
151 |
161 loadSummaryTable(); |
152 loadSummaryTable(); |
162 } |
153 } |
163 |
154 |
164 /** |
155 /** |
165 * Creates exit info group |
156 * Creates exit info group |
186 browserPanicDescription.setLayoutData(new GridData(GridData.FILL_BOTH)); |
177 browserPanicDescription.setLayoutData(new GridData(GridData.FILL_BOTH)); |
187 |
178 |
188 loadExitInfo(); |
179 loadExitInfo(); |
189 } |
180 } |
190 |
181 |
191 /** |
|
192 * Creates call stack group |
|
193 * @param parent |
|
194 */ |
|
195 void createCallStackGroup(Composite parent) { |
|
196 Group groupCallStack = new Group(parent, SWT.NONE); |
|
197 GridLayout layout = new GridLayout(); |
|
198 layout.numColumns = 3; |
|
199 groupCallStack.setLayout(layout); |
|
200 GridData groupGD = new GridData(GridData.FILL_BOTH); |
|
201 groupGD.horizontalSpan = 3; |
|
202 groupCallStack.setText("Call Stack"); |
|
203 groupCallStack.setLayoutData(groupGD); |
|
204 |
|
205 comboCallStack = new Combo(groupCallStack, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY); |
|
206 comboCallStack.addSelectionListener(this); |
|
207 |
|
208 labelStackWarning = new Label(groupCallStack, SWT.NONE); |
|
209 labelStackWarning.setText("(selected stack is build with heuristic algorithm)"); |
|
210 labelStackWarning.setVisible(false); |
|
211 |
|
212 buttonDecodeFile = new Button(groupCallStack, SWT.PUSH); |
|
213 buttonDecodeFile.setText("Decode"); |
|
214 buttonDecodeFile.setVisible(false); |
|
215 buttonDecodeFile.addSelectionListener(this); |
|
216 |
|
217 tableCallStack = new Table(groupCallStack, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | |
|
218 SWT.V_SCROLL | SWT.H_SCROLL); |
|
219 tableCallStack.setHeaderVisible(true); |
|
220 tableCallStack.setFont(fontRegistry.get("monospace")); |
|
221 |
|
222 GridData tableGD = new GridData(GridData.FILL_BOTH); |
|
223 tableGD.horizontalSpan = 3; |
|
224 tableCallStack.setLayoutData(tableGD); |
|
225 |
|
226 GridData buttonGD = new GridData(GridData.FILL_HORIZONTAL); |
|
227 buttonGD.horizontalSpan = 3; |
|
228 |
|
229 buttonAllStackEntries = new Button(groupCallStack, SWT.RADIO); |
|
230 buttonAllStackEntries.setText("Show all stack entries"); |
|
231 buttonAllStackEntries.addSelectionListener(this); |
|
232 buttonAllStackEntries.setLayoutData(buttonGD); |
|
233 |
|
234 buttonSymbolStackEntries = new Button(groupCallStack, SWT.RADIO); |
|
235 buttonSymbolStackEntries.setText("Show stack entries which have associated symbols"); |
|
236 buttonSymbolStackEntries.addSelectionListener(this); |
|
237 buttonSymbolStackEntries.setLayoutData(buttonGD); |
|
238 buttonSymbolStackEntries.setSelection(true); |
|
239 |
|
240 tableViewerCallStack = new CallStackTableViewer(tableCallStack); |
|
241 |
|
242 initialCallStackTableLoad(); |
|
243 AutoSizeCallStackTableCells(); |
|
244 } |
|
245 |
182 |
246 /** |
183 /** |
247 * Packs all columns for given table |
184 * Packs all columns for given table |
248 * @param table table which columns are to be packed |
185 * @param table table which columns are to be packed |
249 */ |
186 */ |
251 for (int i = 0; i < table.getColumnCount(); i++) { |
188 for (int i = 0; i < table.getColumnCount(); i++) { |
252 table.getColumn(i).pack(); |
189 table.getColumn(i).pack(); |
253 } |
190 } |
254 } |
191 } |
255 |
192 |
256 /** |
|
257 * Packs columns in call stack table nicely |
|
258 */ |
|
259 void AutoSizeCallStackTableCells() { |
|
260 int tableWidth = tableCallStack.getBounds().width; |
|
261 tableCallStack.getColumn(CallStackTableViewer.COLUMN_ADDRESS).setWidth(80); |
|
262 tableCallStack.getColumn(CallStackTableViewer.COLUMN_VALUE).setWidth(80); |
|
263 tableCallStack.getColumn(CallStackTableViewer.COLUMN_OFFSET).setWidth(65); |
|
264 tableCallStack.getColumn(CallStackTableViewer.COLUMN_TEXT).setWidth(60); |
|
265 int space = tableWidth - 80 - 80 - 65 - 60 - 25; |
|
266 int object = space / 3; |
|
267 if (object < 70) |
|
268 object = 70; |
|
269 tableCallStack.getColumn(CallStackTableViewer.COLUMN_OBJECT).setWidth(object); |
|
270 tableCallStack.getColumn(CallStackTableViewer.COLUMN_SYMBOL).setWidth(object*2); |
|
271 } |
|
272 |
|
273 /** |
193 /** |
274 * Loads data into summary table |
194 * Loads data into summary table |
275 */ |
195 */ |
276 void loadSummaryTable() { |
196 void loadSummaryTable() { |
277 // if there is no crashFile given, we are waiting for data to be loaded. |
197 // if there is no crashFile given, we are waiting for data to be loaded. |
282 // we have crash data, load summary table |
202 // we have crash data, load summary table |
283 } else { |
203 } else { |
284 tableSummary.removeAll(); |
204 tableSummary.removeAll(); |
285 |
205 |
286 // show the data of crashed process |
206 // show the data of crashed process |
287 Process process = crashFile.getCrashedProcess(); |
207 Process process = null; |
|
208 if (crashFile.getThread() != null) { |
|
209 process = crashFile.getProcessByThread(crashFile.getThread().getId()); |
|
210 } else { |
|
211 process = crashFile.getCrashedProcess(); |
|
212 } |
|
213 |
288 if (process != null) { |
214 if (process != null) { |
289 newSummaryTableItem("PROCESS", process.getName(), true); |
215 newSummaryTableItem("PROCESS", process.getName(), true); |
290 |
216 |
291 // current UI support only one thread, so show the first thread of first process |
217 // current UI support only one thread, so show the first thread of first process |
292 Thread thread = process.getFirstThread(); |
218 Thread thread = null; |
|
219 if (crashFile.getThread() != null) { |
|
220 // Show only thread information (no crash info) |
|
221 thread = crashFile.getThread(); |
|
222 } else { |
|
223 thread = crashFile.getCrashedThread(); |
|
224 } |
|
225 |
293 if (thread != null) { |
226 if (thread != null) { |
294 selectedThread = thread; |
227 selectedThread = thread; |
295 newSummaryTableItem("THREAD", thread.getFullName(), true); |
228 newSummaryTableItem("THREAD", thread.getFullName(), true); |
296 newSummaryTableItem("STACK POINTER", thread.getStackPointer(), true); |
229 newSummaryTableItem("STACK POINTER", thread.getStackPointer(), true); |
297 newSummaryTableItem("LINK REGISTER", thread.getLinkRegister(), true); |
230 newSummaryTableItem("LINK REGISTER", thread.getLinkRegister(), true); |
299 } |
232 } |
300 } |
233 } |
301 |
234 |
302 Summary crashSummary = crashFile.getSummary(); |
235 Summary crashSummary = crashFile.getSummary(); |
303 if (crashSummary != null) { |
236 if (crashSummary != null) { |
304 newSummaryTableItem("CRASH TIME", crashSummary.getCrashTime(), true); |
|
305 newSummaryTableItem("CRASH DATE", crashSummary.getCrashDate(), true); |
|
306 newSummaryTableItem("UPTIME", crashSummary.getUpTime(), true); |
|
307 newSummaryTableItem("ROM ID", crashSummary.getRomId(), true); |
|
308 // there can be several software version informations, show them all |
237 // there can be several software version informations, show them all |
309 String[] versions = crashSummary.getSwVersion(); |
238 String[] versions = crashSummary.getSwVersion(); |
310 if (versions != null && versions.length > 0) { |
239 if (versions != null && versions.length > 0) { |
311 for (int i = 0; i < versions.length; i++) { |
240 for (int i = 0; i < versions.length; i++) { |
312 newSummaryTableItem("SW VERSION", versions[i], false); |
241 newSummaryTableItem("SW VERSION", versions[i], false); |
320 } |
249 } |
321 } |
250 } |
322 newSummaryTableItem("PRODUCT TYPE", crashSummary.getProductType(), true); |
251 newSummaryTableItem("PRODUCT TYPE", crashSummary.getProductType(), true); |
323 newSummaryTableItem("PRODUCT CODE", crashSummary.getProductCode(), true); |
252 newSummaryTableItem("PRODUCT CODE", crashSummary.getProductCode(), true); |
324 newSummaryTableItem("LANGUAGE", crashSummary.getLanguage(), true); |
253 newSummaryTableItem("LANGUAGE", crashSummary.getLanguage(), true); |
325 newSummaryTableItem("SERIAL NUMBER", crashSummary.getSerialNumber(), true); |
|
326 newSummaryTableItem("IMEI", crashSummary.getImei(), true); |
254 newSummaryTableItem("IMEI", crashSummary.getImei(), true); |
327 newSummaryTableItem("FREE RAM", crashSummary.getFreeRam(), true); |
255 newSummaryTableItem("CRASH TIME", crashSummary.getCrashTime(), true); |
|
256 newSummaryTableItem("CRASH DATE", crashSummary.getCrashDate(), true); |
|
257 newSummaryTableItem("ROM ID", crashSummary.getRomId(), true); |
|
258 newSummaryTableItem("AVAILABLE MEMORY", crashSummary.getFreeRam(), true); |
|
259 newSummaryTableItem("PSN", crashSummary.getSerialNumber(), true); |
|
260 newSummaryTableItem("UPTIME", crashSummary.getUpTime(), true); |
|
261 newSummaryTableItem("MOBILECRASH CONFIGURATION", crashSummary.getProductionMode(), true); |
|
262 newSummaryTableItem("CRASH SOURCE", crashSummary.getCrashSource(), true); |
|
263 newSummaryTableItem("FREE DISK SPACE", crashSummary.getFreeDisk(), true); |
|
264 |
|
265 // Print defect hash if exist |
|
266 List<Stack> stacks = null; |
|
267 if (selectedThread != null) |
|
268 stacks = selectedThread.getStacks(); |
|
269 |
|
270 if (stacks != null && !stacks.isEmpty()) |
|
271 { |
|
272 String defectHash = ""; |
|
273 for(Stack stack: stacks) { |
|
274 defectHash = stack.getHash(); |
|
275 if(! "".equals(defectHash)) { |
|
276 newSummaryTableItem("DEFECT HASH", defectHash, true); |
|
277 } |
|
278 } |
|
279 } |
328 } |
280 } |
329 |
281 |
330 // stand alone stacks don't belong to a thread, check if there are any |
282 // stand alone stacks don't belong to a thread, check if there are any |
331 // of these, and print SP, LR and PC if needed |
283 // of these, and print SP, LR and PC if needed |
332 List<Stack> standAloneStacks = crashFile.getStandAloneStacks(); |
284 List<Stack> standAloneStacks = crashFile.getStandAloneStacks(); |
363 * Load exit information |
315 * Load exit information |
364 */ |
316 */ |
365 void loadExitInfo() { |
317 void loadExitInfo() { |
366 if (crashFile == null) |
318 if (crashFile == null) |
367 return; |
319 return; |
368 |
320 |
369 String panicSummary = ""; |
321 String panicSummary = ""; |
370 String panicDescription = ""; |
322 String panicDescription = ""; |
|
323 |
|
324 if (crashFile.getContentType() == ContentType.REGMSG) { |
|
325 labelPanicSummary.setText("Registration message"); |
|
326 panicDescription = HtmlFormatter.formatRegistrationMessage(); |
|
327 browserPanicDescription.setText(HtmlFormatter.formatHtmlStyle(labelPanicSummary.getFont(), |
|
328 panicDescription)); |
|
329 return; |
|
330 } else if (crashFile.getContentType() == ContentType.REPORT) { |
|
331 labelPanicSummary.setText("Report"); |
|
332 panicDescription = HtmlFormatter.formatReport(); |
|
333 browserPanicDescription.setText(HtmlFormatter.formatHtmlStyle(labelPanicSummary.getFont(), |
|
334 panicDescription)); |
|
335 return; |
|
336 } |
|
337 |
371 if (selectedThread != null && !"".equals(selectedThread.getExitType())) { |
338 if (selectedThread != null && !"".equals(selectedThread.getExitType())) { |
372 panicDescription = selectedThread.getPanicDescription(); |
339 panicDescription = selectedThread.getPanicDescription(); |
373 panicSummary = selectedThread.getExitType(); |
340 panicSummary = selectedThread.getExitType(); |
374 if (!"".equals(selectedThread.getExitCategory()) && !"".equals(selectedThread.getExitReason())) { |
341 if (!"".equals(selectedThread.getExitCategory()) && !"".equals(selectedThread.getExitReason())) { |
375 // if crash was an exception |
342 // if crash was an exception |
392 |
359 |
393 browserPanicDescription.setText(HtmlFormatter.formatHtmlStyle(labelPanicSummary.getFont(), |
360 browserPanicDescription.setText(HtmlFormatter.formatHtmlStyle(labelPanicSummary.getFont(), |
394 panicDescription)); |
361 panicDescription)); |
395 } |
362 } |
396 |
363 |
397 /** |
|
398 * Loads stacks to combo, selects the correct stack as |
|
399 * default set and then loads stack's data to table. |
|
400 */ |
|
401 void initialCallStackTableLoad() { |
|
402 int selectedIndex = 0; |
|
403 if (selectedThread != null) { |
|
404 List<Stack> stacks = selectedThread.getStacks(); |
|
405 if (stacks != null && !stacks.isEmpty()) { |
|
406 // add all stacks into combo |
|
407 for (int i = 0; i < stacks.size(); i++) { |
|
408 Stack stack = stacks.get(i); |
|
409 // show stack which contains CPSR register as default |
|
410 if (stack.stackRegisterContainsCpsr()) |
|
411 selectedIndex = i; |
|
412 comboCallStack.add(stack.getStackType()); |
|
413 comboCallStack.setData(stack.getStackType(), stack); |
|
414 } |
|
415 } |
|
416 } |
|
417 |
|
418 List<Stack> standAloneStacks = crashFile.getStandAloneStacks(); |
|
419 if (standAloneStacks != null && !standAloneStacks.isEmpty()) { |
|
420 for (int i = 0; i < standAloneStacks.size(); i++) { |
|
421 Stack stack = standAloneStacks.get(i); |
|
422 if (stack.stackRegisterContainsCpsr()) |
|
423 selectedIndex = comboCallStack.getItemCount() + i; |
|
424 comboCallStack.add(stack.getStackType()); |
|
425 comboCallStack.setData(stack.getStackType(), stack); |
|
426 } |
|
427 } |
|
428 |
|
429 if (comboCallStack.getItemCount() > 0) { |
|
430 comboCallStack.select(selectedIndex); |
|
431 loadCallStackTable(true); |
|
432 } |
|
433 } |
|
434 |
|
435 /** |
|
436 * Loads call stack table according to which stack is |
|
437 * selected in combo. |
|
438 */ |
|
439 void loadCallStackTable(boolean autoSizeCells) { |
|
440 tableCallStack.removeAll(); |
|
441 labelStackWarning.setVisible(false); |
|
442 |
|
443 if (comboCallStack.getItemCount() < 1) |
|
444 return; |
|
445 |
|
446 try { |
|
447 Stack stack = (Stack)comboCallStack.getData(comboCallStack.getText()); |
|
448 boolean containsAccurate = stack.containsAccurateStackEntries(); |
|
449 labelStackWarning.setVisible(!containsAccurate); |
|
450 List<StackEntry> stackEntries = stack.getStackEntries(); |
|
451 if (stackEntries != null && !stackEntries.isEmpty()) { |
|
452 for (int i = 0; i < stackEntries.size(); i++) { |
|
453 StackEntry stackEntry = stackEntries.get(i); |
|
454 newStackTableItem(stackEntry, containsAccurate); |
|
455 } |
|
456 if (autoSizeCells) |
|
457 AutoSizeCallStackTableCells(); |
|
458 } |
|
459 |
|
460 // nothing in stack |
|
461 if (stackEntries == null || stackEntries.isEmpty()) { |
|
462 disableStack(); |
|
463 } |
|
464 |
|
465 } catch (Exception e) { |
|
466 e.printStackTrace(); |
|
467 } |
|
468 } |
|
469 |
|
470 /** |
|
471 * Disables stack UI elements |
|
472 */ |
|
473 void disableStack() { |
|
474 labelStackWarning.setVisible(true); |
|
475 labelStackWarning.setText("Symbols were not available while creating stack."); |
|
476 buttonDecodeFile.setVisible(true); |
|
477 comboCallStack.setEnabled(false); |
|
478 buttonAllStackEntries.setEnabled(false); |
|
479 buttonSymbolStackEntries.setEnabled(false); |
|
480 tableCallStack.setEnabled(false); |
|
481 } |
|
482 |
|
483 public void widgetDefaultSelected(SelectionEvent arg0) { |
364 public void widgetDefaultSelected(SelectionEvent arg0) { |
484 // no implementation required |
365 // no implementation required |
485 } |
366 } |
486 |
367 |
487 public void widgetSelected(SelectionEvent event) { |
|
488 // stack was changed in combo |
|
489 if (event.widget == comboCallStack) { |
|
490 loadCallStackTable(true); |
|
491 // stack radio button changes |
|
492 } else if (event.widget == buttonAllStackEntries || |
|
493 event.widget == buttonSymbolStackEntries) { |
|
494 loadCallStackTable(false); |
|
495 // decode button was pressed |
|
496 } else if (event.widget == buttonDecodeFile) { |
|
497 MainView mv = MainView.showAndReturnYourself(true); |
|
498 mv.decodeFile(crashFile); |
|
499 } |
|
500 } |
|
501 |
368 |
502 /** |
369 /** |
503 * Adds new summary table row |
370 * Adds new summary table row |
504 * @param header header text |
371 * @param header header text |
505 * @param value value text |
372 * @param value value text |
520 |
387 |
521 return false; |
388 return false; |
522 } |
389 } |
523 |
390 |
524 /** |
391 /** |
525 * Adds new stack table row. |
|
526 * @param stackEntry row data |
|
527 * @param stackContainsAccurateEntries affects row colorings |
|
528 */ |
|
529 void newStackTableItem(StackEntry stackEntry, boolean stackContainsAccurateEntries) { |
|
530 // if 'Show stack entries which have associated symbols' radio button is selected and |
|
531 // if stack contains accurate stack entries, and this stack entry is not accurate |
|
532 // don't add it to table (unless this stack entry is current stack pointer or register based) |
|
533 if (buttonSymbolStackEntries.getSelection() && |
|
534 stackContainsAccurateEntries && |
|
535 !stackEntry.accurate() && |
|
536 !stackEntry.currentStackPointer() && |
|
537 !stackEntry.registerBased()) { |
|
538 return; |
|
539 // if 'Show stack entries which have associated symbols' radio button is selected |
|
540 // if stack doesn't contain accurate stack entries, don't show current stack entry |
|
541 // if it doesn't have associated symbol (unless this stack entry is current stack pointer or register based) |
|
542 } else if (buttonSymbolStackEntries.getSelection() && |
|
543 !stackContainsAccurateEntries && |
|
544 "".equals(stackEntry.getSymbol()) && |
|
545 !stackEntry.currentStackPointer() && |
|
546 !stackEntry.registerBased()) |
|
547 return; |
|
548 |
|
549 TableItem item = new TableItem(tableCallStack, SWT.NONE); |
|
550 item.setText(new String[] {stackEntry.getAddress(), |
|
551 stackEntry.getSymbol(), |
|
552 stackEntry.getValue(), |
|
553 stackEntry.getOffset(), |
|
554 stackEntry.getObject(), |
|
555 stackEntry.getText()}); |
|
556 |
|
557 item.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); |
|
558 item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); |
|
559 |
|
560 // item is current stack pointer FG black, BG light pink |
|
561 if (stackEntry.currentStackPointer()) { |
|
562 item.setBackground(new Color(Display.getCurrent(), 255, 182, 193)); // light pink |
|
563 // PC or LR |
|
564 } else if (stackEntry.registerBased()) { |
|
565 item.setBackground(new Color(Display.getCurrent(), 173, 216, 230)); // light blue |
|
566 // item is out of stack bound FG gray, BG white |
|
567 } else if (stackEntry.outsideStackBounds()) { |
|
568 item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); |
|
569 // item has no symbols, FG black, BG white |
|
570 } else if ("".equals(stackEntry.getSymbol())) { |
|
571 } else |
|
572 // if stack contains accurate entries, show "ghost" entries as gray |
|
573 if (stackContainsAccurateEntries) { |
|
574 // color accurate stack entries black or blue |
|
575 if (stackEntry.accurate()) { |
|
576 // ram loaded code (instead of execute-in-place code) FG blue |
|
577 if (!stackEntry.xip()) { |
|
578 item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE)); |
|
579 } |
|
580 // not accurate stack entry FG gray |
|
581 } else { |
|
582 item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY)); |
|
583 } |
|
584 // stack isn't accurate, |
|
585 } else { |
|
586 // ram loaded code (instead of execute-in-place code) |
|
587 if (!stackEntry.xip()) { |
|
588 item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE)); |
|
589 } |
|
590 } |
|
591 |
|
592 item.setData(stackEntry); |
|
593 } |
|
594 |
|
595 /** |
|
596 * Sets context sensitive help ids to UI elements |
392 * Sets context sensitive help ids to UI elements |
597 */ |
393 */ |
598 void setHelps() { |
394 void setHelps() { |
599 PlatformUI.getWorkbench().getHelpSystem().setHelp(tableCallStack, |
|
600 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
|
601 PlatformUI.getWorkbench().getHelpSystem().setHelp(tableSummary, |
395 PlatformUI.getWorkbench().getHelpSystem().setHelp(tableSummary, |
602 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
|
603 PlatformUI.getWorkbench().getHelpSystem().setHelp(comboCallStack, |
|
604 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
|
605 PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonAllStackEntries, |
|
606 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
|
607 PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonDecodeFile, |
|
608 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
|
609 PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonSymbolStackEntries, |
|
610 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
396 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
611 PlatformUI.getWorkbench().getHelpSystem().setHelp(browserPanicDescription, |
397 PlatformUI.getWorkbench().getHelpSystem().setHelp(browserPanicDescription, |
612 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
398 HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER); |
613 } |
399 } |
614 } |
400 } |