[haiku-commits] haiku: hrev47378 - in src/apps/debugger: debug_info dwarf user_interface/gui controllers debug_info/loading_state_handlers

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 15 Jun 2014 17:08:50 +0200 (CEST)

hrev47378 adds 6 changesets to branch 'master'
old head: 004f41565ee7ad9c9d7d32f86330401ce5b16796
new head: d44d8207a86103afa47f1862c06ff46e46e1cb33
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=d44d820+%5E004f415

----------------------------------------------------------------------------

4605feb: Debugger: Add/handle new suspend state for jobs.
  
  - In addition to waiting for one or more dependent jobs to complete,
  a job can now potentially wait for user input to proceed further. Add
  a corresponding job_wait_status and respective handling in Worker.

a262768: Debugger: Add classes for representing image loading state.
  
  Adds a hierarchy of classes for preserving the loading state information for
  a LoadImageDebugInfoJob. These include:
        - ImageDebugInfoLoadingState:
                Top level class that simply stores a reference for  the 
specific info
                state that we're currently attempting to load.
  
        - SpecificImageDebugInfoLoadingState:
                Abstract base class representing state information specific to a
                particular kind of debug information.
  
        - DwarfImageDebugInfoLoadingState:
                Implementation of the above for the case of DWARF.
  
        - DwarfFileLoadingState:
                Encapsulates the in-progress loading state of a DWARF file for 
the case
                where a file's debug information is referenced externally, but 
cannot
                be found.

7cab832: Debugger: Add support for suspending LoadImageDebugInfoJob.
  
  DwarfFile:
  - Loading is now split into two steps, the first of which simply attempts to
  verify the presence of debug information. If the latter is referenced
  externally, but cannot be found on disk, the corresponding file reference is
  returned.
  
  TeamDebugInfo:
  - Add state parameter to LoadImageDebugInfo(). Use it to preserve where we
  are in the specific info loading loop if necessary.
  
  SpecificTeamDebugInfo:
  - Add parameter to CreateImageDebugInfo() to allow passing in a state object
  and adjust implementing subclasses accordingly.
  
  DwarfTeamDebugInfo:
  - Preserve and/or pass down DwarfFile's loading state as needed.
  
  DwarfManager:
  - When attempting to load a DwarfFile, detect the case where external debug
    information is referenced, but could not be located. If so, preserve the
    relevant details in the loading state, so the user can be notified and
    asked to find it accordingly.
  
  LoadImageDebugInfoJob:
  - Keep a state object for the progress of the current loading job. If a
    particular image fails due to needing user input, suspend ourselves
    until such input has been provided.

d9e9718: Debugger: Add file prompt hook to UserInterface.
  
  In some circumstances, it may be necessary to ask the user to locate a file
  from the lower layers. Adds the corresponding hook to UserInterface, and a
  stub implementation for CommandLineUserInterface.
  
  Adds full implementation for GraphicalUserInterface.

3315110: Debugger: Start adding the groundwork for load state handlers.
  
  Adds abstract class ImageDebugLoadingStateHandler which simply contains two
  hooks, which allow one to a) ask it if it supports a handling a particular
  type of loading state, and b) if so, ask it to attempt to handle that case,
  given the passed in user interface object.
  
  Also adds implementing subclass for DwarfImageDebugInfo, currently
  intended primarily to handle the case of missing external debug information.
  At present, this just supports prompting the user to find/install the file,
  but eventually this will be extended to also support automatically installing
  the corresponding debug information package, if applicable.
  
  Finally, adds ImageDebugLoadingStateHandlerRoster, which acts as a front end
  for matching up a given loading state with the appropriate handler.

d44d820: Debugger: Finish handling of missing debug information.
  
  Add a listener interface for LoadImageDebugInfoJob that allows it to request
  user assistance based on its current state. Adjust callers to pass in said
  listener accordingly.
  
  Implement the aforementioned listener interface in TeamDebugger, and use the
  loading state handler roster to find the appropriate handler / handle the 
request.
  
  This implements most of what's needed for #10138, the main piece still missing
  is for the dwarf handler to detect whether the image in question comes from a 
package,
  and if so, to offer to install the corresponding debug information package 
rather than
  locating the file manually, assuming such a package exists.

                                         [ Rene Gollent <rene@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

43 files changed, 1131 insertions(+), 68 deletions(-)
src/apps/debugger/Debugger.cpp                   |   8 +-
src/apps/debugger/Jamfile                        |   9 ++
src/apps/debugger/MessageCodes.h                 |   5 +-
src/apps/debugger/controllers/TeamDebugger.cpp   |  58 +++++++-
src/apps/debugger/controllers/TeamDebugger.h     |  12 +-
src/apps/debugger/controllers/ThreadHandler.cpp  |   7 +-
src/apps/debugger/controllers/ThreadHandler.h    |   4 +
.../debug_info/DebuggerTeamDebugInfo.cpp         |   3 +-
.../debugger/debug_info/DebuggerTeamDebugInfo.h  |   2 +
.../DwarfImageDebugInfoLoadingState.cpp          |  27 ++++
.../debug_info/DwarfImageDebugInfoLoadingState.h |  30 ++++
.../debugger/debug_info/DwarfTeamDebugInfo.cpp   |  25 +++-
.../debugger/debug_info/DwarfTeamDebugInfo.h     |   2 +
.../debug_info/ImageDebugInfoLoadingState.cpp    |  61 ++++++++
.../debug_info/ImageDebugInfoLoadingState.h      |  43 ++++++
.../debug_info/ImageDebugLoadingStateHandler.cpp |  12 ++
.../debug_info/ImageDebugLoadingStateHandler.h   |  30 ++++
.../ImageDebugLoadingStateHandlerRoster.cpp      | 143 ++++++++++++++++++
.../ImageDebugLoadingStateHandlerRoster.h        |  56 +++++++
.../SpecificImageDebugInfoLoadingState.cpp       |  19 +++
.../SpecificImageDebugInfoLoadingState.h         |  21 +++
.../debugger/debug_info/SpecificTeamDebugInfo.h  |   4 +-
src/apps/debugger/debug_info/TeamDebugInfo.cpp   |  16 +-
src/apps/debugger/debug_info/TeamDebugInfo.h     |   3 +
.../DwarfLoadingStateHandler.cpp                 |  73 +++++++++
.../DwarfLoadingStateHandler.h                   |  27 ++++
src/apps/debugger/dwarf/DwarfFile.cpp            |  57 +++++--
src/apps/debugger/dwarf/DwarfFile.h              |   9 +-
.../debugger/dwarf/DwarfFileLoadingState.cpp     |  26 ++++
src/apps/debugger/dwarf/DwarfFileLoadingState.h  |  38 +++++
src/apps/debugger/dwarf/DwarfManager.cpp         |  43 ++++--
src/apps/debugger/dwarf/DwarfManager.h           |   8 +-
src/apps/debugger/dwarf/Jamfile                  |   1 +
src/apps/debugger/jobs/GetStackTraceJob.cpp      |   6 +-
src/apps/debugger/jobs/Jobs.h                    |  26 +++-
src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp |  49 +++++-
src/apps/debugger/user_interface/UserInterface.h |   5 +-
.../cli/CommandLineUserInterface.cpp             |   9 +-
.../cli/CommandLineUserInterface.h               |   3 +-
.../gui/GraphicalUserInterface.cpp               | 148 ++++++++++++++++++-
.../user_interface/gui/GraphicalUserInterface.h  |   8 +
src/apps/debugger/util/Worker.cpp                |  51 ++++++-
src/apps/debugger/util/Worker.h                  |  12 +-

############################################################################

Commit:      4605febacfbad61b13dd93e4f599884e2c38f886
URL:         http://cgit.haiku-os.org/haiku/commit/?id=4605feb
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Mon Dec  2 02:10:51 2013 UTC

Debugger: Add/handle new suspend state for jobs.

- In addition to waiting for one or more dependent jobs to complete,
a job can now potentially wait for user input to proceed further. Add
a corresponding job_wait_status and respective handling in Worker.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/util/Worker.cpp 
b/src/apps/debugger/util/Worker.cpp
index 304c3bd..e395af4 100644
--- a/src/apps/debugger/util/Worker.cpp
+++ b/src/apps/debugger/util/Worker.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2012-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
@@ -114,6 +114,13 @@ Job::WaitFor(const JobKey& key)
 }
 
 
