diff --git a/sources/environment/dfmc/application/control-protocols.dylan b/sources/environment/dfmc/application/control-protocols.dylan index 732757dce6..8409df4267 100644 --- a/sources/environment/dfmc/application/control-protocols.dylan +++ b/sources/environment/dfmc/application/control-protocols.dylan @@ -152,8 +152,10 @@ define method run-application else dll-project? & dll-wrap? & phase == #"end" end; - debugger-message("Preparing %=: top? %=, dll? %=, dll-wrap? %=, phase %=", - prepare-for-interaction?, top-level?, dll-project?, dll-wrap?, phase); + debug-target-message(target, $debug-level, + "Preparing %=: top? %=, dll? %=, dll-wrap? %=, phase %=", + prepare-for-interaction?, top-level?, + dll-project?, dll-wrap?, phase); if (prepare-for-interaction?) initialize-interactive-threads(application, thread); maybe-initialize-allocation-profiling(application) diff --git a/sources/environment/dfmc/application/library.dylan b/sources/environment/dfmc/application/library.dylan index 59590cdf26..4cd740937c 100644 --- a/sources/environment/dfmc/application/library.dylan +++ b/sources/environment/dfmc/application/library.dylan @@ -12,6 +12,7 @@ define library dfmc-environment-application use collections; use io; use channels; + use logging; use environment-protocols; use dfmc-environment-database; @@ -45,6 +46,7 @@ define module dfmc-application project-compilation-mode, project-compilation-mode-setter }; use channels; + use logging; use environment-protocols, // Prevent name clashes with projects:projects, imported above // via project-manager-interface. (Many of these are renamed but diff --git a/sources/environment/dfmc/application/profiling.dylan b/sources/environment/dfmc/application/profiling.dylan index 52b3689e64..d7a0b220d4 100644 --- a/sources/environment/dfmc/application/profiling.dylan +++ b/sources/environment/dfmc/application/profiling.dylan @@ -83,7 +83,7 @@ define method maybe-initialize-cpu-profiling & ~profile-state.state-class-profiling? & application.application-loaded-dylan-library?) let target = application.application-target-app; - debugger-message("Initializing CPU profiling"); + debug-target-message(target, $debug-level, "Initializing CPU profiling"); with-debugger-transaction (target) start-profiling(target, class-profiling?: #f); profile-state.state-profile-initialized? := #t @@ -100,7 +100,7 @@ define method maybe-initialize-allocation-profiling & profile-state.state-class-profiling? & application.application-initialized-interactive-threads?) let target = application.application-target-app; - debugger-message("Initializing allocation profiling"); + debug-target-message(target, $debug-level, "Initializing allocation profiling"); //---*** Temporary hack, this may not always be what we want but //---*** for now switch on breakpoints on all threads let interactive-thread = application-open-interactor-thread(application); @@ -144,15 +144,16 @@ define sealed method stop-profiling-application end; with-debugger-transaction (target) if (interactive-thread) - debugger-message("Stopping general class breakpoint"); + debug-target-message(target, $debug-level, "Stopping general class breakpoint"); let remote-thread = interactive-thread.application-object-proxy; clear-application-class-breakpoint (application, interactive-thread, #f, stop-profile?: #t); #f else - debugger-message("Failed to stop general class breakpoint"); - debugger-message(" thread: %=, class profiling?: %=", - interactive-thread, class-profiling?); + debug-target-message(target, $debug-level, + "Failed to stop general class breakpoint: " + " thread: %=, class-profiling?: %=", + interactive-thread, class-profiling?); end; block () unless (class-profiling?) @@ -260,10 +261,10 @@ define sealed method process-thread-snapshot-frame-snapshots = if (instance?(object, )) values(object, location) else - debugger-message("Corrupted profile stack! Found %=", - object - & environment-object-display-name - (project, object, #f)); + debug-target-message + (target, $debug-level, + "Corrupted profile stack! Found %=", + object & environment-object-display-name(project, object, #f)); values(#f, #f) end; if (object) @@ -296,8 +297,9 @@ define sealed method process-profiling-results let snapshots = profile.application-profile-snapshots; let raw-threads = data.dm-application-profile-threads; let raw-snapshots = data.application-snapshots; - debugger-message("Processing profile results: threads=%d, snapshots=%d", - raw-threads.size, raw-snapshots.size); + debug-target-message(target, $debug-level, + "Processing profile results: threads=%d, snapshots=%d", + raw-threads.size, raw-snapshots.size); do(method (raw-snapshot :: dm-) let raw-snapshots = raw-snapshot.thread-snapshots; let thread-snapshots @@ -345,9 +347,10 @@ define sealed method process-profiling-results application-total-wall-time(profile) := total-wall-time; application-total-page-faults(profile) := total-page-faults; reset-profile-data(target); - debugger-message("Returning, %d snapshots, %d threads", - profile.application-profile-snapshots.size, - profile.application-profile-threads.size); + debug-target-message(target, $debug-level, + "Returning, %d snapshots, %d threads", + profile.application-profile-snapshots.size, + profile.application-profile-threads.size); profile else profile-state.state-last-profile diff --git a/sources/environment/dfmc/application/stop-reason-handlers.dylan b/sources/environment/dfmc/application/stop-reason-handlers.dylan index cc0434ad8d..721f9ec352 100644 --- a/sources/environment/dfmc/application/stop-reason-handlers.dylan +++ b/sources/environment/dfmc/application/stop-reason-handlers.dylan @@ -1070,10 +1070,11 @@ define function handle-library-initialization application.application-just-finished-execution? := #t; end; end; - /* - debugger-message("Stopping? %=: top? %= dll? %=, dll-wrap? %=, phase %=", - stop?, top-level?, dll-project?, dll-wrap?, phase); - */ + let target = application.application-target-app; + debug-target-message(target, $debug-level, + "Stopping? %=: top? %= really-top? dll? %=, dll-wrap? %=, phase %=", + stop?, top-level?, really-top-level?, dll-project?, dll-wrap?, + phase); stop? end function handle-library-initialization; diff --git a/sources/environment/dfmc/application/thread-objects.dylan b/sources/environment/dfmc/application/thread-objects.dylan index ecc7a52797..5b9ff54788 100644 --- a/sources/environment/dfmc/application/thread-objects.dylan +++ b/sources/environment/dfmc/application/thread-objects.dylan @@ -101,8 +101,9 @@ end class; define method process-next-interaction-request (application :: , thread :: ) => () - debugger-message("process-next-interaction-request on %=", thread); let target = application.application-target-app; + debug-target-message(target, $debug-level, + "process-next-interaction-request on %=", thread); let path = target.debug-target-access-path; let state-model = thread-state-model(application, thread); let requests-pending? = @@ -154,7 +155,8 @@ define method request-interaction context :: , module :: , code-string :: , state :: ) => (request :: ) - debugger-message("request-interaction on %=", thread); + debug-target-message(application.application-target-app, $debug-level, + "request-interaction on %=", thread); let request = make(, string: code-string, module: module, context: context, application-state: state); @@ -349,7 +351,8 @@ define method suspend-application-thread unless (thread-available-for-interaction?(target, remote-thread)) error("Cannot suspend a thread that is not ready for interaction"); end; - debugger-message("Suspending environment interactive thread %=", remote-thread); + debug-target-message(target, $debug-level, + "Suspending environment interactive thread %=", remote-thread); suspend-thread(path, remote-thread); thread-permanently-suspended?(path, remote-thread) := #t; end @@ -472,8 +475,9 @@ define method request-evaluator-thread #key name :: = next-evaluator-thread-name(application), thread :: = application.dylan-thread-manager) => (thread :: ) - debugger-message("request-evaluator-thread %=", name); let target = application.application-target-app; + debug-target-message(target, $debug-level, + "request-evaluator-thread %=", name); let success? = spawn-interactive-thread(target, name, thread: thread); let stop-reason :: = @@ -493,8 +497,9 @@ end method; define method install-evaluator-thread (application :: , thread :: , name :: ) => () - debugger-message("install-evaluator-thread %= %=", name, thread); let target = application.application-target-app; + debug-target-message(target, $debug-level, + "install-evaluator-thread %= %=", name, thread); let path = target.debug-target-access-path; let state-model = thread-state-model(application, thread); suspend-thread(path, thread); @@ -586,7 +591,8 @@ define method application-open-interactor-thread if (interactive-threads?) // If we fall through to here, spawn a new thread - debugger-message("application-open-interactor-thread spawning new thread"); + debug-target-message(target, $debug-level, + "application-open-interactor-thread spawning new thread"); create-application-thread(application, "") else // If we fall through to here, just use any thread. @@ -599,8 +605,9 @@ define method application-open-interactor-thread end; end end; - debugger-message("application-open-interactor-thread chose Thread %=", - thread.application-object-proxy); + debug-target-message(target, $debug-level, + "application-open-interactor-thread chose Thread %=", + thread.application-object-proxy); thread end method; @@ -618,7 +625,8 @@ define method resume-evaluator-thread end if; if (thread-permanently-suspended?(path, thread)) - debugger-message("Resuming environment interactive thread %=", thread); + debug-target-message(target, $debug-level, + "Resuming environment interactive thread %=", thread); thread-permanently-suspended?(path, thread) := #f; end if; end method; @@ -636,7 +644,8 @@ define method suspend-evaluator-thread let thread-trans-id = thread-state-transaction(application, thread); if (thread-trans-id & (thread-trans-id == trans-id)) - debugger-message("Suspending environment interactive thread %=", thread); + debug-target-message(target, $debug-level, + "Suspending environment interactive thread %=", thread); thread-permanently-suspended?(path, thread) := #t; end if; end method; diff --git a/sources/environment/target-application/control.dylan b/sources/environment/target-application/control.dylan index 51918c1141..0a90a27129 100644 --- a/sources/environment/target-application/control.dylan +++ b/sources/environment/target-application/control.dylan @@ -14,7 +14,8 @@ Warranty: Distributed WITHOUT WARRANTY OF ANY KIND define method stop-target-application (application :: , #key client-data = #f) => () - thread-debug-message("Stopping target application"); + debug-target-message(application, $debug-level, + "Stopping target application"); let stop-reason = make(, client-data: client-data); @@ -26,7 +27,8 @@ end method; define method stop-application-request (application :: ) => () - thread-debug-message("Stopping target application temporarily"); + debug-target-message(application, $debug-level, + "Stopping target application temporarily"); let stop-reason :: = make(); stop-application @@ -57,17 +59,21 @@ end function; define method continue-target-application (application :: , remote-thread) => () - debugger-message("Selected Thread is %=", remote-thread); + debug-target-message(application, $debug-level, + "Selected Thread is %=", remote-thread); application.application-selected-thread := remote-thread; if (current-thread() == application.manager-thread) application-continuation-pending(application); else - thread-debug-message("Continuing target application"); + debug-target-message(application, $debug-level, + "Continuing target application"); with-lock(application.debugger-transaction) - thread-debug-message("Releasing debugger-transaction-notification"); + debug-target-message(application, $debug-level, + "Releasing debugger-transaction-notification"); release(application.debugger-transaction-notification); - thread-debug-message("Waiting for debugger-transaction-complete"); + debug-target-message(application, $debug-level, + "Waiting for debugger-transaction-complete"); wait-for(application.debugger-transaction-complete); end with-lock; end; @@ -92,7 +98,8 @@ define method target-application-state (application :: ) application.been-managed? => #"closed"; otherwise => #"uninitialized"; end case; - thread-debug-message("target-application-state is %=", state); + debug-target-message(application, $debug-level, + "target-application-state is %=", state); state end method; diff --git a/sources/environment/target-application/library.dylan b/sources/environment/target-application/library.dylan index bfbba72d64..051e04cdde 100644 --- a/sources/environment/target-application/library.dylan +++ b/sources/environment/target-application/library.dylan @@ -14,6 +14,7 @@ define library target-application use release-info; + use logging; use access-path; use debugger-manager; @@ -40,6 +41,7 @@ define module target-application-internals use release-info; + use logging; use access-path, rename: { thread-name => ap-thread-name}; use debugger-manager, diff --git a/sources/environment/target-application/synchronized-access.dylan b/sources/environment/target-application/synchronized-access.dylan index e08d786f61..bed415282e 100644 --- a/sources/environment/target-application/synchronized-access.dylan +++ b/sources/environment/target-application/synchronized-access.dylan @@ -84,7 +84,8 @@ define method perform-debugger-transaction if (application.under-management?) temporary-stop? := application-temporary-stop?(application); - thread-debug-message("Performing debugger transaction"); + debug-target-message(application, $debug-level, + "Performing debugger transaction"); block() application.thread-being-served := transaction-thread; do-transaction(); @@ -97,12 +98,12 @@ define method perform-debugger-transaction // Continue the application only if explicitly requested to do // so by clients, or if we explicitly stopped the running application if (continue) - thread-debug-message - ("perform-debugger-transaction: continue application"); + debug-target-message(application, $debug-level, + "perform-debugger-transaction: continue application"); continue(); elseif (temporary-stop?) - thread-debug-message - ("temporary-stop-reason for interrupting application"); + debug-target-message(application, $debug-level, + "temporary-stop-reason for interrupting application"); continue-target-application(application, application.application-selected-thread); end if @@ -128,7 +129,8 @@ define method manage-debugger-transaction with-lock (application.debugger-transaction) // with a lock on the current transaction, open the floodgates // for threads requiring debugger transactions - thread-debug-message("Releasing debugger-session"); + debug-target-message(application, $debug-level, + "Releasing debugger-session"); release(application.debugger-session); // Enter a wait state for continuously serving client thread @@ -138,13 +140,15 @@ define method manage-debugger-transaction while (begin let wait-state = #"waiting"; while (wait-state == #"waiting") - thread-debug-message("Waiting for debugger-transaction-notification"); + debug-target-message(application, $debug-level, + "Waiting for debugger-transaction-notification"); if (wait-for(application.debugger-transaction-notification, timeout: application.debugger-transaction-timeout)) thunk := application.interruption-function; wait-state := thunk; else - thread-debug-message("Waiting for debugger-session"); + debug-target-message(application, $debug-level, + "Waiting for debugger-session"); if (wait-for(application.debugger-session, mode: #"write", timeout: application.debugger-transaction-timeout)) wait-state := #f; @@ -162,7 +166,8 @@ define method manage-debugger-transaction application.interruption-results := #[]; end block; - thread-debug-message("Releasing interruption-evaluated"); + debug-target-message(application, $debug-level, + "Releasing interruption-evaluated"); release(application.interruption-evaluated); end while; @@ -173,17 +178,20 @@ define method manage-debugger-transaction // inclusive claims on the session before going back into // exclusive mode unless (application.debugger-session.owned?) - thread-debug-message("Waiting for debugger-session"); + debug-target-message(application, $debug-level, + "Waiting for debugger-session"); wait-for(application.debugger-session, mode: #"write"); end; // Lastly, signal all client threads that this debugger // transaction is now complete, in response to a request // to continue the stopped thread - thread-debug-message("Releasing debugger-transaction-complete"); + debug-target-message(application, $debug-level, + "Releasing debugger-transaction-complete"); release-all(application.debugger-transaction-complete); end with-lock; - thread-debug-message("debugger transaction is complete"); + debug-target-message(application, $debug-level, + "debugger transaction is complete"); end method; @@ -195,7 +203,8 @@ define method call-debugger-function (application :: , function :: , #rest arguments) => (#rest results) - thread-debug-message("Entered CALL-DEBUGGER-FUNCTION"); + debug-target-message(application, $debug-level, + "Entered CALL-DEBUGGER-FUNCTION"); let transaction-thread = current-thread(); if (transaction-thread == application.manager-thread) apply(function, arguments) @@ -208,10 +217,12 @@ define method call-debugger-function application.interruption-function := method() apply(function, arguments) end; - thread-debug-message("Releasing debugger-transaction-notification"); + debug-target-message(application, $debug-level, + "Releasing debugger-transaction-notification"); release(application.debugger-transaction-notification); - thread-debug-message("Waiting for interruption-evaluated"); + debug-target-message(application, $debug-level, + "Waiting for interruption-evaluated"); wait-for(application.interruption-evaluated); let results = application.interruption-results; diff --git a/sources/environment/target-application/target-application.dylan b/sources/environment/target-application/target-application.dylan index c073203be0..8821480269 100644 --- a/sources/environment/target-application/target-application.dylan +++ b/sources/environment/target-application/target-application.dylan @@ -8,15 +8,6 @@ License: See License.txt in this distribution for details. Warranty: Distributed WITHOUT WARRANTY OF ANY KIND -define function thread-debug-message - (string :: , #rest pants) => () - if (*debugging-debugger?*) - let control = - concatenate(current-thread().thread-name | "???", " : ", string); - apply(debugger-message, control, pants) - end if -end function; - define constant = type-union(, , singleton(#f)); @@ -206,8 +197,8 @@ define method run-target-application local method manage-stop-reason (app :: , sr :: ) => (interested? :: ) - thread-debug-message - ("Entering stop-reason callback for %=", sr); + debug-target-message(application, $debug-level, + "Entering stop-reason callback for %=", sr); let stopping? :: = if (instance?(sr, )) #t @@ -218,7 +209,8 @@ define method run-target-application #f end block; end if; - thread-debug-message("Returning %= from sr callback", stopping?); + debug-target-message(application, $debug-level, + "Returning %= from sr callback", stopping?); stopping? end method; @@ -229,7 +221,8 @@ define method run-target-application application-state-callback(app, #"stopped"); if (dt-prolog) - thread-debug-message("Running debugger transaction prolog"); + debug-target-message(application, $debug-level, + "Running debugger transaction prolog"); block() dt-prolog(app, sr) exception() @@ -243,7 +236,8 @@ define method run-target-application unless (instance?(sr, )) if (dt-epilog) - thread-debug-message("Running debugger transaction epilog"); + debug-target-message(application, $debug-level, + "Running debugger transaction epilog"); block() dt-epilog(app, sr) exception() diff --git a/sources/environment/tests/dfmc/debugging.dylan b/sources/environment/tests/dfmc/debugging.dylan index 49fc8bfd09..7cff185b58 100644 --- a/sources/environment/tests/dfmc/debugging.dylan +++ b/sources/environment/tests/dfmc/debugging.dylan @@ -31,6 +31,16 @@ define function dbg-machine () => (machine :: ); end if end function; +define function test-debugger-message + (string :: , #rest args) => () + let target = *test-application-application*.application-target-app; + if (target) + apply(debug-target-message, target, $info-level, string, args) + else + apply(debug-message, string, args); + end if; +end function; + define constant $project-message-queue = make(); define constant $project-message-notification = make(, lock: make()); @@ -94,8 +104,8 @@ end function; define function ensure-application-at-start () if (*test-application-application* & *test-application-application*.application-state ~== #"closed") - debugger-message("Application in state %s, closing", - *test-application-application*.application-state); + test-debugger-message("Application in state %s, closing", + *test-application-application*.application-state); close-application(*test-application*, wait-for-termination?: #t) end if; @@ -110,7 +120,8 @@ define function ensure-application-at-start () machine: machine); iterate loop (initialized? = #f, stopped? = #t, transient-bp-count = 0) - debugger-message("I=%= S=%= BP=%d", initialized?, stopped?, transient-bp-count); + test-debugger-message("I=%= S=%= BP=%d", + initialized?, stopped?, transient-bp-count); unless (initialized? & stopped? & zero?(transient-bp-count)) let message = await-project-message(); select (message by instance?) @@ -120,11 +131,11 @@ define function ensure-application-at-start () error("run-application failed for %s", message.message-project.project-name); => - debugger-message(" Application initialized"); + test-debugger-message(" Application initialized"); loop(#t, stopped?, transient-bp-count); => let state = *test-application-application*.application-state; - debugger-message(" Application state is now %s", state); + test-debugger-message(" Application state is now %s", state); if (state == #"running") loop(initialized?, #f, transient-bp-count); else @@ -133,7 +144,7 @@ define function ensure-application-at-start () => let breakpoint = message.message-breakpoint; let state = message.message-breakpoint-state; - debugger-message + test-debugger-message (" Breakpoint %s (%=) state is now %s", breakpoint, environment-object-id(*test-application*, breakpoint), @@ -150,7 +161,7 @@ define function ensure-application-at-start () end if; => for (thread in *test-application-application*.application-threads) - debugger-message + test-debugger-message (" Thread %s (%s) index %s state %s suspended %=", thread, environment-object-primitive-name(*test-application*, thread), @@ -160,7 +171,7 @@ define function ensure-application-at-start () end for; loop(initialized?, stopped?, transient-bp-count); otherwise => - debugger-message("%=", message); + test-debugger-message("%=", message); loop(initialized?, stopped?, transient-bp-count); end select; end unless; @@ -171,10 +182,10 @@ define function close-debugging-test-project () => () close-application(*test-application-application*); iterate loop() let state = *test-application-application*.application-state; - debugger-message("closing, state is %s", state); + test-debugger-message("closing, state is %s", state); if (state ~== #"closed") let message = await-project-message(); - debugger-message("%=", message); + test-debugger-message("%=", message); loop(); end if; end iterate; @@ -313,7 +324,7 @@ define test interactivity-test () clear-project-messages(); let code = item.head; - debugger-message("Evaluate: %s", code); + test-debugger-message("Evaluate: %s", code); let transaction-id = project-execute-code(*test-application*, code, main-thread, @@ -325,7 +336,7 @@ define test interactivity-test () select (message by instance?) => let state = *test-application-application*.application-state; - debugger-message(" Application state is now %s", state); + test-debugger-message(" Application state is now %s", state); select (state) #"stopped" => #f; @@ -334,7 +345,7 @@ define test interactivity-test () end select; otherwise => - debugger-message("%=", message); + test-debugger-message("%=", message); loop(); end select; end iterate; @@ -354,7 +365,7 @@ define test interactivity-test () let value-string = print-environment-object-to-string (*test-application*, value, namespace: module); - debugger-message(" %s = %s", name, value-string); + test-debugger-message(" %s = %s", name, value-string); check-true("Return value", regex-position(pattern, value-string)); end; dispose-interactor-return-values(*test-application*, transaction-id); diff --git a/sources/environment/tests/dfmc/library.dylan b/sources/environment/tests/dfmc/library.dylan index 6287eb1b0c..4c677dd096 100644 --- a/sources/environment/tests/dfmc/library.dylan +++ b/sources/environment/tests/dfmc/library.dylan @@ -16,6 +16,7 @@ define library dfmc-environment-test-suite use testworks; use channels; + use logging; use regular-expressions; use dylan-orb; @@ -30,6 +31,7 @@ define library dfmc-environment-test-suite use access-path; use local-access-path; use remote-access-path; + use debugger-manager; export dfmc-environment-test-suite; end library dfmc-environment-test-suite; diff --git a/sources/environment/tests/dfmc/module.dylan b/sources/environment/tests/dfmc/module.dylan index e24c335752..de8ab1f3a3 100644 --- a/sources/environment/tests/dfmc/module.dylan +++ b/sources/environment/tests/dfmc/module.dylan @@ -16,6 +16,7 @@ define module dfmc-environment-test-suite use locators; use file-system; use threads; + use logging; use source-records; use operating-system, @@ -28,7 +29,7 @@ define module dfmc-environment-test-suite import: { compile-regex, regex-position }; use dylan-orb; - use access-path, import: { debugger-message }; + use debugger-manager, import: { debug-target-message }; use environment-protocols, exclude: { application-filename, diff --git a/sources/runtime-manager/access-path/access-path.dylan b/sources/runtime-manager/access-path/access-path.dylan index 823f81cf58..dd4cc6a8d8 100644 --- a/sources/runtime-manager/access-path/access-path.dylan +++ b/sources/runtime-manager/access-path/access-path.dylan @@ -35,6 +35,9 @@ define abstract class () slot access-path-abstract-handle :: , init-value: #f; + slot access-path-log :: ; + constant slot access-path-log-lock :: = make(); + constant slot symbol-file-locations :: , init-value: #[], init-keyword: symbol-file-locations:; @@ -178,6 +181,27 @@ define open generic make-access-connection #key) => (conn :: ); +define method initialize + (ap :: , #key, #all-keys) => () + next-method(); + let ap-log = get-log("access-path") | make(, name: "access-path"); + ap.access-path-log := ap-log; + let debug-log = environment-variable("OPEN_DYLAN_DEBUGGING_LOG"); + if (debug-log) + select (debug-log by \=) + "trace" => ap-log.log-level := $trace-level; + "debug" => ap-log.log-level := $debug-level; + "info" => ap-log.log-level := $info-level; + "warn", "warning" => ap-log.log-level := $warn-level; + "error" => ap-log.log-level := $error-level; + otherwise => #f; + end select; + add-target(ap-log, + make(, + pathname: "dylan-access-path.log")); + end if; +end method; + ///// INITIALIZE // Initializes an instance of , which includes // firing up the remote process. @@ -243,59 +267,43 @@ define method initialize (ap :: , #key) => () next-method(); end method; - - -/// Debugging the Debugger is like groping around in the dark. -/// These functions will allow a full report to be generated for -/// everything that ever took place on every thread on both sides -/// of the tether during a debugger session. - - -define variable *debugging-debugger?* = #f; - -define variable *debugger-stream* = #f; - -define variable *debugger-stream-count* = 0; - -define function make-debugger-stream(file-name :: ) - *debugging-debugger?* := #t; - - *debugger-stream* := - make (, - locator: as(, - format-to-string(concatenate(file-name, ".%d"), *debugger-stream-count*)), - direction: #"output"); - - *debugger-stream-count* := *debugger-stream-count* + 1; -end function; - -// make-debugger-stream("U:\\nosa\\dylan\\admin\\logs\\debugging"); - -define function close-debugger-stream() - if (*debugger-stream*) - close(*debugger-stream*); +define function access-path-message + (ap :: , level :: , object :: , #rest args) + => () + with-lock (ap.access-path-log-lock) + apply(log-message, level, ap.access-path-log, object, args) end; end function; +// Used by the nub for printing trace-level messages define function debugger-message (string :: , #rest args) => () - if (*debugging-debugger?*) - let string :: = as(, string); - if (*debugger-stream*) - apply(format, *debugger-stream*, concatenate("\n### ", string, "\n"), args); - // force-output(*debugger-stream*); - else - // apply(format-out, concatenate("\n### ", string, "\n"), args); - apply(nub-debug-message, string, args) - end if; + let string :: = as(, string); + let ap + = with-lock (*access-path-lock*) + first(*current-access-paths*, default: #f) + end with-lock; + if (ap) + apply(access-path-message, ap, $trace-level, string, args); + else + apply(debug-message, string, args); end if; end function; +// Used by the nub for printing error-level messages +// TODO: Rectification of names define function nub-debug-message (string :: , #rest args) => () let string :: = as(, string); - apply(debug-message, string, args) - // apply(format-out, concatenate("\n### ", string, "\n"), args); + let ap + = with-lock (*access-path-lock*) + first(*current-access-paths*, default: #f) + end with-lock; + if (ap) + apply(access-path-message, ap, $error-level, string, args); + else + apply(debug-message, string, args); + end if; end function; define function debugger-error diff --git a/sources/runtime-manager/access-path/app-control.dylan b/sources/runtime-manager/access-path/app-control.dylan index 86689c1717..063c4190b1 100644 --- a/sources/runtime-manager/access-path/app-control.dylan +++ b/sources/runtime-manager/access-path/app-control.dylan @@ -205,7 +205,7 @@ define open generic unhandled-continue-application define method suspend-thread (ap :: , thread :: ) => () if (~thread-suspended? (thread)) - debugger-message("suspend-thread %=", thread); + access-path-message(ap, $debug-level, "suspend-thread %=", thread); thread-suspended?(thread) := #t; thread-state(thread) := "Suspended by debugger"; suspend-application-thread (ap.connection, thread); @@ -221,7 +221,7 @@ define open generic suspend-application-thread define method resume-thread (ap :: , thread :: ) => () if (thread-suspended? (thread)) - debugger-message("resume-thread %=", thread); + access-path-message(ap, $debug-level, "resume-thread %=", thread); thread-suspended?(thread) := #f; thread-state(thread) := "[Can't get thread state]"; resume-application-thread (ap.connection, thread); @@ -236,7 +236,7 @@ end method; define inline method dylan-resume-thread (ap :: , thread :: ) => () - debugger-message("resume-thread %=", thread); + access-path-message(ap, $debug-level, "resume-thread %=", thread); thread-suspended?(thread) := #f; thread-state(thread) := "[Can't get thread state]"; end method; diff --git a/sources/runtime-manager/access-path/library.dylan b/sources/runtime-manager/access-path/library.dylan index d42287314e..e429306a8a 100644 --- a/sources/runtime-manager/access-path/library.dylan +++ b/sources/runtime-manager/access-path/library.dylan @@ -15,6 +15,7 @@ define library access-path use io; use system; use c-ffi; + use logging; export access-path, access-path-nub; diff --git a/sources/runtime-manager/access-path/module.dylan b/sources/runtime-manager/access-path/module.dylan index c9d2c6c186..66a3ed54f1 100644 --- a/sources/runtime-manager/access-path/module.dylan +++ b/sources/runtime-manager/access-path/module.dylan @@ -8,9 +8,6 @@ Warranty: Distributed WITHOUT WARRANTY OF ANY KIND define module access-path - - use common-dylan; - create ///// @@ -33,6 +30,8 @@ define module access-path $access-ok, + access-path-message, + ///// Remote Objects , @@ -420,9 +419,6 @@ define module access-path nub-debug-message; create - *debugging-debugger?*, - make-debugger-stream, - close-debugger-stream, debugger-message, debugger-error; @@ -542,9 +538,11 @@ define module access-path-implementation use streams, import: {, , force-output, close}; use locators, import: {}; use file-system; + use operating-system, import: {environment-variable}; use byte-vector; use table-extensions, import: {}; use c-ffi; + use logging; use access-path; use access-path-nub; diff --git a/sources/runtime-manager/access-path/remote-function-call.dylan b/sources/runtime-manager/access-path/remote-function-call.dylan index 455d074546..b4eb5e5dcb 100644 --- a/sources/runtime-manager/access-path/remote-function-call.dylan +++ b/sources/runtime-manager/access-path/remote-function-call.dylan @@ -35,7 +35,7 @@ define method remote-call (ap :: , thr :: , function :: , #rest arguments) => (ret-addr :: , cookie :: ) - debugger-message("remote-call %= %=", thr, function); + access-path-message(ap, $debug-level, "remote-call %= %=", thr, function); let thread-was-suspended? = thr.thread-suspended?; if (thread-was-suspended?) @@ -61,7 +61,7 @@ define open generic remote-call-on-connection define method remote-call-result (ap :: , thr :: ) => (result :: ) - debugger-message("remote-call-result %=", thr); + access-path-message(ap, $debug-level, "remote-call-result %=", thr); remote-call-result-on-connection(ap.connection, thr); end method; @@ -78,7 +78,7 @@ define open generic remote-call-result-on-connection define method remote-restore-context (ap :: , thr :: , ctx :: ) => () - debugger-message("remote-restore-context %=", thr); + access-path-message(ap, $debug-level, "remote-restore-context %=", thr); remote-restore-context-on-connection(ap.connection, thr, ctx); if (ctx.thread-was-suspended-by-debugger?) // The thread was released only for the duration of this remote @@ -102,7 +102,8 @@ define method remote-call-spy (ap :: , thr :: , function :: , #rest arguments) => (result :: , aborted? :: ) - debugger-message("remote-call-spy %= %= %=", thr, function, arguments); + access-path-message(ap, $debug-level, "remote-call-spy %= %= %=", + thr, function, arguments); // If the selected thread is suspended, release it for the duration // of the remote call. @@ -111,7 +112,9 @@ define method remote-call-spy // continue to be used for spy calls while interacting on other threads let thread-was-permanently-suspended? = thread-permanently-suspended?(ap, thr); if (thread-was-permanently-suspended?) - debugger-message("Releasing permanent suspension on %= for spy call %=", thr, function); + access-path-message(ap, $debug-level, + "Releasing permanent suspension on %= for spy call %=", + thr, function); thread-permanently-suspended?(ap, thr) := #f; end if; @@ -134,7 +137,9 @@ define method remote-call-spy end if; if (thread-was-permanently-suspended?) - debugger-message("Restoring permanent suspension on %= for spy call %=", thr, function); + access-path-message(ap, $debug-level, + "Restoring permanent suspension on %= for spy call %=", + thr, function); thread-permanently-suspended?(ap, thr) := #t; end if; end block; diff --git a/sources/runtime-manager/debugger-manager/debug-target.dylan b/sources/runtime-manager/debugger-manager/debug-target.dylan index 8b3b93e177..41b6d76c75 100644 --- a/sources/runtime-manager/debugger-manager/debug-target.dylan +++ b/sources/runtime-manager/debugger-manager/debug-target.dylan @@ -242,6 +242,14 @@ define method initialize access-path: t.debug-target-access-path); end method; +///// DEBUG-TARGET-MESSAGE +// +define function debug-target-message + (application :: , level :: , object :: , #rest args) + => () + apply(access-path-message, application.debug-target-access-path, level, + object, args); +end function; ///// ADDRESS-CORRESPONDS-TO-PRIMITIVE? (Internal function) // Decides whether a given instruction pointer is within the definition diff --git a/sources/runtime-manager/debugger-manager/invoke-dylan.dylan b/sources/runtime-manager/debugger-manager/invoke-dylan.dylan index 2bb216946f..e7e98eb116 100644 --- a/sources/runtime-manager/debugger-manager/invoke-dylan.dylan +++ b/sources/runtime-manager/debugger-manager/invoke-dylan.dylan @@ -109,13 +109,14 @@ define method handle-debug-point-event #f end if; - debugger-message("handle-debug-point-event\n" - "\nTHREAD:%= TOPF:%= TOPFP:%=\n" - "\nCALLINGF:%= CALLINGFP:%=\n" - "\nBPCALLINGF:%= BPUSEF:%=", - thread, top-frame-now, top-frame-pointer, - calling-frame-now, calling-frame-pointer, - bp.calling-frame, bp.used-frame); + debug-target-message(application, $debug-level, + "handle-debug-point-event" + " THREAD:%= TOPFP:%= " + " CALLINGF:%= CALLINGFP:%=" + " BPCALLINGF:%= BPUSEF:%=", + thread, top-frame-pointer, + calling-frame-now, calling-frame-pointer, + bp.calling-frame, bp.used-frame); if ((top-frame-pointer = bp.used-frame) | ((bp.calling-frame) & (calling-frame-pointer) & @@ -272,9 +273,10 @@ define method handle-interactor-return #"running" => #t; otherwise => #f; end; - debugger-message("handle-interactor-return %= %=", - application.application-just-interacted?, - application.application-running-on-code-entry?); + debug-target-message(application, $debug-level, + "handle-interactor-return %= %=", + application.application-just-interacted?, + application.application-running-on-code-entry?); #f end method; @@ -297,7 +299,9 @@ define method setup-interactor symbolic-C-entry-point :: , symbolic-dll :: false-or(), return-spec :: , #rest args) => (transaction-id :: ) - debugger-message("setup-interactor %= running on %=", thread, current-thread().thread-name-internal); + debug-target-message(application, $debug-level, + "setup-interactor %= running on %=", + thread, current-thread().thread-name-internal); let recovery-manager = find-symbol(application.debug-target-access-path, @@ -393,8 +397,9 @@ define method C-setup-interactor application :: , thread :: , invoker :: , #rest args) => (transaction-id :: ) - debugger-message("C-setup-interactor %= running on %=", - thread, current-thread().thread-name-internal); + debug-target-message(application, $debug-level, + "C-setup-interactor %= running on %=", + thread, current-thread().thread-name-internal); locate-C-spy-function(application, invoker); diff --git a/sources/runtime-manager/debugger-manager/library.dylan b/sources/runtime-manager/debugger-manager/library.dylan index 1b74d7a0ef..7cf4dbb304 100644 --- a/sources/runtime-manager/debugger-manager/library.dylan +++ b/sources/runtime-manager/debugger-manager/library.dylan @@ -11,6 +11,7 @@ define library debugger-manager use common-dylan; use big-integers; use collections; + use logging; use access-path; use tether-downloader; use interactive-symbol-table; @@ -38,6 +39,7 @@ define module debugger-manager ///// , debug-target-access-path, + debug-target-message, debug-target-symbol-table, debug-target-compilation-context, debug-target-compilation-context-setter, @@ -343,6 +345,7 @@ define module dm-internals use threads, rename: {thread-name => thread-name-internal}; use dylan-extensions, import: {, }; use table-extensions, import: {}; + use logging; use access-path, import: { kill-application => kill }; use debugger-manager; diff --git a/sources/runtime-manager/debugger-manager/profile.dylan b/sources/runtime-manager/debugger-manager/profile.dylan index fbdf63eb88..92c4d18f08 100644 --- a/sources/runtime-manager/debugger-manager/profile.dylan +++ b/sources/runtime-manager/debugger-manager/profile.dylan @@ -638,7 +638,8 @@ define method set-application-class-breakpoint else #t end; - debugger-message("Setting class breakpoint in stopped application"); + debug-target-message(application, $debug-level, + "Setting class breakpoint in stopped application"); run-spy-on-thread(application, thread, application.C-spy.primitive-class-breakpoint-pending); @@ -671,7 +672,8 @@ define method clear-application-class-breakpoint stop-profile? => stop-profiling-after-interaction; otherwise => C-interactor; end; - debugger-message("Clearing class breakpoint in stopped application"); + debug-target-message(application, $debug-level, + "Clearing class breakpoint in stopped application"); run-spy-on-thread(application, thread, application.C-spy.primitive-class-breakpoint-pending); @@ -687,7 +689,8 @@ end method clear-application-class-breakpoint; define method clear-application-class-breakpoints (application :: , thread :: ) => (transaction) - debugger-message("Clearing all class breakpoints in stopped application"); + debug-target-message(application, $debug-level, + "Clearing all class breakpoints in stopped application"); run-spy-on-thread(application, thread, application.C-spy.primitive-class-breakpoint-pending); diff --git a/sources/runtime-manager/debugger-manager/stepping.dylan b/sources/runtime-manager/debugger-manager/stepping.dylan index 78b968068c..beae881ec8 100644 --- a/sources/runtime-manager/debugger-manager/stepping.dylan +++ b/sources/runtime-manager/debugger-manager/stepping.dylan @@ -20,7 +20,8 @@ define method align-thread-to-source-location (application :: , thread :: , #key interactive? = #f) => (success? :: ) - debugger-message("align-thread-to-source-location %=", thread); + debug-target-message(application, $debug-level, + "align-thread-to-source-location %=", thread); let success? = #f; let call-frame = get-top-call-frame(application, thread); let obtained-context? = #f; diff --git a/sources/runtime-manager/debugger-manager/threads.dylan b/sources/runtime-manager/debugger-manager/threads.dylan index e2d461fb8e..af9e69a8ab 100644 --- a/sources/runtime-manager/debugger-manager/threads.dylan +++ b/sources/runtime-manager/debugger-manager/threads.dylan @@ -101,9 +101,10 @@ define method remote-thread-information dylan-thread-handle := #f; remote-thread-name := thread.thread-name; end block; - debugger-message("remote-thread-information %= : [%=, %=, %=, %=]", thread, - dylan-thread?, remote-thread-name, - dylan-thread-object, dylan-thread-handle); + debug-target-message(application, $debug-level, + "remote-thread-information %= : [%=, %=, %=, %=]", thread, + dylan-thread?, remote-thread-name, + dylan-thread-object, dylan-thread-handle); values(dylan-thread?, remote-thread-name, dylan-thread-object, dylan-thread-handle); end method; @@ -567,7 +568,9 @@ define method spawn-interactive-thread block () write-value(path, running-dylan-spy-function?, as-remote-value(1)); - debugger-message("spawn-interactive-thread %= on Thread %=", tname, spy-thread); + debug-target-message(application, $debug-level, + "spawn-interactive-thread %= on Thread %=", + tname, spy-thread); let address-of-name = download-byte-string(tname); if (address-of-name & @@ -596,8 +599,9 @@ define method suspend-interesting-thread unless (stopped-thread.thread-suspended?) unless (application.application-just-interacted-on-running-thread?) - debugger-message("Suspending thread %= in response to debug-event", - stopped-thread); + debug-target-message(application, $debug-level, + "Suspending thread %= in response to debug-event %=", + stopped-thread, stop-reason); suspend-thread(access-path, stopped-thread); end; end; @@ -617,8 +621,9 @@ define method resume-selected-thread unless (thread-permanently-suspended?(access-path, remote-thread)) if (remote-thread.thread-suspended?) unless (application.application-just-interacted-on-running-thread?) - debugger-message("Resuming thread %= in response to continuation", - remote-thread); + debug-target-message(application, $debug-level, + "Resuming thread %= in response to continuation", + remote-thread); dylan-resume-thread(access-path, remote-thread); remote-thread; end; @@ -630,18 +635,19 @@ end method; define method resume-all-suspended-threads (application :: ) => (resumed-threads :: ) - debugger-message("Resuming all threads"); + debug-target-message(application, $debug-level, "Resuming all threads"); let access-path = application.debug-target-access-path; let threads = #(); do-threads - (method(remote-thread :: ) + (method (remote-thread :: ) unless (thread-permanently-suspended?(access-path, remote-thread)) if (remote-thread.thread-suspended?) - debugger-message("Resuming thread %= in response to continuation", - remote-thread); + debug-target-message(application, $debug-level, + "Resuming thread %= in response to continuation", + remote-thread); dylan-resume-thread(access-path, remote-thread); threads := pair(remote-thread, threads); end if; diff --git a/sources/runtime-manager/debugger-nub/x86-win32/symbol_lookup.c b/sources/runtime-manager/debugger-nub/x86-win32/symbol_lookup.c index 5e24df1f3b..312cddf6b5 100644 --- a/sources/runtime-manager/debugger-nub/x86-win32/symbol_lookup.c +++ b/sources/runtime-manager/debugger-nub/x86-win32/symbol_lookup.c @@ -40,6 +40,7 @@ void add_boundary_cache char out[1024]; #ifdef DEBUGGING +#include #define debug_me(x, y) \ sprintf(out, x, y); \ debugger_message(out, 0, 0); @@ -172,9 +173,9 @@ NUBINT } else { if (status) { - debug_me("no symbol found for addr\n",0 ); + debug_me("no symbol found for addr",0 ); } else { - debug_me("Error %x\n", GetLastError()); + debug_me("Error %x", GetLastError()); } return((NUBINT) 0); } @@ -217,7 +218,15 @@ NUBINT nub_find_symbol_in_library int i = 0; int j = 0; - debug_me("nub_find_symbol_in_library",0); +#ifdef DEBUGGING + // Make a NUL-terminated copy of the name + for (;i < name_length; ++i) { + extended_name[i] = name[i]; + } + extended_name[i] = '\0'; + debug_me("nub_find_symbol_in_library %s", extended_name); + i = 0; +#endif ensure_debug_information_for_library(process, module);