Debugger: Split into core library and application.
- Add subfolder src/kits/debugger which contains the debugger's core functionality and lower layers. Correspondingly add headers/private/debugger for shared headers to be used by clients such as the Debugger application and eventual remote_debug_server. Adjust various files to account for differences as a result of the split and moves. - Add libdebugger.so to minimal Jamfile.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef INTEGER_FORMATTER_H
|
||||
#define INTEGER_FORMATTER_H
|
||||
|
||||
|
||||
#include <Variant.h>
|
||||
|
||||
|
||||
enum integer_format {
|
||||
INTEGER_FORMAT_DEFAULT = 0,
|
||||
INTEGER_FORMAT_SIGNED = 1,
|
||||
INTEGER_FORMAT_UNSIGNED = 2,
|
||||
INTEGER_FORMAT_HEX_DEFAULT = 3,
|
||||
INTEGER_FORMAT_HEX_8 = 8,
|
||||
INTEGER_FORMAT_HEX_16 = 16,
|
||||
INTEGER_FORMAT_HEX_32 = 32,
|
||||
INTEGER_FORMAT_HEX_64 = 64
|
||||
};
|
||||
|
||||
|
||||
class IntegerFormatter {
|
||||
public:
|
||||
static bool FormatValue(const BVariant& value,
|
||||
integer_format format, char* buffer,
|
||||
size_t bufferSize);
|
||||
};
|
||||
|
||||
|
||||
#endif // INTEGER_FORMATTER_H
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2013, Rene Gollent, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef RANGE_LIST_H
|
||||
#define RANGE_LIST_H
|
||||
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
struct Range {
|
||||
int32 lowerBound;
|
||||
int32 upperBound;
|
||||
|
||||
Range()
|
||||
:
|
||||
lowerBound(-1),
|
||||
upperBound(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Range(int32 lowValue, int32 highValue)
|
||||
:
|
||||
lowerBound(lowValue),
|
||||
upperBound(highValue)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class RangeList : private BObjectList<Range>
|
||||
{
|
||||
public:
|
||||
RangeList();
|
||||
virtual ~RangeList();
|
||||
|
||||
|
||||
status_t AddRange(int32 lowValue, int32 highValue);
|
||||
status_t AddRange(const Range& range);
|
||||
|
||||
void RemoveRangeAt(int32 index);
|
||||
|
||||
int32 CountRanges() const;
|
||||
const Range* RangeAt(int32 index) const;
|
||||
|
||||
bool Contains(int32 value) const;
|
||||
|
||||
private:
|
||||
void _CollapseOverlappingRanges(int32 startIndex,
|
||||
int32 highValue);
|
||||
};
|
||||
|
||||
#endif // RANGE_LIST_H
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected]. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef STRING_UTILS_H
|
||||
#define STRING_UTILS_H
|
||||
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class StringUtils {
|
||||
public:
|
||||
static uint32 HashValue(const char* string);
|
||||
static uint32 HashValue(const BString& string);
|
||||
};
|
||||
|
||||
|
||||
/*static*/ inline uint32
|
||||
StringUtils::HashValue(const BString& string)
|
||||
{
|
||||
return HashValue(string.String());
|
||||
}
|
||||
|
||||
|
||||
#endif // STRING_UTILS_H
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright 2009-2012, Ingo Weinhold, [email protected].
|
||||
* Copyright 2014, Rene Gollent, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WORKER_H
|
||||
#define WORKER_H
|
||||
|
||||
#include <Locker.h>
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Referenceable.h>
|
||||
#include <String.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <util/OpenHashTable.h>
|
||||
|
||||
|
||||
class Job;
|
||||
class Worker;
|
||||
|
||||
|
||||
enum job_state {
|
||||
JOB_STATE_UNSCHEDULED,
|
||||
JOB_STATE_WAITING,
|
||||
JOB_STATE_ACTIVE,
|
||||
JOB_STATE_ABORTED,
|
||||
JOB_STATE_FAILED,
|
||||
JOB_STATE_SUCCEEDED
|
||||
};
|
||||
|
||||
enum job_wait_status {
|
||||
JOB_DEPENDENCY_NOT_FOUND,
|
||||
JOB_DEPENDENCY_SUCCEEDED,
|
||||
JOB_DEPENDENCY_FAILED,
|
||||
JOB_DEPENDENCY_ABORTED,
|
||||
JOB_DEPENDENCY_ACTIVE,
|
||||
|
||||
JOB_USER_INPUT_WAITING
|
||||
// internal only
|
||||
};
|
||||
|
||||
|
||||
class JobKey {
|
||||
public:
|
||||
virtual ~JobKey();
|
||||
|
||||
virtual size_t HashValue() const = 0;
|
||||
|
||||
virtual bool operator==(const JobKey& other) const = 0;
|
||||
};
|
||||
|
||||
|
||||
struct SimpleJobKey : public JobKey {
|
||||
const void* object;
|
||||
uint32 type;
|
||||
|
||||
public:
|
||||
SimpleJobKey(const void* object, uint32 type);
|
||||
SimpleJobKey(const SimpleJobKey& other);
|
||||
|
||||
virtual size_t HashValue() const;
|
||||
|
||||
virtual bool operator==(const JobKey& other) const;
|
||||
|
||||
SimpleJobKey& operator=(const SimpleJobKey& other);
|
||||
};
|
||||
|
||||
|
||||
class JobListener {
|
||||
public:
|
||||
virtual ~JobListener();
|
||||
|
||||
virtual void JobStarted(Job* job);
|
||||
virtual void JobDone(Job* job);
|
||||
virtual void JobWaitingForInput(Job* job);
|
||||
virtual void JobFailed(Job* job);
|
||||
virtual void JobAborted(Job* job);
|
||||
};
|
||||
|
||||
|
||||
typedef DoublyLinkedList<Job> JobList;
|
||||
|
||||
|
||||
class Job : public BReferenceable, public DoublyLinkedListLinkImpl<Job> {
|
||||
public:
|
||||
Job();
|
||||
virtual ~Job();
|
||||
|
||||
virtual const JobKey& Key() const = 0;
|
||||
virtual status_t Do() = 0;
|
||||
|
||||
Worker* GetWorker() const { return fWorker; }
|
||||
job_state State() const { return fState; }
|
||||
|
||||
const BString& GetDescription() const
|
||||
{ return fDescription; }
|
||||
|
||||
protected:
|
||||
job_wait_status WaitFor(const JobKey& key);
|
||||
status_t WaitForUserInput();
|
||||
void SetDescription(const char* format, ...);
|
||||
|
||||
private:
|
||||
friend class Worker;
|
||||
|
||||
private:
|
||||
void SetWorker(Worker* worker);
|
||||
void SetState(job_state state);
|
||||
|
||||
Job* Dependency() const { return fDependency; }
|
||||
void SetDependency(Job* job);
|
||||
|
||||
JobList& DependentJobs() { return fDependentJobs; }
|
||||
|
||||
job_wait_status WaitStatus() const { return fWaitStatus; }
|
||||
void SetWaitStatus(job_wait_status status);
|
||||
|
||||
status_t AddListener(JobListener* listener);
|
||||
void RemoveListener(JobListener* listener);
|
||||
void NotifyListeners();
|
||||
|
||||
private:
|
||||
typedef BObjectList<JobListener> ListenerList;
|
||||
|
||||
private:
|
||||
Worker* fWorker;
|
||||
job_state fState;
|
||||
Job* fDependency;
|
||||
JobList fDependentJobs;
|
||||
job_wait_status fWaitStatus;
|
||||
ListenerList fListeners;
|
||||
BString fDescription;
|
||||
|
||||
public:
|
||||
Job* fNext;
|
||||
};
|
||||
|
||||
|
||||
class Worker {
|
||||
public:
|
||||
Worker();
|
||||
~Worker();
|
||||
|
||||
status_t Init();
|
||||
void ShutDown();
|
||||
|
||||
bool Lock() { return fLock.Lock(); }
|
||||
void Unlock() { fLock.Unlock(); }
|
||||
|
||||
status_t ScheduleJob(Job* job,
|
||||
JobListener* listener = NULL);
|
||||
// always takes over reference
|
||||
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
|
||||
|
||||
bool HasPendingJobs();
|
||||
|
||||
status_t AddListener(const JobKey& key,
|
||||
JobListener* listener);
|
||||
void RemoveListener(const JobKey& key,
|
||||
JobListener* listener);
|
||||
|
||||
private:
|
||||
friend class Job;
|
||||
|
||||
struct JobHashDefinition {
|
||||
typedef JobKey KeyType;
|
||||
typedef Job ValueType;
|
||||
|
||||
size_t HashKey(const JobKey& key) const
|
||||
{
|
||||
return key.HashValue();
|
||||
}
|
||||
|
||||
size_t Hash(Job* value) const
|
||||
{
|
||||
return HashKey(value->Key());
|
||||
}
|
||||
|
||||
bool Compare(const JobKey& key, Job* value) const
|
||||
{
|
||||
return value->Key() == key;
|
||||
}
|
||||
|
||||
Job*& GetLink(Job* value) const
|
||||
{
|
||||
return value->fNext;
|
||||
}
|
||||
};
|
||||
|
||||
typedef BOpenHashTable<JobHashDefinition> JobTable;
|
||||
|
||||
private:
|
||||
job_wait_status WaitForJob(Job* waitingJob, const JobKey& key);
|
||||
status_t WaitForUserInput(Job* waitingJob);
|
||||
|
||||
static status_t _WorkerLoopEntry(void* data);
|
||||
status_t _WorkerLoop();
|
||||
|
||||
void _ProcessJobs();
|
||||
void _AbortJob(Job* job, bool removeFromTable);
|
||||
void _FinishJob(Job* job);
|
||||
|
||||
private:
|
||||
BLocker fLock;
|
||||
JobTable fJobs;
|
||||
JobList fUnscheduledJobs;
|
||||
JobList fAbortedJobs;
|
||||
JobList fSuspendedJobs;
|
||||
sem_id fWorkToDoSem;
|
||||
thread_id fWorkerThread;
|
||||
volatile bool fTerminating;
|
||||
};
|
||||
|
||||
|
||||
#endif // WORKER_H
|
||||
Reference in New Issue
Block a user