+status_t
+Job::WaitForUserInput()
+{
+       return fWorker->WaitForUserInput(this);
+}
+
+
 void
 Job::SetWorker(Worker* worker)
 {
@@ -141,6 +148,7 @@ Job::SetWaitStatus(job_wait_status status)
        fWaitStatus = status;
        switch (fWaitStatus) {
                case JOB_DEPENDENCY_ACTIVE:
+               case JOB_USER_INPUT_WAITING:
                        fState = JOB_STATE_WAITING;
                        break;
                default:
@@ -316,6 +324,25 @@ Worker::GetJob(const JobKey& key)
 
 
 status_t
+Worker::ResumeJob(Job* job)
+{
+       AutoLocker<Worker> locker(this);
+
+       for (JobList::Iterator it = fSuspendedJobs.GetIterator(); it.Next();) {
+               if (it.Current() == job) {
+                       it.Remove();
+                       job->SetState(JOB_STATE_UNSCHEDULED);
+                       fUnscheduledJobs.Add(job);
+                       release_sem(fWorkToDoSem);
+                       return B_OK;
+               }
+       }
+
+       return B_ENTRY_NOT_FOUND;
+}
+
+
+status_t
 Worker::AddListener(const JobKey& key, JobListener* listener)
 {
        AutoLocker<Worker> locker(this);
@@ -359,6 +386,21 @@ Worker::WaitForJob(Job* waitingJob, const JobKey& key)
 }
 
 
+status_t
+Worker::WaitForUserInput(Job* waitingJob)
+{
+       AutoLocker<Worker> locker(this);
+
+       if (fTerminating || waitingJob->State() == JOB_STATE_ABORTED)
+               return B_INTERRUPTED;
+
+       waitingJob->SetWaitStatus(JOB_USER_INPUT_WAITING);
+       fSuspendedJobs.Add(waitingJob);
+
+       return B_OK;
+}
+
+
 /*static*/ status_t
 Worker::_WorkerLoopEntry(void* data)
 {
@@ -439,10 +481,13 @@ Worker::_AbortJob(Job* job, bool removeFromTable)
                        break;
 
                case JOB_STATE_WAITING:
-                       job->Dependency()->DependentJobs().Remove(job);
+               {
+                       Job* dependency = job->Dependency();
+                       if (dependency != NULL)
+                               dependency->DependentJobs().Remove(job);
                        job->SetDependency(NULL);
                        break;
-
+               }
                case JOB_STATE_ACTIVE:
                case JOB_STATE_FAILED:
                case JOB_STATE_SUCCEEDED:
diff --git a/src/apps/debugger/util/Worker.h b/src/apps/debugger/util/Worker.h
index 411b9cb..f3fa550 100644
--- a/src/apps/debugger/util/Worker.h
+++ b/src/apps/debugger/util/Worker.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef WORKER_H
@@ -31,7 +32,9 @@ enum job_wait_status {
        JOB_DEPENDENCY_SUCCEEDED,
        JOB_DEPENDENCY_FAILED,
        JOB_DEPENDENCY_ABORTED,
-       JOB_DEPENDENCY_ACTIVE
+       JOB_DEPENDENCY_ACTIVE,
+
+       JOB_USER_INPUT_WAITING
                // internal only
 };
 
@@ -88,6 +91,7 @@ public:
 
 protected:
                        job_wait_status         WaitFor(const JobKey& key);
+                       status_t                        WaitForUserInput();
 
 private:
                        friend class Worker;
@@ -141,6 +145,10 @@ public:
                        void                            AbortJob(const JobKey& 
key);
                        Job*                            GetJob(const JobKey& 
key);
 
+                       status_t                        ResumeJob(Job* job);
+                                                                       // only 
valid for jobs that are
+                                                                       // 
suspended pending user input
+
                        status_t                        AddListener(const 
JobKey& key,
                                                                        
JobListener* listener);
                        void                            RemoveListener(const 
JobKey& key,
@@ -178,6 +186,7 @@ private:
 
 private:
                        job_wait_status         WaitForJob(Job* waitingJob, 
const JobKey& key);
+                       status_t                        WaitForUserInput(Job* 
waitingJob);
 
        static  status_t                        _WorkerLoopEntry(void* data);
                        status_t                        _WorkerLoop();
@@ -191,6 +200,7 @@ private:
                        JobTable                        fJobs;
                        JobList                         fUnscheduledJobs;
                        JobList                         fAbortedJobs;
+                       JobList                         fSuspendedJobs;
                        sem_id                          fWorkToDoSem;
                        thread_id                       fWorkerThread;
        volatile bool                           fTerminating;

############################################################################

Commit:      a262768084fef1a4ad73c570f259fab2a31ed8f9
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a262768
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Sun Jun  8 15:41:49 2014 UTC

Debugger: Add classes for representing image loading state.

Adds a hierarchy of classes for preserving the loading state information for
a LoadImageDebugInfoJob. These include:
        - ImageDebugInfoLoadingState:
                Top level class that simply stores a reference for  the 
specific info
                state that we're currently attempting to load.

        - SpecificImageDebugInfoLoadingState:
                Abstract base class representing state information specific to a
                particular kind of debug information.

        - DwarfImageDebugInfoLoadingState:
                Implementation of the above for the case of DWARF.

        - DwarfFileLoadingState:
                Encapsulates the in-progress loading state of a DWARF file for 
the case
                where a file's debug information is referenced externally, but 
cannot
                be found.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index 18ff810..95550ff 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -100,6 +100,7 @@ Application Debugger :
        DebuggerTeamDebugInfo.cpp
        DwarfFunctionDebugInfo.cpp
        DwarfImageDebugInfo.cpp
+       DwarfImageDebugInfoLoadingState.cpp
        DwarfStackFrameDebugInfo.cpp
        DwarfTeamDebugInfo.cpp
        DwarfTypeFactory.cpp
@@ -109,9 +110,11 @@ Application Debugger :
        FunctionInstance.cpp
        GlobalTypeLookup.cpp
        ImageDebugInfo.cpp
+       ImageDebugInfoLoadingState.cpp
        ImageDebugInfoProvider.cpp
        NoOpStackFrameDebugInfo.cpp
        SpecificImageDebugInfo.cpp
+       SpecificImageDebugInfoLoadingState.cpp
        SpecificTeamDebugInfo.cpp
        StackFrameDebugInfo.cpp
        TeamDebugInfo.cpp
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfoLoadingState.cpp 
b/src/apps/debugger/debug_info/DwarfImageDebugInfoLoadingState.cpp
new file mode 100644
index 0000000..d372017
--- /dev/null
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfoLoadingState.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "DwarfImageDebugInfoLoadingState.h"
+
+
+DwarfImageDebugInfoLoadingState::DwarfImageDebugInfoLoadingState()
+       :
+       SpecificImageDebugInfoLoadingState(),
+       fState()
+{
+}
+
+
+DwarfImageDebugInfoLoadingState::~DwarfImageDebugInfoLoadingState()
+{
+}
+
+
+bool
+DwarfImageDebugInfoLoadingState::UserInputRequired() const
+{
+       return fState.state == DWARF_FILE_LOADING_STATE_USER_INPUT_NEEDED;
+}
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfoLoadingState.h 
b/src/apps/debugger/debug_info/DwarfImageDebugInfoLoadingState.h
new file mode 100644
index 0000000..f2edd1c
--- /dev/null
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfoLoadingState.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef DWARF_IMAGE_DEBUG_INFO_LOADING_STATE_H
+#define DWARF_IMAGE_DEBUG_INFO_LOADING_STATE_H
+
+
+#include "DwarfFileLoadingState.h"
+#include "SpecificImageDebugInfoLoadingState.h"
+
+
+class DwarfImageDebugInfoLoadingState
+       : public SpecificImageDebugInfoLoadingState {
+public:
+                                                               
DwarfImageDebugInfoLoadingState();
+       virtual                                         
~DwarfImageDebugInfoLoadingState();
+
+       virtual bool                            UserInputRequired() const;
+
+                       DwarfFileLoadingState& GetFileState()
+                                                                       { 
return fState; }
+
+private:
+                       DwarfFileLoadingState fState;
+};
+
+
+#endif // DWARF_IMAGE_DEBUG_INFO_LOADING_STATE_H
+
diff --git a/src/apps/debugger/debug_info/ImageDebugInfoLoadingState.cpp 
b/src/apps/debugger/debug_info/ImageDebugInfoLoadingState.cpp
new file mode 100644
index 0000000..dffab2f
--- /dev/null
+++ b/src/apps/debugger/debug_info/ImageDebugInfoLoadingState.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "ImageDebugInfoLoadingState.h"
+
+#include "SpecificImageDebugInfoLoadingState.h"
+
+
+ImageDebugInfoLoadingState::ImageDebugInfoLoadingState()
+       :
+       fSpecificInfoLoadingState(),
+       fSpecificInfoIndex(0)
+{
+}
+
+
+ImageDebugInfoLoadingState::~ImageDebugInfoLoadingState()
+{
+}
+
+
+bool
+ImageDebugInfoLoadingState::HasSpecificDebugInfoLoadingState() const
+{
+       return fSpecificInfoLoadingState.Get() != NULL;
+}
+
+
+void
+ImageDebugInfoLoadingState::SetSpecificDebugInfoLoadingState(
+       SpecificImageDebugInfoLoadingState* state)
+{
+       fSpecificInfoLoadingState.SetTo(state, true);
+}
+
+
+void
+ImageDebugInfoLoadingState::ClearSpecificDebugInfoLoadingState()
+{
+       fSpecificInfoLoadingState = NULL;
+}
+
+
+bool
+ImageDebugInfoLoadingState::UserInputRequired() const
+{
+       if (HasSpecificDebugInfoLoadingState())
+               return fSpecificInfoLoadingState->UserInputRequired();
+
+       return false;
+}
+
+
+void
+ImageDebugInfoLoadingState::SetSpecificInfoIndex(int32 index)
+{
+       fSpecificInfoIndex = index;
+}
diff --git a/src/apps/debugger/debug_info/ImageDebugInfoLoadingState.h 
b/src/apps/debugger/debug_info/ImageDebugInfoLoadingState.h
new file mode 100644
index 0000000..8089759
--- /dev/null
+++ b/src/apps/debugger/debug_info/ImageDebugInfoLoadingState.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef IMAGE_DEBUG_INFO_LOADING_STATE_H
+#define IMAGE_DEBUG_INFO_LOADING_STATE_H
+
+#include <Referenceable.h>
+
+
+class SpecificImageDebugInfoLoadingState;
+
+
+class ImageDebugInfoLoadingState {
+public:
+                                                               
ImageDebugInfoLoadingState();
+       virtual                                         
~ImageDebugInfoLoadingState();
+
+                       bool                            
HasSpecificDebugInfoLoadingState() const;
+                       SpecificImageDebugInfoLoadingState*
+                                                               
GetSpecificDebugInfoLoadingState() const
+                                                                       { 
return fSpecificInfoLoadingState; }
+                       void                            
SetSpecificDebugInfoLoadingState(
+                                                                       
SpecificImageDebugInfoLoadingState* state);
+                                                                       // 
note: takes over reference of passed
+                                                                       // in 
state object.
+                       void                            
ClearSpecificDebugInfoLoadingState();
+
+                       bool                            UserInputRequired() 
const;
+
+
+                       int32                           GetSpecificInfoIndex() 
const
+                                                                       { 
return fSpecificInfoIndex; }
+                       void                            
SetSpecificInfoIndex(int32 index);
+
+private:
+                       BReference<SpecificImageDebugInfoLoadingState>
+                                                               
fSpecificInfoLoadingState;
+                       int32                           fSpecificInfoIndex;
+};
+
+
+#endif // IMAGE_DEBUG_INFO_LOADING_STATE_H
diff --git 
a/src/apps/debugger/debug_info/SpecificImageDebugInfoLoadingState.cpp 
b/src/apps/debugger/debug_info/SpecificImageDebugInfoLoadingState.cpp
new file mode 100644
index 0000000..23fabb8
--- /dev/null
+++ b/src/apps/debugger/debug_info/SpecificImageDebugInfoLoadingState.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "SpecificImageDebugInfoLoadingState.h"
+
+
+SpecificImageDebugInfoLoadingState::SpecificImageDebugInfoLoadingState()
+       :
+       BReferenceable()
+{
+}
+
+
+SpecificImageDebugInfoLoadingState::~SpecificImageDebugInfoLoadingState()
+{
+}
diff --git a/src/apps/debugger/debug_info/SpecificImageDebugInfoLoadingState.h 
b/src/apps/debugger/debug_info/SpecificImageDebugInfoLoadingState.h
new file mode 100644
index 0000000..ce4393b
--- /dev/null
+++ b/src/apps/debugger/debug_info/SpecificImageDebugInfoLoadingState.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef SPECIFIC_IMAGE_DEBUG_INFO_LOADING_STATE_H
+#define SPECIFIC_IMAGE_DEBUG_INFO_LOADING_STATE_H
+
+
+#include <Referenceable.h>
+
+
+class SpecificImageDebugInfoLoadingState : public BReferenceable {
+public:
+                                                               
SpecificImageDebugInfoLoadingState();
+       virtual                                         
~SpecificImageDebugInfoLoadingState();
+
+       virtual bool                            UserInputRequired() const = 0;
+};
+
+
+#endif // SPECIFIC_IMAGE_DEBUG_INFO_LOADING_STATE_H
diff --git a/src/apps/debugger/dwarf/DwarfFileLoadingState.cpp 
b/src/apps/debugger/dwarf/DwarfFileLoadingState.cpp
new file mode 100644
index 0000000..bcf33da
--- /dev/null
+++ b/src/apps/debugger/dwarf/DwarfFileLoadingState.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "DwarfFileLoadingState.h"
+
+#include "DwarfFile.h"
+
+
+DwarfFileLoadingState::DwarfFileLoadingState()
+       :
+       dwarfFile(),
+       externalInfoFileName(),
+       locatedExternalInfoPath(),
+       state(DWARF_FILE_LOADING_STATE_INITIAL)
+{
+}
+
+
+DwarfFileLoadingState::~DwarfFileLoadingState()
+{
+}
+
+
diff --git a/src/apps/debugger/dwarf/DwarfFileLoadingState.h 
b/src/apps/debugger/dwarf/DwarfFileLoadingState.h
new file mode 100644
index 0000000..7f1467d
--- /dev/null
+++ b/src/apps/debugger/dwarf/DwarfFileLoadingState.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef DWARF_FILE_LOADING_STATE_H
+#define DWARF_FILE_LOADING_STATE_H
+
+
+#include <Referenceable.h>
+#include <String.h>
+
+
+class DwarfFile;
+
+
+enum dwarf_file_loading_state {
+       DWARF_FILE_LOADING_STATE_INITIAL = 0,
+       DWARF_FILE_LOADING_STATE_USER_INPUT_NEEDED,
+       DWARF_FILE_LOADING_STATE_USER_INPUT_PROVIDED,
+       DWARF_FILE_LOADING_STATE_FAILED,
+       DWARF_FILE_LOADING_STATE_SUCCEEDED
+};
+
+
+struct DwarfFileLoadingState {
+                       BReference<DwarfFile>
+                                                               dwarfFile;
+                       BString                         externalInfoFileName;
+                       BString                         locatedExternalInfoPath;
+                       dwarf_file_loading_state
+                                                               state;
+
+                                                               
DwarfFileLoadingState();
+                                                               
~DwarfFileLoadingState();
+};
+
+
+#endif // DWARF_FILE_LOADING_STATE_H
diff --git a/src/apps/debugger/dwarf/Jamfile b/src/apps/debugger/dwarf/Jamfile
index 4cf6b78..f806498 100644
--- a/src/apps/debugger/dwarf/Jamfile
+++ b/src/apps/debugger/dwarf/Jamfile
@@ -22,6 +22,7 @@ MergeObject Debugger_dwarf.o
        DebugInfoEntry.cpp
        DwarfExpressionEvaluator.cpp
        DwarfFile.cpp
+       DwarfFileLoadingState.cpp
        DwarfManager.cpp
        DwarfTargetInterface.cpp
        DwarfUtils.cpp

############################################################################

Commit:      7cab8329564c7bccca42693808e9445ccfe6e108
URL:         http://cgit.haiku-os.org/haiku/commit/?id=7cab832
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Sun Dec  8 22:20:11 2013 UTC

Debugger: Add support for suspending LoadImageDebugInfoJob.

DwarfFile:
- Loading is now split into two steps, the first of which simply attempts to
verify the presence of debug information. If the latter is referenced
externally, but cannot be found on disk, the corresponding file reference is
returned.

TeamDebugInfo:
- Add state parameter to LoadImageDebugInfo(). Use it to preserve where we
are in the specific info loading loop if necessary.

SpecificTeamDebugInfo:
- Add parameter to CreateImageDebugInfo() to allow passing in a state object
and adjust implementing subclasses accordingly.

DwarfTeamDebugInfo:
- Preserve and/or pass down DwarfFile's loading state as needed.

DwarfManager:
- When attempting to load a DwarfFile, detect the case where external debug
  information is referenced, but could not be located. If so, preserve the
  relevant details in the loading state, so the user can be notified and
  asked to find it accordingly.

LoadImageDebugInfoJob:
- Keep a state object for the progress of the current loading job. If a
  particular image fails due to needing user input, suspend ourselves
  until such input has been provided.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.cpp 
b/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.cpp
index 3c46e5f..66195db 100644
--- a/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.cpp
@@ -33,7 +33,8 @@ DebuggerTeamDebugInfo::Init()
 
 status_t
 DebuggerTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo,
-       LocatableFile* imageFile, SpecificImageDebugInfo*& _imageDebugInfo)
+       LocatableFile* imageFile, ImageDebugInfoLoadingState& _state,
+       SpecificImageDebugInfo*& _imageDebugInfo)
 {
        DebuggerImageDebugInfo* debuggerInfo
                = new(std::nothrow) DebuggerImageDebugInfo(imageInfo,
diff --git a/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.h 
b/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.h
index d3895c0..3736754 100644
--- a/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.h
+++ b/src/apps/debugger/debug_info/DebuggerTeamDebugInfo.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef DEBUGGER_TEAM_DEBUG_INFO_H
@@ -24,6 +25,7 @@ public:
 
        virtual status_t                        CreateImageDebugInfo(const 
ImageInfo& imageInfo,
                                                                        
LocatableFile* imageFile,
+                                                                       
ImageDebugInfoLoadingState& _state,
                                                                        
SpecificImageDebugInfo*& _imageDebugInfo);
 
 private:
diff --git a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp 
b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp
index 331f0a3..da04aca 100644
--- a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -12,8 +13,10 @@
 #include "DebuggerInterface.h"
 #include "DwarfFile.h"
 #include "DwarfImageDebugInfo.h"
+#include "DwarfImageDebugInfoLoadingState.h"
 #include "DwarfManager.h"
 #include "GlobalTypeLookup.h"
+#include "ImageDebugInfoLoadingState.h"
 #include "LocatableFile.h"
 
 
@@ -58,7 +61,8 @@ DwarfTeamDebugInfo::Init()
 
 status_t
 DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& imageInfo,
-       LocatableFile* imageFile, SpecificImageDebugInfo*& _imageDebugInfo)
+       LocatableFile* imageFile, ImageDebugInfoLoadingState& _state,
+       SpecificImageDebugInfo*& _imageDebugInfo)
 {
        // We only like images whose file we can play with.
        BString filePath;
@@ -66,11 +70,22 @@ DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& 
imageInfo,
                return B_ENTRY_NOT_FOUND;
 
        // try to load the DWARF file
-       DwarfFile* file;
-       status_t error = fManager->LoadFile(filePath, file);
+       DwarfImageDebugInfoLoadingState* dwarfState;
+       if (_state.HasSpecificDebugInfoLoadingState()) {
+               dwarfState = dynamic_cast<DwarfImageDebugInfoLoadingState*>(
+                       _state.GetSpecificDebugInfoLoadingState());
+               if (dwarfState == NULL)
+                       return B_BAD_VALUE;
+       } else {
+               dwarfState = new(std::nothrow) 
DwarfImageDebugInfoLoadingState();
+               if (dwarfState == NULL)
+                       return B_NO_MEMORY;
+               _state.SetSpecificDebugInfoLoadingState(dwarfState);
+       }
+
+       status_t error = fManager->LoadFile(filePath, 
dwarfState->GetFileState());
        if (error != B_OK)
                return error;
-       BReference<DwarfFile> fileReference(file, true);
 
        error = fManager->FinishLoading();
        if (error != B_OK)
@@ -79,7 +94,7 @@ DwarfTeamDebugInfo::CreateImageDebugInfo(const ImageInfo& 
imageInfo,
        // create the image debug info
        DwarfImageDebugInfo* debugInfo = new(std::nothrow) DwarfImageDebugInfo(
                imageInfo, fDebuggerInterface, fArchitecture, fFileManager,
-               fTypeLookup, fTypeCache, file);
+               fTypeLookup, fTypeCache, dwarfState->GetFileState().dwarfFile);
        if (debugInfo == NULL)
                return B_NO_MEMORY;
 
diff --git a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h 
b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h
index 90c2434..fa2891b 100644
--- a/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h
+++ b/src/apps/debugger/debug_info/DwarfTeamDebugInfo.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef DWARF_TEAM_DEBUG_INFO_H
@@ -31,6 +32,7 @@ public:
 
        virtual status_t                        CreateImageDebugInfo(const 
ImageInfo& imageInfo,
                                                                        
LocatableFile* imageFile,
+                                                                       
ImageDebugInfoLoadingState& _state,
                                                                        
SpecificImageDebugInfo*& _imageDebugInfo);
 
 private:
diff --git a/src/apps/debugger/debug_info/SpecificTeamDebugInfo.h 
b/src/apps/debugger/debug_info/SpecificTeamDebugInfo.h
index 1d3a47d..f9ac7c6 100644
--- a/src/apps/debugger/debug_info/SpecificTeamDebugInfo.h
+++ b/src/apps/debugger/debug_info/SpecificTeamDebugInfo.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef SPECIFIC_TEAM_DEBUG_INFO_H
@@ -8,17 +9,18 @@
 #include <SupportDefs.h>
 
 
+class ImageDebugInfoLoadingState;
 class ImageInfo;
 class LocatableFile;
 class SpecificImageDebugInfo;
 
-
 class SpecificTeamDebugInfo {
 public:
        virtual                                         
~SpecificTeamDebugInfo();
 
        virtual status_t                        CreateImageDebugInfo(const 
ImageInfo& imageInfo,
                                                                        
LocatableFile* imageFile,
+                                                                       
ImageDebugInfoLoadingState& _state,
                                                                        
SpecificImageDebugInfo*& _imageDebugInfo)
                                                                                
= 0;
 };
diff --git a/src/apps/debugger/debug_info/TeamDebugInfo.cpp 
b/src/apps/debugger/debug_info/TeamDebugInfo.cpp
index 700caa4..00b174e 100644
--- a/src/apps/debugger/debug_info/TeamDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/TeamDebugInfo.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2012-2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2012-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -24,6 +24,7 @@
 #include "Function.h"
 #include "FunctionID.h"
 #include "ImageDebugInfo.h"
+#include "ImageDebugInfoLoadingState.h"
 #include "LocatableFile.h"
 #include "SourceFile.h"
 #include "SourceLanguage.h"
@@ -426,7 +427,8 @@ TeamDebugInfo::GetType(GlobalTypeCache* cache, const 
BString& name,
 
 status_t
 TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& imageInfo,
-       LocatableFile* imageFile, ImageDebugInfo*& _imageDebugInfo)
+       LocatableFile* imageFile, ImageDebugInfoLoadingState& _state,
+       ImageDebugInfo*& _imageDebugInfo)
 {
        ImageDebugInfo* imageDebugInfo = new(std::nothrow) ImageDebugInfo(
                imageInfo);
@@ -438,15 +440,23 @@ TeamDebugInfo::LoadImageDebugInfo(const ImageInfo& 
imageInfo,
                        = fSpecificInfos.ItemAt(i); i++) {
                SpecificImageDebugInfo* specificImageInfo;
                status_t error = 
specificTeamInfo->CreateImageDebugInfo(imageInfo,
-                       imageFile, specificImageInfo);
+                       imageFile, _state, specificImageInfo);
                if (error == B_OK) {
                        if 
(!imageDebugInfo->AddSpecificInfo(specificImageInfo)) {
                                delete specificImageInfo;
                                return B_NO_MEMORY;
                        }
+               } else if (_state.UserInputRequired()) {
+                       _state.SetSpecificInfoIndex(i);
+                       return error;
                } else if (error == B_NO_MEMORY)
                        return error;
                                // fail only when out of memory
+
+               _state.ClearSpecificDebugInfoLoadingState();
+                       // if we made it this far, then we're done with current 
specific
+                       // info, and its corresponding state object, if any, is 
no longer
+                       // needed
        }
 
        status_t error = imageDebugInfo->FinishInit(fDebuggerInterface);
diff --git a/src/apps/debugger/debug_info/TeamDebugInfo.h 
b/src/apps/debugger/debug_info/TeamDebugInfo.h
index 06b7fe0..884a1a3 100644
--- a/src/apps/debugger/debug_info/TeamDebugInfo.h
+++ b/src/apps/debugger/debug_info/TeamDebugInfo.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef TEAM_DEBUG_INFO_H
@@ -26,6 +27,7 @@ class Function;
 class FunctionID;
 class FunctionInstance;
 class ImageDebugInfo;
+class ImageDebugInfoLoadingState;
 class ImageInfo;
 class LocatableFile;
 class SourceCode;
@@ -54,6 +56,7 @@ public:
 
                        status_t                        
LoadImageDebugInfo(const ImageInfo& imageInfo,
                                                                        
LocatableFile* imageFile,
+                                                                       
ImageDebugInfoLoadingState& state,
                                                                        
ImageDebugInfo*& _imageDebugInfo);
 
                        status_t                        
LoadSourceCode(LocatableFile* file,
diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp 
b/src/apps/debugger/dwarf/DwarfFile.cpp
index ad2fd47..fa38af5 100644
--- a/src/apps/debugger/dwarf/DwarfFile.cpp
+++ b/src/apps/debugger/dwarf/DwarfFile.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2012-2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2012-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -504,7 +504,7 @@ DwarfFile::~DwarfFile()
 
 
 status_t
-DwarfFile::Load(const char* fileName)
+DwarfFile::StartLoading(const char* fileName, BString& _requiredExternalFile)
 {
        fName = strdup(fileName);
        if (fName == NULL)
@@ -523,9 +523,21 @@ DwarfFile::Load(const char* fileName)
        if (error != B_OK)
                return error;
 
-       error = _LocateDebugInfo();
-       if (error != B_OK)
-               return error;
+       return _LocateDebugInfo(_requiredExternalFile);
+}
+
+
+status_t
+DwarfFile::Load(const BString& externalInfoFilePath)
+{
+       status_t error = B_OK;
+       if (fDebugInfoSection == NULL) {
+               BString path;
+               error = _LocateDebugInfo(path, externalInfoFilePath.IsEmpty()
+                               ? NULL : externalInfoFilePath.String());
+               if (error != B_OK)
+                       return error;
+       }
 
        ElfFile* debugInfoFile = fAlternateElfFile != NULL
                ? fAlternateElfFile : fElfFile;
@@ -2686,7 +2698,8 @@ DwarfFile::_FindLocationExpression(CompilationUnit* unit, 
uint64 offset,
 
 
 status_t
-DwarfFile::_LocateDebugInfo()
+DwarfFile::_LocateDebugInfo(BString& _requiredExternalFileName,
+       const char* locatedFilePath)
 {
        ElfFile* debugInfoFile = fElfFile;
        ElfSection* debugLinkSection = fElfFile->GetSection(".gnu_debuglink");
@@ -2700,10 +2713,19 @@ DwarfFile::_LocateDebugInfo()
                // by a 32-bit CRC
 
                BString debugPath;
-               status_t result = _GetDebugInfoPath(
-                       (const char*)debugLinkSection->Data(), debugPath);
-               if (result != B_OK)
-                       return result;
+               if (locatedFilePath)
+                       debugPath = locatedFilePath;
+               else {
+                       status_t result = _GetDebugInfoPath(
+                               (const char*)debugLinkSection->Data(),
+                               _requiredExternalFileName);
+                       if (result != B_OK)
+                               return result;
+                       debugPath = _requiredExternalFileName;
+               }
+
+               if (fAlternateName != NULL)
+                       free(fAlternateName);
 
                fAlternateName = strdup(debugPath.String());
 
@@ -2715,11 +2737,13 @@ DwarfFile::_LocateDebugInfo()
                int32 debugCRC = *(int32*)((char*)debugLinkSection->Data()
                        + debugLinkSection->Size() - sizeof(int32));
 */
-               fAlternateElfFile = new(std::nothrow) ElfFile;
-               if (fAlternateElfFile == NULL)
-                       return B_NO_MEMORY;
+               if (fAlternateElfFile == NULL) {
+                       fAlternateElfFile = new(std::nothrow) ElfFile;
+                       if (fAlternateElfFile == NULL)
+                               return B_NO_MEMORY;
+               }
 
-               result = fAlternateElfFile->Init(fAlternateName);
+               status_t result = fAlternateElfFile->Init(fAlternateName);
                if (result != B_OK)
                        return result;
 
@@ -2780,6 +2804,11 @@ DwarfFile::_GetDebugInfoPath(const char* debugFileName,
        if (result == B_OK) {
                _infoPath = basePath.Path();
                return B_OK;
+       } else {
+               // if we failed to find a match, then it's up to the user to
+               // locate it. As such, return the external info file name
+               // for user interface purposes.
+               _infoPath.SetTo(debugFileName);
        }
 
        return B_ENTRY_NOT_FOUND;
diff --git a/src/apps/debugger/dwarf/DwarfFile.h 
b/src/apps/debugger/dwarf/DwarfFile.h
index 17dee90..b778383 100644
--- a/src/apps/debugger/dwarf/DwarfFile.h
+++ b/src/apps/debugger/dwarf/DwarfFile.h
@@ -35,7 +35,9 @@ public:
                                                                DwarfFile();
                                                                ~DwarfFile();
 
-                       status_t                        Load(const char* 
fileName);
+                       status_t                        StartLoading(const 
char* fileName,
+                                                                       
BString& _requiredExternalFile);
+                       status_t                        Load(const BString& 
externalFilePath);
                        status_t                        FinishLoading();
 
                        const char*                     Name() const            
{ return fName; }
@@ -172,7 +174,10 @@ private:
                                                                        const 
void*& _expression,
                                                                        off_t& 
_length) const;
 
-                       status_t                        _LocateDebugInfo();
+                       status_t                        _LocateDebugInfo(
+                                                                       
BString& _requiredExternalFileName,
+                                                                       const 
char* locatedFilePath = NULL);
+
                        status_t                        _GetDebugInfoPath(const 
char* fileName,
                                                                        
BString& _infoPath) const;
 
diff --git a/src/apps/debugger/dwarf/DwarfManager.cpp 
b/src/apps/debugger/dwarf/DwarfManager.cpp
index b6fb6bf..4f033da 100644
--- a/src/apps/debugger/dwarf/DwarfManager.cpp
+++ b/src/apps/debugger/dwarf/DwarfManager.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -11,6 +12,7 @@
 #include <AutoLocker.h>
 
 #include "DwarfFile.h"
+#include "DwarfFileLoadingState.h"
 
 
 DwarfManager::DwarfManager()
@@ -33,26 +35,49 @@ DwarfManager::Init()
 
 
 status_t
-DwarfManager::LoadFile(const char* fileName, DwarfFile*& _file)
+DwarfManager::LoadFile(const char* fileName, DwarfFileLoadingState& _state)
 {
        AutoLocker<DwarfManager> locker(this);
 
-       DwarfFile* file = new(std::nothrow) DwarfFile;
-       if (file == NULL)
-               return B_NO_MEMORY;
+       DwarfFile* file = _state.dwarfFile;
+       BReference<DwarfFile> fileReference;
+       if (file == NULL) {
+               file = new(std::nothrow) DwarfFile;
+               if (file == NULL)
+                       return B_NO_MEMORY;
+               fileReference.SetTo(file, true);
+               _state.dwarfFile = file;
+       } else
+               fileReference.SetTo(file);
+
+       status_t error;
+       if (_state.externalInfoFileName.IsEmpty()) {
+               error = file->StartLoading(fileName, 
_state.externalInfoFileName);
+               if (error != B_OK) {
+                       // only preserve state in the failure case if an 
external
+                       // debug information reference was found, but the 
corresponding
+                       // file could not be located on disk.
+                       _state.state = _state.externalInfoFileName.IsEmpty()
+                               ? DWARF_FILE_LOADING_STATE_FAILED
+                               : DWARF_FILE_LOADING_STATE_USER_INPUT_NEEDED;
 
-       BReference<DwarfFile> fileReference(file, true);
-       status_t error = file->Load(fileName);
+                       return error;
+               }
+       }
+
+       error = file->Load(_state.locatedExternalInfoPath);
        if (error != B_OK) {
+               _state.state = DWARF_FILE_LOADING_STATE_FAILED;
                return error;
        }
 
        fFiles.Add(file);
+
        fileReference.Detach();
-               // we keep the initial reference for ourselves
+               // keep a reference for ourselves in the list.
+
+       _state.state = DWARF_FILE_LOADING_STATE_SUCCEEDED;
 
-       file->AcquireReference();
-       _file = file;
        return B_OK;
 }
 
diff --git a/src/apps/debugger/dwarf/DwarfManager.h 
b/src/apps/debugger/dwarf/DwarfManager.h
index 8da0755..375402f 100644
--- a/src/apps/debugger/dwarf/DwarfManager.h
+++ b/src/apps/debugger/dwarf/DwarfManager.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef DWARF_MANAGER_H
@@ -11,6 +12,7 @@
 
 
 class DwarfFile;
+struct DwarfFileLoadingState;
 
 
 class DwarfManager {
@@ -24,8 +26,10 @@ public:
                        void                            Unlock()        { 
fLock.Unlock(); }
 
                        status_t                        LoadFile(const char* 
fileName,
-                                                                       
DwarfFile*& _file);
-                                                                       // 
returns a reference
+                                                                       
DwarfFileLoadingState& _loadingState);
+                                                                       // 
_loadingState receives a reference
+                                                                       // to 
the corresponding DwarfFile.
+
                        status_t                        FinishLoading();
 
 private:
diff --git a/src/apps/debugger/jobs/Jobs.h b/src/apps/debugger/jobs/Jobs.h
index 1cf7a06..f024bc3 100644
--- a/src/apps/debugger/jobs/Jobs.h
+++ b/src/apps/debugger/jobs/Jobs.h
@@ -1,12 +1,13 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef JOBS_H
 #define JOBS_H
 
 
+#include "ImageDebugInfoLoadingState.h"
 #include "ImageDebugInfoProvider.h"
 #include "Types.h"
 #include "Worker.h"
@@ -128,6 +129,8 @@ public:
 private:
                        SimpleJobKey            fKey;
                        Image*                          fImage;
+                       ImageDebugInfoLoadingState
+                                                               fState;
 };
 
 
diff --git a/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp 
b/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
index dc1706c..418873f 100644
--- a/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
+++ b/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
@@ -17,7 +17,8 @@
 LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image)
        :
        fKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO),
-       fImage(image)
+       fImage(image),
+       fState()
 {
        fImage->AcquireReference();
 }
@@ -47,10 +48,16 @@ LoadImageDebugInfoJob::Do()
        // create the debug info
        ImageDebugInfo* debugInfo;
        status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo(
-               imageInfo, fImage->ImageFile(), debugInfo);
+               imageInfo, fImage->ImageFile(), fState, debugInfo);
 
        // set the result
        locker.Lock();
+
+       if (fState.UserInputRequired()) {
+               // TODO: notify the user interface
+               return WaitForUserInput();
+       }
+
        if (error == B_OK) {
                error = fImage->SetImageDebugInfo(debugInfo, 
IMAGE_DEBUG_INFO_LOADED);
                debugInfo->ReleaseReference();

############################################################################

Commit:      d9e97187f53201ae200731a0503448c04acec988
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d9e9718
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Tue Jun 10 23:10:53 2014 UTC

Debugger: Add file prompt hook to UserInterface.

In some circumstances, it may be necessary to ask the user to locate a file
from the lower layers. Adds the corresponding hook to UserInterface, and a
stub implementation for CommandLineUserInterface.

Adds full implementation for GraphicalUserInterface.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h
index e0efd00..ab6d8c5 100644
--- a/src/apps/debugger/MessageCodes.h
+++ b/src/apps/debugger/MessageCodes.h
@@ -72,7 +72,10 @@ enum {
        MSG_SHOW_WATCH_VARIABLE_PROMPT                          = 'swvp',
        MSG_SHOW_CONTAINER_RANGE_PROMPT                         = 'scrp',
        MSG_SET_CONTAINER_RANGE                                         = 
'chcr',
-       MSG_GENERATE_DEBUG_REPORT                                       = 'gdrp'
+       MSG_GENERATE_DEBUG_REPORT                                       = 
'gdrp',
+
+       MSG_DEBUG_INFO_NEEDS_USER_INPUT                         = 'dnui',
+       MSG_USER_INTERFACE_FILE_CHOSEN                          = 'uifc'
 };
 
 
diff --git a/src/apps/debugger/user_interface/UserInterface.h 
b/src/apps/debugger/user_interface/UserInterface.h
index cb00459..67fa804 100644
--- a/src/apps/debugger/user_interface/UserInterface.h
+++ b/src/apps/debugger/user_interface/UserInterface.h
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2013-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef USER_INTERFACE_H
@@ -67,6 +67,9 @@ public:
                                                                        = 0;
                                                                        // 
returns -1, if not implemented or user
                                                                        // 
cannot be asked
+
+       virtual status_t                        
SynchronouslyAskUserForFile(entry_ref* _ref)
+                                                                       = 0;
 };
 
 
diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp 
b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
index ab2c837..33a467f 100644
--- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
+++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
@@ -201,6 +201,13 @@ CommandLineUserInterface::SynchronouslyAskUser(const char* 
title,
 }
 
 
+status_t
+CommandLineUserInterface::SynchronouslyAskUserForFile(entry_ref* _ref)
+{
+       return B_UNSUPPORTED;
+}
+
+
 void
 CommandLineUserInterface::Run()
 {
diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h 
b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h
index 12d479c..b89e634 100644
--- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h
+++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2011-2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
@@ -43,6 +43,7 @@ public:
        virtual int32                           SynchronouslyAskUser(const 
char* title,
                                                                        const 
char* message, const char* choice1,
                                                                        const 
char* choice2, const char* choice3);
+       virtual status_t                        
SynchronouslyAskUserForFile(entry_ref* _ref);
 
                        void                            Run();
                                                                        // 
Called by the main thread, when
diff --git a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp 
b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp
index 136c721..9fd2c6c 100644
--- a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp
+++ b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -8,16 +8,127 @@
 #include "GraphicalUserInterface.h"
 
 #include <Alert.h>
+#include <Autolock.h>
+#include <FilePanel.h>
+#include <Locker.h>
 
 #include "GuiTeamUiSettings.h"
+#include "MessageCodes.h"
 #include "TeamWindow.h"
 #include "Tracing.h"
 
 
+// #pragma mark - GraphicalUserInterface::FilePanelHandler
+
+
+class GraphicalUserInterface::FilePanelHandler : public BHandler {
+public:
+                                                               
FilePanelHandler();
+       virtual                                         ~FilePanelHandler();
+
+                       status_t                        Init();
+
+       virtual void                            MessageReceived(BMessage* 
message);
+
+                       status_t                        WaitForPanel();
+
+                       void                            
SetCurrentRef(entry_ref* ref);
+
+                       BLocker&                        Locker()
+                                                                       { 
return fPanelLock; }
+
+private:
+                       entry_ref*                      fCurrentRef;
+                       BLocker                         fPanelLock;
+                       sem_id                          fPanelWaitSem;
+};
+
+
+GraphicalUserInterface::FilePanelHandler::FilePanelHandler()
+       :
+       BHandler("GuiPanelHandler"),
+       fCurrentRef(NULL),
+       fPanelLock(),
+       fPanelWaitSem(-1)
+{
+}
+
+
+GraphicalUserInterface::FilePanelHandler::~FilePanelHandler()
+{
+       if (fPanelWaitSem >= 0)
+               delete_sem(fPanelWaitSem);
+}
+
+
+status_t
+GraphicalUserInterface::FilePanelHandler::Init()
+{
+       fPanelWaitSem = create_sem(0, "FilePanelWaitSem");
+
+       if (fPanelWaitSem < 0)
+               return fPanelWaitSem;
+
+       return B_OK;
+}
+
+
+void
+GraphicalUserInterface::FilePanelHandler::MessageReceived(BMessage* message)
+{
+       switch (message->what) {
+               case MSG_USER_INTERFACE_FILE_CHOSEN:
+               {
+                       entry_ref ref;
+                       if (message->FindRef("refs", &ref) == B_OK
+                               && fCurrentRef != NULL) {
+                               *fCurrentRef = ref;
+                               fCurrentRef = NULL;
+                       }
+                       // fall through
+               }
+
+               case B_CANCEL:
+               {
+                       release_sem(fPanelWaitSem);
+                       break;
+               }
+
+               default:
+                       BHandler::MessageReceived(message);
+                       break;
+       }
+}
+
+
+status_t
+GraphicalUserInterface::FilePanelHandler::WaitForPanel()
+{
+       status_t result = B_OK;
+       do {
+               result = acquire_sem(fPanelWaitSem);
+       } while (result == B_INTERRUPTED);
+
+       return result;
+}
+
+
+void
+GraphicalUserInterface::FilePanelHandler::SetCurrentRef(entry_ref* ref)
+{
+       fCurrentRef = ref;
+}
+
+
+// #pragma mark - GraphicalUserInterface
+
+
 GraphicalUserInterface::GraphicalUserInterface()
        :
        fTeamWindow(NULL),
-       fTeamWindowMessenger(NULL)
+       fTeamWindowMessenger(NULL),
+       fFilePanelHandler(NULL),
+       fFilePanel(NULL)
 {
 }
 
@@ -25,6 +136,7 @@ GraphicalUserInterface::GraphicalUserInterface()
 GraphicalUserInterface::~GraphicalUserInterface()
 {
        delete fTeamWindowMessenger;
+       delete fFilePanel;
 }
 
 
@@ -41,6 +153,13 @@ GraphicalUserInterface::Init(Team* team, 
UserInterfaceListener* listener)
        try {
                fTeamWindow = TeamWindow::Create(team, listener);
                fTeamWindowMessenger = new BMessenger(fTeamWindow);
+               fFilePanelHandler = new FilePanelHandler();
+               status_t error = fFilePanelHandler->Init();
+               if (error != B_OK) {
+                       ERROR("Error: Failed to create file panel 
semaphore!\n");
+                       return error;
+               }
+               fTeamWindow->AddHandler(fFilePanelHandler);
 
                // start the message loop
                fTeamWindow->Hide();
@@ -132,3 +251,28 @@ GraphicalUserInterface::SynchronouslyAskUser(const char* 
title,
                return 0;
        return alert->Go();
 }
+
+
+status_t
+GraphicalUserInterface::SynchronouslyAskUserForFile(entry_ref* _ref)
+{
+       BAutolock lock(&fFilePanelHandler->Locker());
+
+       if (fFilePanel == NULL) {
+               BMessenger messenger(fFilePanelHandler);
+               BMessage* message = new(std::nothrow) BMessage(
+                       MSG_USER_INTERFACE_FILE_CHOSEN);
+               if (message == NULL)
+                       return B_NO_MEMORY;
+               ObjectDeleter<BMessage> messageDeleter(message);
+               fFilePanel = new(std::nothrow) BFilePanel(B_OPEN_PANEL,
+                       &messenger, NULL, B_FILE_NODE, false, message);
+               if (fFilePanel == NULL)
+                       return B_NO_MEMORY;
+               messageDeleter.Detach();
+       }
+
+       fFilePanelHandler->SetCurrentRef(_ref);
+       fFilePanel->Show();
+       return fFilePanelHandler->WaitForPanel();
+}
diff --git a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h 
b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h
index 60b7d5b..ef79cfd 100644
--- a/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h
+++ b/src/apps/debugger/user_interface/gui/GraphicalUserInterface.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef GRAPHICAL_USER_INTERFACE_H
@@ -9,6 +10,8 @@
 #include "UserInterface.h"
 
 
+class BFilePanel;
+class BHandler;
 class BMessenger;
 class TeamWindow;
 
@@ -36,10 +39,15 @@ public:
        virtual int32                           SynchronouslyAskUser(const 
char* title,
                                                                        const 
char* message, const char* choice1,
                                                                        const 
char* choice2, const char* choice3);
+       virtual status_t                        
SynchronouslyAskUserForFile(entry_ref* _ref);
+private:
+                       class FilePanelHandler;
 
 private:
                        TeamWindow*                     fTeamWindow;
                        BMessenger*                     fTeamWindowMessenger;
+                       FilePanelHandler*       fFilePanelHandler;
+                       BFilePanel*                     fFilePanel;
 };
 
 

############################################################################

Commit:      331511009c7f769f4c4dad00c7a31e2d926e7731
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3315110
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Tue Jun 10 23:12:45 2014 UTC

Debugger: Start adding the groundwork for load state handlers.

Adds abstract class ImageDebugLoadingStateHandler which simply contains two
hooks, which allow one to a) ask it if it supports a handling a particular
type of loading state, and b) if so, ask it to attempt to handle that case,
given the passed in user interface object.

Also adds implementing subclass for DwarfImageDebugInfo, currently
intended primarily to handle the case of missing external debug information.
At present, this just supports prompting the user to find/install the file,
but eventually this will be extended to also support automatically installing
the corresponding debug information package, if applicable.

Finally, adds ImageDebugLoadingStateHandlerRoster, which acts as a front end
for matching up a given loading state with the appropriate handler.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp
index 46e146d..dbf24e3 100644
--- a/src/apps/debugger/Debugger.cpp
+++ b/src/apps/debugger/Debugger.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2011-2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -24,6 +24,7 @@
 
 #include "CommandLineUserInterface.h"
 #include "GraphicalUserInterface.h"
+#include "ImageDebugLoadingStateHandlerRoster.h"
 #include "MessageCodes.h"
 #include "SettingsManager.h"
 #include "SignalSet.h"
@@ -212,6 +213,10 @@ global_init()
        if (error != B_OK)
                return error;
 
+       error = ImageDebugLoadingStateHandlerRoster::CreateDefault();
+       if (error != B_OK)
+               return error;
+
        return B_OK;
 }
 
@@ -402,6 +407,7 @@ Debugger::~Debugger()
 {
        ValueHandlerRoster::DeleteDefault();
        TypeHandlerRoster::DeleteDefault();
+       ImageDebugLoadingStateHandlerRoster::DeleteDefault();
 }
 
 
diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index 95550ff..e7f38af 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -14,6 +14,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86 ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86_64 ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) controllers ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info ] ;
+SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info loading_state_handlers ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_managers ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) elf ] ;
@@ -112,6 +113,8 @@ Application Debugger :
        ImageDebugInfo.cpp
        ImageDebugInfoLoadingState.cpp
        ImageDebugInfoProvider.cpp
