diff --git a/debug/org.eclipse.cdt.debug.core/.options b/debug/org.eclipse.cdt.debug.core/.options new file mode 100644 index 00000000000..6b989a05c85 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/.options @@ -0,0 +1,5 @@ +org.eclipse.cdt.debug.core/debug=false + +# Reports activity on the ExecutablesManager and its client (Executables viewer) +org.eclipse.cdt.debug.core/debug/executables=false + diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java index b645f121ca4..6788bcf51d3 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.debug.internal.core.DebugConfiguration; import org.eclipse.cdt.debug.internal.core.ICDebugInternalConstants; import org.eclipse.cdt.debug.internal.core.ListenerList; import org.eclipse.cdt.debug.internal.core.SessionManager; +import org.eclipse.cdt.debug.internal.core.Trace; import org.eclipse.cdt.debug.internal.core.disassembly.DisassemblyContextService; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.internal.core.sourcelookup.CommonSourceLookupDirector; @@ -339,6 +340,8 @@ public class CDebugCorePlugin extends Plugin { @Override public void start(BundleContext context) throws Exception { super.start(context); + + Trace.init(); initializeCommonSourceLookupDirector(); createCommandAdapterFactory(); createBreakpointListenersList(); diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/Trace.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/Trace.java new file mode 100644 index 00000000000..d5bd44bea43 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/Trace.java @@ -0,0 +1,108 @@ +package org.eclipse.cdt.debug.internal.core; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; +import org.eclipse.osgi.service.debug.DebugOptions; +import org.eclipse.osgi.service.debug.DebugTrace; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.util.tracker.ServiceTracker; + +/** + * Class for getting a singleton instance of DebugTrace, an extremely useful + * utility for tracing multithreaded code, as each trace statement prints out + * the thread and the time (in millisecond granularity). For performance + * reasons, trace statements should explicitly check a trace flag before calling + * into a DebugTrace method. E.g., + * + *
+ *
+ * if (Trace.DEBUG_EXECUTABLES) DebugTrace.getTrace.trace(null, ...);
+ *
+ *
+ *
+ * The alternative is to have DebugTrace check the debug option for you (i.e., + * don't pass null for first param), but this incurs a relatively heavy price + * considering the trace statements are present in release code. An advantage of + * asking DebugTrace to do the check is that is that it supports trace options + * changing during the workbench lifetime. However that's an unlikely and + * esoteric scenario. + * + *
+ * This class is also a central location for trace flags. They are public static + * fields, so checking them in trace statements is very efficient. They are set + * at plugin startup. + * + *
+ * DebugTrace objects are particular to a plugin. Plugins can reuse most of this
+ * class definition. However, since it's all based on static methods and fields,
+ * reuse means copy-n-paste. Making this not rely on statics would complicate
+ * things and simplicity and efficiency is what we need most when it comes to
+ * trace. When making a copy of this class for your plugin, make sure to update
+ * the Activator class reference (appears three times). Also, the DEBUG_XXXX
+ * fields will need to be whatever options are used in your plugin.
+ */
+public class Trace {
+ // See .options file in plugin for description of these flags. DEBUG is the base option.
+ public static boolean DEBUG;
+ public static boolean DEBUG_EXECUTABLES;
+
+ /**
+ * Use a no-op trace when a real one isn't available. Simplifies life for
+ * clients; no need to check for null.
+ */
+ private static final DebugTrace NULL_TRACE = new DebugTrace() {
+ public void trace(String option, String message) {}
+ public void trace(String option, String message, Throwable error) {}
+ public void traceDumpStack(String option) {}
+ public void traceEntry(String option) {}
+ public void traceEntry(String option, Object methodArgument) {}
+ public void traceEntry(String option, Object[] methodArguments) {}
+ public void traceExit(String option) {}
+ public void traceExit(String option, Object result) {}
+ };
+
+ /** Should be called by plugin's startup method() */
+ public static void init() {
+ DEBUG = CDebugCorePlugin.getDefault().isDebugging();
+
+ String option = Platform.getDebugOption(CDebugCorePlugin.PLUGIN_ID + "/debug/executables"); //$NON-NLS-1$
+ DEBUG_EXECUTABLES = DEBUG && ((option != null) ? option.equalsIgnoreCase("true") : false); //$NON-NLS-1$
+ }
+ /** Singleton trace object */
+ private static DebugTrace trace;
+
+ /**
+ * Gets the singleton trace object, or a null trace object if a real one
+ * isn't available
+ *
+ * @return trace object; never null
+ */
+ synchronized public static DebugTrace getTrace() {
+ if (trace == null) {
+ Plugin plugin = CDebugCorePlugin.getDefault();
+ if (plugin != null) {
+ Bundle bundle = plugin.getBundle();
+ if (bundle != null) {
+ BundleContext context = bundle.getBundleContext();
+ if (context != null) {
+ ServiceTracker