--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysis/crashanalyser/com.nokia.s60tools.crashanalyser/src/com/nokia/s60tools/crashanalyser/ui/editors/SummaryPage.java Thu Feb 11 15:06:45 2010 +0200
@@ -0,0 +1,614 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package com.nokia.s60tools.crashanalyser.ui.editors;
+
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+import org.eclipse.swt.browser.*;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.ui.PlatformUI;
+
+import com.nokia.s60tools.crashanalyser.files.*;
+import com.nokia.s60tools.crashanalyser.model.HtmlFormatter;
+import com.nokia.s60tools.crashanalyser.containers.Summary;
+import com.nokia.s60tools.crashanalyser.containers.Process;
+import com.nokia.s60tools.crashanalyser.containers.Thread;
+import com.nokia.s60tools.crashanalyser.containers.Stack;
+import com.nokia.s60tools.crashanalyser.containers.StackEntry;
+import com.nokia.s60tools.crashanalyser.containers.RegisterSet;
+import com.nokia.s60tools.crashanalyser.resources.HelpContextIDs;
+import com.nokia.s60tools.crashanalyser.ui.viewers.*;
+import com.nokia.s60tools.crashanalyser.ui.views.*;
+import java.util.List;
+import org.eclipse.jface.resource.FontRegistry;
+import org.eclipse.swt.graphics.FontData;
+
+/**
+ * Crash Data page in Crash Visualiser editor.
+ *
+ */
+public class SummaryPage implements SelectionListener {
+
+ // summary group UI items
+ Table tableSummary;
+
+ // exit info group UI items
+ Label labelExitType;
+ Label labelPanicSummary;
+ Browser browserPanicDescription;
+
+ // call stack group UI items
+ Combo comboCallStack;
+ Label labelStackWarning;
+ Button buttonDecodeFile;
+ Table tableCallStack;
+ CallStackTableViewer tableViewerCallStack;
+ Button buttonAllStackEntries;
+ Button buttonSymbolStackEntries;
+
+ SummaryFile crashFile = null;
+ FontRegistry fontRegistry;
+ Thread selectedThread = null;
+
+ /**
+ * Creates the page
+ * @param parent composite
+ * @param file summary file
+ * @return composite
+ */
+ public Composite createPage(Composite parent, SummaryFile file) {
+ crashFile = file;
+ return doCreate(parent);
+ }
+
+ /**
+ * Creates the page
+ * @param parent composite
+ * @return composite
+ */
+ public Composite createPage(Composite parent) {
+ return doCreate(parent);
+ }
+
+ public void update() {
+ AutoSizeCallStackTableCells();
+ }
+
+ /**
+ * Loads data from given file into UI elements.
+ * @param file crash file
+ */
+ public void setFile(CrashFile file) {
+ if (file != null) {
+ crashFile = file;
+ loadSummaryTable();
+ loadExitInfo();
+ initialCallStackTableLoad();
+ }
+ }
+
+ /**
+ * Creates all UI elements to the page
+ * @param parent
+ * @return composite
+ */
+ Composite doCreate(Composite parent) {
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ parent.setLayout(layout);
+ parent.setLayoutData(new GridData(GridData.FILL_BOTH));
+ fontRegistry = new FontRegistry(Display.getCurrent());
+ fontRegistry.put("monospace", new FontData[]{new FontData("Courier", 8, SWT.NORMAL)});
+ SashForm sashFormMain = new SashForm(parent, SWT.VERTICAL);
+ sashFormMain.setLayoutData(new GridData(GridData.FILL_BOTH));
+ SashForm sashFormTop = new SashForm(sashFormMain, SWT.HORIZONTAL);
+ createSummaryGroup(sashFormTop);
+ createExitInfoGroup(sashFormTop);
+ createCallStackGroup(sashFormMain);
+
+ sashFormMain.setWeights(new int[] {1,2});
+
+ setHelps();
+
+ return parent;
+ }
+
+ /**
+ * Creates summary group
+ * @param parent
+ */
+ void createSummaryGroup(Composite parent) {
+ Group groupSummary = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ groupSummary.setLayout(layout);
+ groupSummary.setText("Summary");
+ GridData groupGD = new GridData(GridData.FILL_HORIZONTAL);
+ groupGD.heightHint = 200;
+ groupSummary.setLayoutData(groupGD);
+
+ tableSummary = new Table(groupSummary, SWT.BORDER);
+ tableSummary.setHeaderVisible(true);
+ tableSummary.setLinesVisible(true);
+ TableColumn col1 = new TableColumn(tableSummary, SWT.LEFT);
+ col1.setWidth(130);
+ TableColumn col2 = new TableColumn(tableSummary, SWT.LEFT);
+ col2.setWidth(300);
+ tableSummary.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ tableSummary.setFont(fontRegistry.get("monospace"));
+
+ loadSummaryTable();
+ }
+
+ /**
+ * Creates exit info group
+ * @param parent
+ */
+ void createExitInfoGroup(Composite parent) {
+ Group groupExitInfo = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ groupExitInfo.setLayout(layout);
+ groupExitInfo.setText("Exit Info");
+ GridData groupGD = new GridData(GridData.FILL_HORIZONTAL);
+ groupGD.heightHint = 200;
+ groupExitInfo.setLayoutData(groupGD);
+
+ labelExitType = new Label(groupExitInfo, SWT.NONE);
+ labelExitType.setText("Exit Type:");
+ labelExitType.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ labelPanicSummary = new Label(groupExitInfo, SWT.BORDER);
+ labelPanicSummary.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ browserPanicDescription = new Browser(groupExitInfo, SWT.BORDER);
+ browserPanicDescription.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ loadExitInfo();
+ }
+
+ /**
+ * Creates call stack group
+ * @param parent
+ */
+ void createCallStackGroup(Composite parent) {
+ Group groupCallStack = new Group(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 3;
+ groupCallStack.setLayout(layout);
+ GridData groupGD = new GridData(GridData.FILL_BOTH);
+ groupGD.horizontalSpan = 3;
+ groupCallStack.setText("Call Stack");
+ groupCallStack.setLayoutData(groupGD);
+
+ comboCallStack = new Combo(groupCallStack, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY);
+ comboCallStack.addSelectionListener(this);
+
+ labelStackWarning = new Label(groupCallStack, SWT.NONE);
+ labelStackWarning.setText("(selected stack is build with heuristic algorithm)");
+ labelStackWarning.setVisible(false);
+
+ buttonDecodeFile = new Button(groupCallStack, SWT.PUSH);
+ buttonDecodeFile.setText("Decode");
+ buttonDecodeFile.setVisible(false);
+ buttonDecodeFile.addSelectionListener(this);
+
+ tableCallStack = new Table(groupCallStack, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION |
+ SWT.V_SCROLL | SWT.H_SCROLL);
+ tableCallStack.setHeaderVisible(true);
+ tableCallStack.setFont(fontRegistry.get("monospace"));
+
+ GridData tableGD = new GridData(GridData.FILL_BOTH);
+ tableGD.horizontalSpan = 3;
+ tableCallStack.setLayoutData(tableGD);
+
+ GridData buttonGD = new GridData(GridData.FILL_HORIZONTAL);
+ buttonGD.horizontalSpan = 3;
+
+ buttonAllStackEntries = new Button(groupCallStack, SWT.RADIO);
+ buttonAllStackEntries.setText("Show all stack entries");
+ buttonAllStackEntries.addSelectionListener(this);
+ buttonAllStackEntries.setLayoutData(buttonGD);
+
+ buttonSymbolStackEntries = new Button(groupCallStack, SWT.RADIO);
+ buttonSymbolStackEntries.setText("Show stack entries which have associated symbols");
+ buttonSymbolStackEntries.addSelectionListener(this);
+ buttonSymbolStackEntries.setLayoutData(buttonGD);
+ buttonSymbolStackEntries.setSelection(true);
+
+ tableViewerCallStack = new CallStackTableViewer(tableCallStack);
+
+ initialCallStackTableLoad();
+ AutoSizeCallStackTableCells();
+ }
+
+ /**
+ * Packs all columns for given table
+ * @param table table which columns are to be packed
+ */
+ void AutoSizeTableCells(Table table) {
+ for (int i = 0; i < table.getColumnCount(); i++) {
+ table.getColumn(i).pack();
+ }
+ }
+
+ /**
+ * Packs columns in call stack table nicely
+ */
+ void AutoSizeCallStackTableCells() {
+ int tableWidth = tableCallStack.getBounds().width;
+ tableCallStack.getColumn(CallStackTableViewer.COLUMN_ADDRESS).setWidth(80);
+ tableCallStack.getColumn(CallStackTableViewer.COLUMN_VALUE).setWidth(80);
+ tableCallStack.getColumn(CallStackTableViewer.COLUMN_OFFSET).setWidth(65);
+ tableCallStack.getColumn(CallStackTableViewer.COLUMN_TEXT).setWidth(60);
+ int space = tableWidth - 80 - 80 - 65 - 60 - 25;
+ int object = space / 3;
+ if (object < 70)
+ object = 70;
+ tableCallStack.getColumn(CallStackTableViewer.COLUMN_OBJECT).setWidth(object);
+ tableCallStack.getColumn(CallStackTableViewer.COLUMN_SYMBOL).setWidth(object*2);
+ }
+
+ /**
+ * Loads data into summary table
+ */
+ void loadSummaryTable() {
+ // if there is no crashFile given, we are waiting for data to be loaded.
+ // Show 'Loading file' text in summary table until we get data.
+ if (crashFile == null) {
+ TableItem item = new TableItem(tableSummary, SWT.NONE);
+ item.setText(new String[] {"Loading file. Please wait.", ""});
+ // we have crash data, load summary table
+ } else {
+ tableSummary.removeAll();
+
+ // show the data of crashed process
+ Process process = crashFile.getCrashedProcess();
+ if (process != null) {
+ newSummaryTableItem("PROCESS", process.getName(), true);
+
+ // current UI support only one thread, so show the first thread of first process
+ Thread thread = process.getFirstThread();
+ if (thread != null) {
+ selectedThread = thread;
+ newSummaryTableItem("THREAD", thread.getFullName(), true);
+ newSummaryTableItem("STACK POINTER", thread.getStackPointer(), true);
+ newSummaryTableItem("LINK REGISTER", thread.getLinkRegister(), true);
+ newSummaryTableItem("PROGRAM COUNTER", thread.getProgramCounter(), true);
+ }
+ }
+
+ Summary crashSummary = crashFile.getSummary();
+ if (crashSummary != null) {
+ newSummaryTableItem("CRASH TIME", crashSummary.getCrashTime(), true);
+ newSummaryTableItem("CRASH DATE", crashSummary.getCrashDate(), true);
+ newSummaryTableItem("UPTIME", crashSummary.getUpTime(), true);
+ newSummaryTableItem("ROM ID", crashSummary.getRomId(), true);
+ // there can be several software version informations, show them all
+ String[] versions = crashSummary.getSwVersion();
+ if (versions != null && versions.length > 0) {
+ for (int i = 0; i < versions.length; i++) {
+ newSummaryTableItem("SW VERSION", versions[i], false);
+ }
+ }
+ // there can be several hardware version informations, show them all
+ versions = crashSummary.getHwVersion();
+ if (versions != null && versions.length > 0) {
+ for (int i = 0; i < versions.length; i++) {
+ newSummaryTableItem("HW VERSION", versions[i], false);
+ }
+ }
+ newSummaryTableItem("PRODUCT TYPE", crashSummary.getProductType(), true);
+ newSummaryTableItem("PRODUCT CODE", crashSummary.getProductCode(), true);
+ newSummaryTableItem("LANGUAGE", crashSummary.getLanguage(), true);
+ newSummaryTableItem("SERIAL NUMBER", crashSummary.getSerialNumber(), true);
+ newSummaryTableItem("IMEI", crashSummary.getImei(), true);
+ newSummaryTableItem("FREE RAM", crashSummary.getFreeRam(), true);
+ }
+
+ // stand alone stacks don't belong to a thread, check if there are any
+ // of these, and print SP, LR and PC if needed
+ List<Stack> standAloneStacks = crashFile.getStandAloneStacks();
+ if (standAloneStacks != null && !standAloneStacks.isEmpty()) {
+ for (int i = 0; i < standAloneStacks.size(); i++) {
+ Stack stack = standAloneStacks.get(i);
+ if (stack.stackRegisterContainsCpsr()) {
+ newSummaryTableItem("STACK POINTER", stack.getStackPointer(), true);
+ newSummaryTableItem("LINK REGISTER", stack.getLinkRegister(), true);
+ newSummaryTableItem("PROGRAM COUNTER", stack.getProgramCounter(), true);
+ }
+ }
+ }
+
+ // stand alone registers don't belong to a thread, check if there are any
+ // of these, and print SP, LR and PC if needed
+ List<RegisterSet> standAloneRegisterSets = crashFile.getStandAloneRegisterSets();
+ if (standAloneRegisterSets != null && !standAloneRegisterSets.isEmpty()) {
+ for (int i = 0; i < standAloneRegisterSets.size(); i++) {
+ RegisterSet regSet = standAloneRegisterSets.get(i);
+ if (regSet.containsCPSR()) {
+ newSummaryTableItem("STACK POINTER", regSet.getStackPointer(), true);
+ newSummaryTableItem("LINK REGISTER", regSet.getLinkRegister(), true);
+ newSummaryTableItem("PROGRAM COUNTER", regSet.getProgramCounter(), true);
+ }
+ }
+ }
+
+ AutoSizeTableCells(tableSummary);
+ }
+ }
+
+ /**
+ * Load exit information
+ */
+ void loadExitInfo() {
+ if (crashFile == null)
+ return;
+
+ String panicSummary = "";
+ String panicDescription = "";
+ if (selectedThread != null && !"".equals(selectedThread.getExitType())) {
+ panicDescription = selectedThread.getPanicDescription();
+ panicSummary = selectedThread.getExitType();
+ if (!"".equals(selectedThread.getExitCategory()) && !"".equals(selectedThread.getExitReason())) {
+ // if crash was an exception
+ if (selectedThread.getExitType().equals("Exception")) {
+ panicSummary += ": " + selectedThread.getExitReason();
+ // crash was a panic
+ } else {
+ panicSummary += ": " + selectedThread.getExitCategory() + " - " + selectedThread.getExitReason();
+ }
+ }
+ }
+
+ // we could not find panic data
+ if ("".equals(panicSummary.trim())) {
+ panicSummary = "Unknown";
+ }
+ labelPanicSummary.setText(panicSummary);
+ if ("".equals(panicDescription.trim()))
+ panicDescription = HtmlFormatter.formatUnknownPanicMessage(panicSummary);
+
+ browserPanicDescription.setText(HtmlFormatter.formatHtmlStyle(labelPanicSummary.getFont(),
+ panicDescription));
+ }
+
+ /**
+ * Loads stacks to combo, selects the correct stack as
+ * default set and then loads stack's data to table.
+ */
+ void initialCallStackTableLoad() {
+ int selectedIndex = 0;
+ if (selectedThread != null) {
+ List<Stack> stacks = selectedThread.getStacks();
+ if (stacks != null && !stacks.isEmpty()) {
+ // add all stacks into combo
+ for (int i = 0; i < stacks.size(); i++) {
+ Stack stack = stacks.get(i);
+ // show stack which contains CPSR register as default
+ if (stack.stackRegisterContainsCpsr())
+ selectedIndex = i;
+ comboCallStack.add(stack.getStackType());
+ comboCallStack.setData(stack.getStackType(), stack);
+ }
+ }
+ }
+
+ List<Stack> standAloneStacks = crashFile.getStandAloneStacks();
+ if (standAloneStacks != null && !standAloneStacks.isEmpty()) {
+ for (int i = 0; i < standAloneStacks.size(); i++) {
+ Stack stack = standAloneStacks.get(i);
+ if (stack.stackRegisterContainsCpsr())
+ selectedIndex = comboCallStack.getItemCount() + i;
+ comboCallStack.add(stack.getStackType());
+ comboCallStack.setData(stack.getStackType(), stack);
+ }
+ }
+
+ if (comboCallStack.getItemCount() > 0) {
+ comboCallStack.select(selectedIndex);
+ loadCallStackTable(true);
+ }
+ }
+
+ /**
+ * Loads call stack table according to which stack is
+ * selected in combo.
+ */
+ void loadCallStackTable(boolean autoSizeCells) {
+ tableCallStack.removeAll();
+ labelStackWarning.setVisible(false);
+
+ if (comboCallStack.getItemCount() < 1)
+ return;
+
+ try {
+ Stack stack = (Stack)comboCallStack.getData(comboCallStack.getText());
+ boolean containsAccurate = stack.containsAccurateStackEntries();
+ labelStackWarning.setVisible(!containsAccurate);
+ List<StackEntry> stackEntries = stack.getStackEntries();
+ if (stackEntries != null && !stackEntries.isEmpty()) {
+ for (int i = 0; i < stackEntries.size(); i++) {
+ StackEntry stackEntry = stackEntries.get(i);
+ newStackTableItem(stackEntry, containsAccurate);
+ }
+ if (autoSizeCells)
+ AutoSizeCallStackTableCells();
+ }
+
+ // nothing in stack
+ if (stackEntries == null || stackEntries.isEmpty()) {
+ disableStack();
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Disables stack UI elements
+ */
+ void disableStack() {
+ labelStackWarning.setVisible(true);
+ labelStackWarning.setText("Symbols were not available while creating stack.");
+ buttonDecodeFile.setVisible(true);
+ comboCallStack.setEnabled(false);
+ buttonAllStackEntries.setEnabled(false);
+ buttonSymbolStackEntries.setEnabled(false);
+ tableCallStack.setEnabled(false);
+ }
+
+ public void widgetDefaultSelected(SelectionEvent arg0) {
+ // no implementation required
+ }
+
+ public void widgetSelected(SelectionEvent event) {
+ // stack was changed in combo
+ if (event.widget == comboCallStack) {
+ loadCallStackTable(true);
+ // stack radio button changes
+ } else if (event.widget == buttonAllStackEntries ||
+ event.widget == buttonSymbolStackEntries) {
+ loadCallStackTable(false);
+ // decode button was pressed
+ } else if (event.widget == buttonDecodeFile) {
+ MainView mv = MainView.showAndReturnYourself(true);
+ mv.decodeFile(crashFile);
+ }
+ }
+
+ /**
+ * Adds new summary table row
+ * @param header header text
+ * @param value value text
+ */
+ boolean newSummaryTableItem(String header, String value, boolean doNotDuplicate) {
+ if (!"".equals(value)) {
+ if (doNotDuplicate) {
+ for (int i = 0; i < tableSummary.getItemCount(); i++) {
+ TableItem it = tableSummary.getItem(i);
+ if (it.getText(0).equalsIgnoreCase(header))
+ return false;
+ }
+ }
+ TableItem item = new TableItem(tableSummary, SWT.NONE);
+ item.setText(new String[] {header, value});
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Adds new stack table row.
+ * @param stackEntry row data
+ * @param stackContainsAccurateEntries affects row colorings
+ */
+ void newStackTableItem(StackEntry stackEntry, boolean stackContainsAccurateEntries) {
+ // if 'Show stack entries which have associated symbols' radio button is selected and
+ // if stack contains accurate stack entries, and this stack entry is not accurate
+ // don't add it to table (unless this stack entry is current stack pointer or register based)
+ if (buttonSymbolStackEntries.getSelection() &&
+ stackContainsAccurateEntries &&
+ !stackEntry.accurate() &&
+ !stackEntry.currentStackPointer() &&
+ !stackEntry.registerBased()) {
+ return;
+ // if 'Show stack entries which have associated symbols' radio button is selected
+ // if stack doesn't contain accurate stack entries, don't show current stack entry
+ // if it doesn't have associated symbol (unless this stack entry is current stack pointer or register based)
+ } else if (buttonSymbolStackEntries.getSelection() &&
+ !stackContainsAccurateEntries &&
+ "".equals(stackEntry.getSymbol()) &&
+ !stackEntry.currentStackPointer() &&
+ !stackEntry.registerBased())
+ return;
+
+ TableItem item = new TableItem(tableCallStack, SWT.NONE);
+ item.setText(new String[] {stackEntry.getAddress(),
+ stackEntry.getSymbol(),
+ stackEntry.getValue(),
+ stackEntry.getOffset(),
+ stackEntry.getObject(),
+ stackEntry.getText()});
+
+ item.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
+ item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
+
+ // item is current stack pointer FG black, BG light pink
+ if (stackEntry.currentStackPointer()) {
+ item.setBackground(new Color(Display.getCurrent(), 255, 182, 193)); // light pink
+ // PC or LR
+ } else if (stackEntry.registerBased()) {
+ item.setBackground(new Color(Display.getCurrent(), 173, 216, 230)); // light blue
+ // item is out of stack bound FG gray, BG white
+ } else if (stackEntry.outsideStackBounds()) {
+ item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY));
+ // item has no symbols, FG black, BG white
+ } else if ("".equals(stackEntry.getSymbol())) {
+ } else
+ // if stack contains accurate entries, show "ghost" entries as gray
+ if (stackContainsAccurateEntries) {
+ // color accurate stack entries black or blue
+ if (stackEntry.accurate()) {
+ // ram loaded code (instead of execute-in-place code) FG blue
+ if (!stackEntry.xip()) {
+ item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE));
+ }
+ // not accurate stack entry FG gray
+ } else {
+ item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY));
+ }
+ // stack isn't accurate,
+ } else {
+ // ram loaded code (instead of execute-in-place code)
+ if (!stackEntry.xip()) {
+ item.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE));
+ }
+ }
+
+ item.setData(stackEntry);
+ }
+
+ /**
+ * Sets context sensitive help ids to UI elements
+ */
+ void setHelps() {
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(tableCallStack,
+ HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(tableSummary,
+ HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(comboCallStack,
+ HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonAllStackEntries,
+ HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonDecodeFile,
+ HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(buttonSymbolStackEntries,
+ HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(browserPanicDescription,
+ HelpContextIDs.CRASH_ANALYSER_HELP_CRASH_VISUALISER);
+ }
+}