+       ImageDebugLoadingStateHandler.cpp
+       ImageDebugLoadingStateHandlerRoster.cpp
        NoOpStackFrameDebugInfo.cpp
        SpecificImageDebugInfo.cpp
        SpecificImageDebugInfoLoadingState.cpp
@@ -119,6 +122,9 @@ Application Debugger :
        StackFrameDebugInfo.cpp
        TeamDebugInfo.cpp
 
+       # debug_info/loading_state_handlers
+       DwarfLoadingStateHandler.cpp
+
        # debugger_interface
        DebugEvent.cpp
        DebuggerInterface.cpp
diff --git a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.cpp 
b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.cpp
new file mode 100644
index 0000000..f57cd29
--- /dev/null
+++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.cpp
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "ImageDebugLoadingStateHandler.h"
+
+
+ImageDebugLoadingStateHandler::~ImageDebugLoadingStateHandler()
+{
+}
diff --git a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.h 
b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.h
new file mode 100644
index 0000000..24f54f4
--- /dev/null
+++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandler.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef IMAGE_DEBUG_LOADING_STATE_HANDLER_H
+#define IMAGE_DEBUG_LOADING_STATE_HANDLER_H
+
+
+#include <Referenceable.h>
+
+
+class SpecificImageDebugInfoLoadingState;
+class UserInterface;
+
+
+class ImageDebugLoadingStateHandler : public BReferenceable {
+public:
+       virtual                                         
~ImageDebugLoadingStateHandler();
+
+       virtual bool                            SupportsState(
+                                                                       
SpecificImageDebugInfoLoadingState* state)
+                                                                       = 0;
+
+       virtual void                            HandleState(
+                                                                       
SpecificImageDebugInfoLoadingState* state,
+                                                                       
UserInterface* interface) = 0;
+};
+
+
+#endif // IMAGE_DEBUG_LOADING_STATE_HANDLER_H
diff --git 
a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.cpp 
b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.cpp
new file mode 100644
index 0000000..8745d21
--- /dev/null
+++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "ImageDebugLoadingStateHandlerRoster.h"
+
+#include <new>
+
+#include <AutoDeleter.h>
+#include <AutoLocker.h>
+
+#include "DwarfLoadingStateHandler.h"
+#include "ImageDebugInfoLoadingState.h"
+#include "ImageDebugLoadingStateHandler.h"
+#include "SpecificImageDebugInfoLoadingState.h"
+
+
+/*static*/ ImageDebugLoadingStateHandlerRoster*
+       ImageDebugLoadingStateHandlerRoster::sDefaultInstance = NULL;
+
+
+ImageDebugLoadingStateHandlerRoster::ImageDebugLoadingStateHandlerRoster()
+       :
+       fLock("type handler roster")
+{
+}
+
+
+ImageDebugLoadingStateHandlerRoster::~ImageDebugLoadingStateHandlerRoster()
+{
+}
+
+
+/*static*/ ImageDebugLoadingStateHandlerRoster*
+ImageDebugLoadingStateHandlerRoster::Default()
+{
+       return sDefaultInstance;
+}
+
+
+/*static*/ status_t
+ImageDebugLoadingStateHandlerRoster::CreateDefault()
+{
+       if (sDefaultInstance != NULL)
+               return B_OK;
+
+       ImageDebugLoadingStateHandlerRoster* roster
+               = new(std::nothrow) ImageDebugLoadingStateHandlerRoster;
+       if (roster == NULL)
+               return B_NO_MEMORY;
+       ObjectDeleter<ImageDebugLoadingStateHandlerRoster> 
rosterDeleter(roster);
+
+       status_t error = roster->Init();
+       if (error != B_OK)
+               return error;
+
+       error = roster->RegisterDefaultHandlers();
+       if (error != B_OK)
+               return error;
+
+       sDefaultInstance = rosterDeleter.Detach();
+       return B_OK;
+}
+
+
+/*static*/ void
+ImageDebugLoadingStateHandlerRoster::DeleteDefault()
+{
+       ImageDebugLoadingStateHandlerRoster* roster = sDefaultInstance;
+       sDefaultInstance = NULL;
+       delete roster;
+}
+
+
+status_t
+ImageDebugLoadingStateHandlerRoster::Init()
+{
+       return fLock.InitCheck();
+}
+
+
+status_t
+ImageDebugLoadingStateHandlerRoster::RegisterDefaultHandlers()
+{
+       ImageDebugLoadingStateHandler* handler;
+       BReference<ImageDebugLoadingStateHandler> handlerReference;
+
+       handler = new(std::nothrow) DwarfLoadingStateHandler();
+       if (handler == NULL)
+               return B_NO_MEMORY;
+       handlerReference.SetTo(handler, true);
+
+       if (!RegisterHandler(handler))
+               return B_NO_MEMORY;
+
+       return B_OK;
+}
+
+
+status_t
+ImageDebugLoadingStateHandlerRoster::FindStateHandler(
+       SpecificImageDebugInfoLoadingState* state,
+       ImageDebugLoadingStateHandler*& _handler)
+{
+       AutoLocker<BLocker> locker(fLock);
+
+       bool found = false;
+       ImageDebugLoadingStateHandler* handler = NULL;
+       for (int32 i = 0; (handler = fStateHandlers.ItemAt(i)); i++) {
+               if ((found = handler->SupportsState(state)))
+                       break;
+       }
+
+       if (!found)
+               return B_ENTRY_NOT_FOUND;
+
+       handler->AcquireReference();
+       _handler = handler;
+       return B_OK;
+}
+
+
+bool
+ImageDebugLoadingStateHandlerRoster::RegisterHandler(
+       ImageDebugLoadingStateHandler* handler)
+{
+       if (!fStateHandlers.AddItem(handler))
+               return false;
+
+       handler->AcquireReference();
+       return true;
+}
+
+
+void
+ImageDebugLoadingStateHandlerRoster::UnregisterHandler(
+       ImageDebugLoadingStateHandler* handler)
+{
+       if (fStateHandlers.RemoveItem(handler))
+               handler->ReleaseReference();
+}
diff --git a/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.h 
b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.h
new file mode 100644
index 0000000..6731ae2
--- /dev/null
+++ b/src/apps/debugger/debug_info/ImageDebugLoadingStateHandlerRoster.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef IMAGE_DEBUG_LOADING_STATE_HANDLER_ROSTER_H
+#define IMAGE_DEBUG_LOADING_STATE_HANDLER_ROSTER_H
+
+
+#include <Locker.h>
+#include <ObjectList.h>
+
+
+class ImageDebugLoadingStateHandler;
+class SpecificImageDebugInfoLoadingState;
+
+
+typedef BObjectList<ImageDebugLoadingStateHandler> LoadingStateHandlerList;
+
+
+class ImageDebugLoadingStateHandlerRoster {
+public:
+                                                               
ImageDebugLoadingStateHandlerRoster();
+                                                               
~ImageDebugLoadingStateHandlerRoster();
+
+       static  ImageDebugLoadingStateHandlerRoster*
+                                                               Default();
+       static  status_t                        CreateDefault();
+       static  void                            DeleteDefault();
+
+                       status_t                        Init();
+                       status_t                        
RegisterDefaultHandlers();
+
+                       status_t                        FindStateHandler(
+                                                                       
SpecificImageDebugInfoLoadingState* state,
+                                                                       
ImageDebugLoadingStateHandler*&
+                                                                               
_handler);
+                                                                       // 
returns a reference
+
+                       bool                            RegisterHandler(
+                                                                       
ImageDebugLoadingStateHandler*
+                                                                               
handler);
+                       void                            UnregisterHandler(
+                                                                       
ImageDebugLoadingStateHandler*
+                                                                               
handler);
+
+private:
+                       BLocker                         fLock;
+                       LoadingStateHandlerList
+                                                               fStateHandlers;
+       static  ImageDebugLoadingStateHandlerRoster*
+                                                               
sDefaultInstance;
+};
+
+
+#endif // IMAGE_DEBUG_LOADING_STATE_HANDLER_ROSTER_H
+
diff --git 
a/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.cpp
 
b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.cpp
new file mode 100644
index 0000000..21b58b5
--- /dev/null
+++ 
b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "DwarfLoadingStateHandler.h"
+
+#include <Entry.h>
+#include <Path.h>
+
+#include "DwarfFile.h"
+#include "DwarfImageDebugInfoLoadingState.h"
+#include "Tracing.h"
+#include "UserInterface.h"
+
+
+DwarfLoadingStateHandler::DwarfLoadingStateHandler()
+       :
+       ImageDebugLoadingStateHandler()
+{
+}
+
+
+DwarfLoadingStateHandler::~DwarfLoadingStateHandler()
+{
+}
+
+
+bool
+DwarfLoadingStateHandler::SupportsState(
+       SpecificImageDebugInfoLoadingState* state)
+{
+       return dynamic_cast<DwarfImageDebugInfoLoadingState*>(state) != NULL;
+}
+
+
+void
+DwarfLoadingStateHandler::HandleState(
+       SpecificImageDebugInfoLoadingState* state, UserInterface* interface)
+{
+       DwarfImageDebugInfoLoadingState* dwarfState
+               = dynamic_cast<DwarfImageDebugInfoLoadingState*>(state);
+
+       if (dwarfState == NULL) {
+               ERROR("DwarfLoadingStateHandler::HandleState() passed "
+                       "non-dwarf state object %p.", state);
+               return;
+       }
+
+       DwarfFileLoadingState& fileState = dwarfState->GetFileState();
+
+       // TODO: if the image in question is packaged, query if it has a
+       // corresponding debug info package. If so, offer to install it and
+       // then locate the file automatically rather than forcing the user to
+       // locate the file manually.
+       BString message;
+       message.SetToFormat("The debug information file '%s' for image '%s' is "
+               "missing. Please locate it if possible.",
+               fileState.externalInfoFileName.String(), 
fileState.dwarfFile->Name());
+       int32 choice = interface->SynchronouslyAskUser("Debug info missing",
+               message.String(), "Locate", "Skip", NULL);
+
+       if (choice == 0) {
+               entry_ref ref;
+               interface->SynchronouslyAskUserForFile(&ref);
+               BPath path(&ref);
+               if (path.InitCheck() == B_OK)
+                       fileState.locatedExternalInfoPath = path.Path();
+       }
+
+       fileState.state = DWARF_FILE_LOADING_STATE_USER_INPUT_PROVIDED;
+}
diff --git 
a/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.h
 
b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.h
new file mode 100644
index 0000000..18bbb00
--- /dev/null
+++ 
b/src/apps/debugger/debug_info/loading_state_handlers/DwarfLoadingStateHandler.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef DWARF_LOADING_STATE_HANDLER
+#define DWARF_LOADING_STATE_HANDLER
+
+
+#include "ImageDebugLoadingStateHandler.h"
+
+
+class DwarfLoadingStateHandler : public ImageDebugLoadingStateHandler {
+public:
+                                                               
DwarfLoadingStateHandler();
+       virtual                                         
~DwarfLoadingStateHandler();
+
+       virtual bool                            SupportsState(
+                                                                       
SpecificImageDebugInfoLoadingState* state);
+
+       virtual void                            HandleState(
+                                                                       
SpecificImageDebugInfoLoadingState* state,
+                                                                       
UserInterface* interface);
+
+};
+
+
+#endif // DWARF_LOADING_STATE_HANDLER_H

############################################################################

Revision:    hrev47378
Commit:      d44d8207a86103afa47f1862c06ff46e46e1cb33
URL:         http://cgit.haiku-os.org/haiku/commit/?id=d44d820
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Sat Jun 14 00:25:13 2014 UTC

Ticket:      https://dev.haiku-os.org/ticket/10138

Debugger: Finish handling of missing debug information.

Add a listener interface for LoadImageDebugInfoJob that allows it to request
user assistance based on its current state. Adjust callers to pass in said
listener accordingly.

Implement the aforementioned listener interface in TeamDebugger, and use the
loading state handler roster to find the appropriate handler / handle the 
request.

This implements most of what's needed for #10138, the main piece still missing
is for the dwarf handler to detect whether the image in question comes from a 
package,
and if so, to offer to install the corresponding debug information package 
rather than
locating the file manually, assuming such a package exists.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/controllers/TeamDebugger.cpp 
b/src/apps/debugger/controllers/TeamDebugger.cpp
index 5be1681..d084e22 100644
--- a/src/apps/debugger/controllers/TeamDebugger.cpp
+++ b/src/apps/debugger/controllers/TeamDebugger.cpp
@@ -32,12 +32,16 @@
 #include "Function.h"
 #include "FunctionID.h"
 #include "ImageDebugInfo.h"
+#include "ImageDebugInfoLoadingState.h"
+#include "ImageDebugLoadingStateHandler.h"
+#include "ImageDebugLoadingStateHandlerRoster.h"
 #include "Jobs.h"
 #include "LocatableFile.h"
 #include "MessageCodes.h"
 #include "SettingsManager.h"
 #include "SourceCode.h"
 #include "SpecificImageDebugInfo.h"
+#include "SpecificImageDebugInfoLoadingState.h"
 #include "StackFrame.h"
 #include "StackFrameValues.h"
 #include "Statement.h"
@@ -463,8 +467,7 @@ TeamDebugger::Init(team_id teamID, thread_id threadID, int 
argc,
                                return error;
 
                        ThreadHandler* handler = new(std::nothrow) 
ThreadHandler(thread,
-                               fWorker, fDebuggerInterface,
-                               fBreakpointManager);
+                               fWorker, fDebuggerInterface, this, 
fBreakpointManager);
                        if (handler == NULL)
                                return B_NO_MEMORY;
 
@@ -787,6 +790,20 @@ TeamDebugger::MessageReceived(BMessage* message)
                        break;
                }
 
+               case MSG_DEBUG_INFO_NEEDS_USER_INPUT:
+               {
+                       Job* job;
+                       ImageDebugInfoLoadingState* state;
+                       if (message->FindPointer("job", (void**)&job) != B_OK)
+                               break;
+                       if (message->FindPointer("state", (void**)&state) != 
B_OK)
+                               break;
+
+                       _HandleDebugInfoJobUserInput(state);
+                       fWorker->ResumeJob(job);
+                       break;
+               }
+
                default:
                        BLooper::MessageReceived(message);
                        break;
@@ -848,7 +865,7 @@ TeamDebugger::FunctionSourceCodeRequested(FunctionInstance* 
functionInstance,
 void
 TeamDebugger::ImageDebugInfoRequested(Image* image)
 {
-       LoadImageDebugInfoJob::ScheduleIfNecessary(fWorker, image);
+       LoadImageDebugInfoJob::ScheduleIfNecessary(fWorker, image, this);
 }
 
 
@@ -1122,6 +1139,20 @@ TeamDebugger::JobAborted(Job* job)
 
 
 void
+TeamDebugger::ImageDebugInfoJobNeedsUserInput(Job* job,
+       ImageDebugInfoLoadingState* state)
+{
+       TRACE_JOBS("TeamDebugger::DebugInfoJobNeedsUserInput(%p, %p)\n",
+               job, state);
+
+       BMessage message(MSG_DEBUG_INFO_NEEDS_USER_INPUT);
+       message.AddPointer("job", job);
+       message.AddPointer("state", state);
+       PostMessage(&message);
+}
+
+
+void
 TeamDebugger::ThreadStateChanged(const ::Team::ThreadEvent& event)
 {
        BMessage message(MSG_THREAD_STATE_CHANGED);
@@ -1405,8 +1436,7 @@ TeamDebugger::_HandleThreadCreated(ThreadCreatedEvent* 
event)
                fTeam->AddThread(info, &thread);
 
                ThreadHandler* handler = new(std::nothrow) ThreadHandler(thread,
-                       fWorker, fDebuggerInterface,
-                       fBreakpointManager);
+                       fWorker, fDebuggerInterface, this, fBreakpointManager);
                if (handler != NULL) {
                        fThreadHandlers.Insert(handler);
                        handler->Init();
@@ -1909,6 +1939,24 @@ TeamDebugger::_HandleSetArguments(int argc, const char* 
const* argv)
 }
 
 
+void
+TeamDebugger::_HandleDebugInfoJobUserInput(ImageDebugInfoLoadingState* state)
+{
+       SpecificImageDebugInfoLoadingState* specificState
+               = state->GetSpecificDebugInfoLoadingState();
+
+       ImageDebugLoadingStateHandler* handler;
+       if (ImageDebugLoadingStateHandlerRoster::Default()
+                       ->FindStateHandler(specificState, handler) != B_OK) {
+               TRACE_JOBS("TeamDebugger::_HandleDebugInfoJobUserInput(): "
+                       "Failed to find appropriate information handler, 
aborting.");
+               return;
+       }
+
+       handler->HandleState(specificState, fUserInterface);
+}
+
+
 ThreadHandler*
 TeamDebugger::_GetThreadHandler(thread_id threadID)
 {
diff --git a/src/apps/debugger/controllers/TeamDebugger.h 
b/src/apps/debugger/controllers/TeamDebugger.h
index c91fc58..46fa880 100644
--- a/src/apps/debugger/controllers/TeamDebugger.h
+++ b/src/apps/debugger/controllers/TeamDebugger.h
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2013-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef TEAM_DEBUGGER_H
@@ -13,6 +13,7 @@
 #include <debug_support.h>
 
 #include "DebugEvent.h"
+#include "Jobs.h"
 #include "Team.h"
 #include "TeamSettings.h"
 #include "ThreadHandler.h"
@@ -30,7 +31,8 @@ class WatchpointManager;
 
 
 class TeamDebugger : public BLooper, private UserInterfaceListener,
-       private JobListener, private Team::Listener {
+       private JobListener, private ImageDebugInfoJobListener,
+       private Team::Listener {
 public:
        class Listener;
 
@@ -110,6 +112,9 @@ private:
        virtual void                            JobFailed(Job* job);
        virtual void                            JobAborted(Job* job);
 
+       virtual void                            
ImageDebugInfoJobNeedsUserInput(Job* job,
+                                                                       
ImageDebugInfoLoadingState* state);
+
        // Team::Listener
        virtual void                            ThreadStateChanged(
                                                                        const 
::Team::ThreadEvent& event);
@@ -178,6 +183,9 @@ private:
                        status_t                        _HandleSetArguments(int 
argc,
                                                                        const 
char* const* argv);
 
+                       void                            
_HandleDebugInfoJobUserInput(
+                                                                       
ImageDebugInfoLoadingState* state);
+
                        ThreadHandler*          _GetThreadHandler(thread_id 
threadID);
 
                        status_t                        _AddImage(const 
ImageInfo& imageInfo,
diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp 
b/src/apps/debugger/controllers/ThreadHandler.cpp
index 3a1a02f..a9653c2 100644
--- a/src/apps/debugger/controllers/ThreadHandler.cpp
+++ b/src/apps/debugger/controllers/ThreadHandler.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2010-2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2010-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -44,11 +44,13 @@ enum {
 
 ThreadHandler::ThreadHandler(Thread* thread, Worker* worker,
        DebuggerInterface* debuggerInterface,
+       ImageDebugInfoJobListener* listener,
        BreakpointManager* breakpointManager)
        :
        fThread(thread),
        fWorker(worker),
        fDebuggerInterface(debuggerInterface),
+       fDebugInfoJobListener(listener),
        fBreakpointManager(breakpointManager),
        fStepMode(STEP_NONE),
        fStepStatement(NULL),
@@ -376,7 +378,8 @@ ThreadHandler::HandleCpuStateChanged()
        if (fThread->GetCpuState() != NULL && fThread->GetStackTrace() == NULL) 
{
                fWorker->ScheduleJob(
                        new(std::nothrow) GetStackTraceJob(fDebuggerInterface,
-                               fDebuggerInterface->GetArchitecture(), 
fThread));
+                               fDebugInfoJobListener, 
fDebuggerInterface->GetArchitecture(),
+                               fThread));
        }
 }
 
diff --git a/src/apps/debugger/controllers/ThreadHandler.h 
b/src/apps/debugger/controllers/ThreadHandler.h
index 3bbff41..eb80905 100644
--- a/src/apps/debugger/controllers/ThreadHandler.h
+++ b/src/apps/debugger/controllers/ThreadHandler.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef THREAD_HANDLER_H
@@ -17,6 +18,7 @@
 
 class BreakpointManager;
 class DebuggerInterface;
+class ImageDebugInfoJobListener;
 class StackFrame;
 class Statement;
 class Worker;
@@ -27,6 +29,7 @@ class ThreadHandler : public BReferenceable, private 
ImageDebugInfoProvider,
 public:
                                                                
ThreadHandler(Thread* thread, Worker* worker,
                                                                        
DebuggerInterface* debuggerInterface,
+                                                                       
ImageDebugInfoJobListener* listener,
                                                                        
BreakpointManager* breakpointManager);
                                                                
~ThreadHandler();
 
@@ -103,6 +106,7 @@ private:
                        Thread*                         fThread;
                        Worker*                         fWorker;
                        DebuggerInterface*      fDebuggerInterface;
+                       ImageDebugInfoJobListener* fDebugInfoJobListener;
                        BreakpointManager*      fBreakpointManager;
                        uint32                          fStepMode;
                        Statement*                      fStepStatement;
diff --git a/src/apps/debugger/jobs/GetStackTraceJob.cpp 
b/src/apps/debugger/jobs/GetStackTraceJob.cpp
index 0bc286e..d0b28ce 100644
--- a/src/apps/debugger/jobs/GetStackTraceJob.cpp
+++ b/src/apps/debugger/jobs/GetStackTraceJob.cpp
@@ -18,10 +18,12 @@
 
 
 GetStackTraceJob::GetStackTraceJob(DebuggerInterface* debuggerInterface,
-       Architecture* architecture, Thread* thread)
+       ImageDebugInfoJobListener* listener, Architecture* architecture,
+       Thread* thread)
        :
        fKey(thread, JOB_TYPE_GET_STACK_TRACE),
        fDebuggerInterface(debuggerInterface),
+       fDebugInfoJobListener(listener),
        fArchitecture(architecture),
        fThread(thread)
 {
@@ -82,7 +84,7 @@ GetStackTraceJob::GetImageDebugInfo(Image* image, 
ImageDebugInfo*& _info)
                // schedule a job, if not loaded
                ImageDebugInfo* info;
                status_t error = 
LoadImageDebugInfoJob::ScheduleIfNecessary(GetWorker(),
-                       image, &info);
+                       image, fDebugInfoJobListener, &info);
                if (error != B_OK)
                        return error;
 
diff --git a/src/apps/debugger/jobs/Jobs.h b/src/apps/debugger/jobs/Jobs.h
index f024bc3..bc5df71 100644
--- a/src/apps/debugger/jobs/Jobs.h
+++ b/src/apps/debugger/jobs/Jobs.h
@@ -83,10 +83,19 @@ private:
 };
 
 
+class ImageDebugInfoJobListener {
+public:
+       virtual                                         
~ImageDebugInfoJobListener();
+       virtual void                            
ImageDebugInfoJobNeedsUserInput(Job* job,
+                                                                       
ImageDebugInfoLoadingState* state);
+};
+
+
 class GetStackTraceJob : public Job, private ImageDebugInfoProvider {
 public:
                                                                
GetStackTraceJob(
                                                                        
DebuggerInterface* debuggerInterface,
+                                                                       
ImageDebugInfoJobListener* listener,
                                                                        
Architecture* architecture, Thread* thread);
        virtual                                         ~GetStackTraceJob();
 
@@ -101,6 +110,7 @@ private:
 private:
                        SimpleJobKey            fKey;
                        DebuggerInterface*      fDebuggerInterface;
+                       ImageDebugInfoJobListener* fDebugInfoJobListener;
                        Architecture*           fArchitecture;
                        Thread*                         fThread;
                        CpuState*                       fCpuState;
@@ -109,7 +119,8 @@ private:
 
 class LoadImageDebugInfoJob : public Job {
 public:
-                                                               
LoadImageDebugInfoJob(Image* image);
+                                                               
LoadImageDebugInfoJob(Image* image,
+                                                                       
ImageDebugInfoJobListener* listener);
        virtual                                         
~LoadImageDebugInfoJob();
 
        virtual const JobKey&           Key() const;
@@ -117,6 +128,7 @@ public:
 
        static  status_t                        ScheduleIfNecessary(Worker* 
worker,
                                                                        Image* 
image,
+                                                                       
ImageDebugInfoJobListener* listener,
                                                                        
ImageDebugInfo** _imageDebugInfo = NULL);
                                                                                
// If already loaded returns a
                                                                                
// reference, if desired. If not loaded
@@ -125,12 +137,19 @@ public:
                                                                                
// if scheduling the job failed, or the
                                                                                
// debug info already failed to load
                                                                                
// earlier.
+private:
+                       void                            
NotifyUserInputListener();
+
+private:
+       typedef BObjectList<ImageDebugInfoJobListener> ListenerList;
+
 
 private:
                        SimpleJobKey            fKey;
                        Image*                          fImage;
                        ImageDebugInfoLoadingState
                                                                fState;
+                       ImageDebugInfoJobListener* fListener;
 };
 
 
diff --git a/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp 
b/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
index 418873f..600055c 100644
--- a/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
+++ b/src/apps/debugger/jobs/LoadImageDebugInfoJob.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2012-2014, Rene Gollent, rene@xxxxxxxxxxx.
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
  * Distributed under the terms of the MIT License.
  */
@@ -14,11 +14,31 @@
 #include "Team.h"
 
 
-LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image)
+// #pragma mark - ImageDebugInfoJobListener
+
+
+ImageDebugInfoJobListener::~ImageDebugInfoJobListener()
+{
+}
+
+
+void
+ImageDebugInfoJobListener::ImageDebugInfoJobNeedsUserInput(Job* job,
+       ImageDebugInfoLoadingState* state)
+{
+}
+
+
+// #pragma mark - LoadImageDebugInfoJob
+
+
+LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image,
+       ImageDebugInfoJobListener* listener)
        :
        fKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO),
        fImage(image),
-       fState()
+       fState(),
+       fListener(listener)
 {
        fImage->AcquireReference();
 }
@@ -54,11 +74,9 @@ LoadImageDebugInfoJob::Do()
        locker.Lock();
 
        if (fState.UserInputRequired()) {
-               // TODO: notify the user interface
+               NotifyUserInputListener();
                return WaitForUserInput();
-       }
-
-       if (error == B_OK) {
+       } else if (error == B_OK) {
                error = fImage->SetImageDebugInfo(debugInfo, 
IMAGE_DEBUG_INFO_LOADED);
                debugInfo->ReleaseReference();
        } else
@@ -70,7 +88,7 @@ LoadImageDebugInfoJob::Do()
 
 /*static*/ status_t
 LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
-       ImageDebugInfo** _imageDebugInfo)
+       ImageDebugInfoJobListener* listener, ImageDebugInfo** _imageDebugInfo)
 {
        AutoLocker<Team> teamLocker(image->GetTeam());
 
@@ -95,7 +113,8 @@ LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, 
Image* image,
                return B_ERROR;
 
        // schedule a job
-       LoadImageDebugInfoJob* job = new(std::nothrow) 
LoadImageDebugInfoJob(image);
+       LoadImageDebugInfoJob* job = new(std::nothrow) 
LoadImageDebugInfoJob(image,
+               listener);
        if (job == NULL)
                return B_NO_MEMORY;
 
@@ -111,3 +130,12 @@ LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, 
Image* image,
                *_imageDebugInfo = NULL;
        return B_OK;
 }
+
+
+void
+LoadImageDebugInfoJob::NotifyUserInputListener()
+{
+       if (fListener != NULL)
+               fListener->ImageDebugInfoJobNeedsUserInput(this, &fState);
+}
+


Other related posts:

  • » [haiku-commits] haiku: hrev47378 - in src/apps/debugger: debug_info dwarf user_interface/gui controllers debug_info/loading_state_handlers - anevilyak