[Haiku-commits] r31142 - in haiku/trunk/src/apps/debugger: . arch arch/x86 debug_info debugger_interface gui/team_window

bonefish at BerliOS bonefish at mail.berlios.de
Sat Jun 20 19:20:52 CEST 2009


Author: bonefish
Date: 2009-06-20 19:20:49 +0200 (Sat, 20 Jun 2009)
New Revision: 31142
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31142&view=rev

Added:
   haiku/trunk/src/apps/debugger/SymbolInfo.cpp
   haiku/trunk/src/apps/debugger/SymbolInfo.h
   haiku/trunk/src/apps/debugger/debug_info/
   haiku/trunk/src/apps/debugger/debug_info/BasicFunctionDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/BasicFunctionDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/DebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/DebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/DebuggerDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/DebuggerDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/FunctionDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/FunctionDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/ImageDebugInfo.cpp
   haiku/trunk/src/apps/debugger/debug_info/ImageDebugInfo.h
   haiku/trunk/src/apps/debugger/debug_info/ImageDebugInfoProvider.cpp
   haiku/trunk/src/apps/debugger/debug_info/ImageDebugInfoProvider.h
Removed:
   haiku/trunk/src/apps/debugger/arch/x86/StackFrameX86.cpp
   haiku/trunk/src/apps/debugger/arch/x86/StackFrameX86.h
Modified:
   haiku/trunk/src/apps/debugger/Image.cpp
   haiku/trunk/src/apps/debugger/Image.h
   haiku/trunk/src/apps/debugger/ImageInfo.cpp
   haiku/trunk/src/apps/debugger/ImageInfo.h
   haiku/trunk/src/apps/debugger/Jamfile
   haiku/trunk/src/apps/debugger/Jobs.cpp
   haiku/trunk/src/apps/debugger/Jobs.h
   haiku/trunk/src/apps/debugger/Team.cpp
   haiku/trunk/src/apps/debugger/Team.h
   haiku/trunk/src/apps/debugger/arch/Architecture.cpp
   haiku/trunk/src/apps/debugger/arch/Architecture.h
   haiku/trunk/src/apps/debugger/arch/ArchitectureTypes.h
   haiku/trunk/src/apps/debugger/arch/CpuState.h
   haiku/trunk/src/apps/debugger/arch/StackFrame.cpp
   haiku/trunk/src/apps/debugger/arch/StackFrame.h
   haiku/trunk/src/apps/debugger/arch/StackTrace.cpp
   haiku/trunk/src/apps/debugger/arch/StackTrace.h
   haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp
   haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.h
   haiku/trunk/src/apps/debugger/arch/x86/CpuStateX86.cpp
   haiku/trunk/src/apps/debugger/arch/x86/CpuStateX86.h
   haiku/trunk/src/apps/debugger/debugger_interface/DebuggerInterface.cpp
   haiku/trunk/src/apps/debugger/debugger_interface/DebuggerInterface.h
   haiku/trunk/src/apps/debugger/gui/team_window/StackTraceView.cpp
Log:
* Added DebuggerInterface::GetSymbolInfos() to get the symbols for an image.
* Added the beginnings of the debug info abstraction. Currently we can only load
  the symbols via the debugger.
* Added a job to retrieve debug info for an image. Extended the GetStackTraceJob
  to support waiting for image debug info to be loaded.
* Extended ImageInfo by text/data address and size.
* Removed StackFrameX86 and made StackFrame a simple non-polymorphic class
  featuring all the needed data. The really architecture-dependent is in the
  referenced CpuState already. Added Image* and FunctionDebugInfo* attributes,
  referring to the image respectively debug info for the function hit by the
  instruction pointer.
* Switched StrackTrace's StackFrame management from DoublyLinkedList to
  BObjectList. This makes it more comfortable to use.
* Changed the code for creating stack traces:
  - The creation of the StackTrace object and the main loop to collect the
    frames are now located in the no longer virtual
    Architecture::CreateStackTrace().
  - The decision how to create a StackFrame is based on the instruction pointer.
    If it hit a function for which debug info is available, the respective
    DebugInfo::CreateStackFrame() is used, otherwise we fall back to the new
    virtual Architecture::CreateStackFrame().
* Adjusted the stack trace view to also show function names (mangled ATM).


Modified: haiku/trunk/src/apps/debugger/Image.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/Image.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/Image.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -5,17 +5,22 @@
 
 #include "Image.h"
 
+#include "ImageDebugInfo.h"
 
+
 Image::Image(Team* team,const ImageInfo& imageInfo)
 	:
 	fTeam(team),
-	fInfo(imageInfo)
+	fInfo(imageInfo),
+	fDebugInfo(NULL)
 {
 }
 
 
 Image::~Image()
 {
+	if (fDebugInfo != NULL)
+		fDebugInfo->RemoveReference();
 }
 
 
@@ -24,3 +29,29 @@
 {
 	return B_OK;
 }
+
+
+void
+Image::SetImageDebugInfo(ImageDebugInfo* debugInfo)
+{
+	if (debugInfo == fDebugInfo)
+		return;
+
+	if (fDebugInfo != NULL)
+		fDebugInfo->RemoveReference();
+
+	fDebugInfo = debugInfo;
+
+	if (fDebugInfo != NULL)
+		fDebugInfo->AddReference();
+}
+
+
+bool
+Image::ContainsAddress(target_addr_t address) const
+{
+	return (address >= fInfo.TextBase()
+			&& address < fInfo.TextBase() + fInfo.TextSize())
+		|| (address >= fInfo.DataBase()
+			&& address < fInfo.DataBase() + fInfo.DataSize());
+}

Modified: haiku/trunk/src/apps/debugger/Image.h
===================================================================
--- haiku/trunk/src/apps/debugger/Image.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/Image.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -13,6 +13,7 @@
 #include "ImageInfo.h"
 
 
+class ImageDebugInfo;
 class Team;
 
 
@@ -24,14 +25,20 @@
 			status_t			Init();
 
 
-			Team*				GetTeam() const	{ return fTeam; }
-			image_id			ID() const		{ return fInfo.ImageID(); }
-			const char*			Name() const	{ return fInfo.Name(); }
-			const ImageInfo&	Info() const	{ return fInfo; }
+			Team*				GetTeam() const		{ return fTeam; }
+			image_id			ID() const			{ return fInfo.ImageID(); }
+			const char*			Name() const		{ return fInfo.Name(); }
+			const ImageInfo&	Info() const		{ return fInfo; }
 
+			ImageDebugInfo*		GetImageDebugInfo() const { return fDebugInfo; }
+			void				SetImageDebugInfo(ImageDebugInfo* debugInfo);
+
+			bool				ContainsAddress(target_addr_t address) const;
+
 private:
 			Team*				fTeam;
 			ImageInfo			fInfo;
+			ImageDebugInfo*		fDebugInfo;
 };
 
 

Modified: haiku/trunk/src/apps/debugger/ImageInfo.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/ImageInfo.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/ImageInfo.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -10,7 +10,11 @@
 	:
 	fTeam(-1),
 	fImage(-1),
-	fName()
+	fName(),
+	fTextBase(0),
+	fTextSize(0),
+	fDataBase(0),
+	fDataSize(0)
 {
 }
 
@@ -18,24 +22,40 @@
 	:
 	fTeam(other.fTeam),
 	fImage(other.fImage),
-	fName(other.fName)
+	fName(other.fName),
+	fTextBase(other.fTextBase),
+	fTextSize(other.fTextSize),
+	fDataBase(other.fDataBase),
+	fDataSize(other.fDataSize)
 {
 }
 
 
-ImageInfo::ImageInfo(team_id team, image_id image, const BString& name)
+ImageInfo::ImageInfo(team_id team, image_id image, const BString& name,
+	target_addr_t textBase, target_size_t textSize, target_addr_t dataBase,
+	target_size_t dataSize)
 	:
 	fTeam(team),
 	fImage(image),
-	fName(name)
+	fName(name),
+	fTextBase(textBase),
+	fTextSize(textSize),
+	fDataBase(dataBase),
+	fDataSize(dataSize)
 {
 }
 
 
 void
-ImageInfo::SetTo(team_id team, image_id image, const BString& name)
+ImageInfo::SetTo(team_id team, image_id image, const BString& name,
+	target_addr_t textBase, target_size_t textSize, target_addr_t dataBase,
+	target_size_t dataSize)
 {
 	fTeam = team;
 	fImage = image;
 	fName = name;
+	fTextBase = textBase;
+	fTextSize = textSize;
+	fDataBase = dataBase;
+	fDataSize = dataSize;
 }

Modified: haiku/trunk/src/apps/debugger/ImageInfo.h
===================================================================
--- haiku/trunk/src/apps/debugger/ImageInfo.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/ImageInfo.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -8,25 +8,44 @@
 #include <image.h>
 #include <String.h>
 
+#include "ArchitectureTypes.h"
 
+
 class ImageInfo {
 public:
 								ImageInfo();
 								ImageInfo(const ImageInfo& other);
 								ImageInfo(team_id team, image_id image,
-									const BString& name);
+									const BString& name,
+									target_addr_t textBase,
+									target_size_t textSize,
+									target_addr_t dataBase,
+									target_size_t dataSize);
 
 			void				SetTo(team_id team, image_id image,
-									const BString& name);
+									const BString& name,
+									target_addr_t textBase,
+									target_size_t textSize,
+									target_addr_t dataBase,
+									target_size_t dataSize);
 
 			team_id				TeamID() const	{ return fTeam; }
 			image_id			ImageID() const	{ return fImage; }
 			const char*			Name() const	{ return fName.String(); }
 
+			target_addr_t		TextBase() const	{ return fTextBase; }
+			target_size_t		TextSize() const	{ return fTextSize; }
+			target_addr_t		DataBase() const	{ return fDataBase; }
+			target_size_t		DataSize() const	{ return fDataSize; }
+
 private:
 			thread_id			fTeam;
 			image_id			fImage;
 			BString				fName;
+			target_addr_t		fTextBase;
+			target_size_t		fTextSize;
+			target_addr_t		fDataBase;
+			target_size_t		fDataSize;
 };
 
 

Modified: haiku/trunk/src/apps/debugger/Jamfile
===================================================================
--- haiku/trunk/src/apps/debugger/Jamfile	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/Jamfile	2009-06-20 17:20:49 UTC (rev 31142)
@@ -8,6 +8,7 @@
 
 SEARCH_SOURCE += [ FDirName $(SUBDIR) arch ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) arch x86 ] ;
+SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_info ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ;
 SEARCH_SOURCE += [ FDirName $(SUBDIR) gui team_window ] ;
 
@@ -23,6 +24,7 @@
 	Image.cpp
 	ImageInfo.cpp
 	Jobs.cpp
+	SymbolInfo.cpp
 	Team.cpp
 	TeamDebugger.cpp
 	TeamDebugModel.cpp
@@ -40,8 +42,15 @@
 	# arch/x86
 	ArchitectureX86.cpp
 	CpuStateX86.cpp
-	StackFrameX86.cpp
 
+	# debug_info
+	BasicFunctionDebugInfo.cpp
+	DebuggerDebugInfo.cpp
+	DebugInfo.cpp
+	FunctionDebugInfo.cpp
+	ImageDebugInfo.cpp
+	ImageDebugInfoProvider.cpp
+
 	# debugger_interface
 	DebugEvent.cpp
 	DebuggerInterface.cpp

Modified: haiku/trunk/src/apps/debugger/Jobs.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/Jobs.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/Jobs.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -5,11 +5,15 @@
 
 #include "Jobs.h"
 
+#include <new>
+
 #include <AutoLocker.h>
 
 #include "Architecture.h"
 #include "CpuState.h"
 #include "DebuggerInterface.h"
+#include "Image.h"
+#include "ImageDebugInfo.h"
 #include "StackTrace.h"
 #include "Team.h"
 #include "Thread.h"
@@ -101,7 +105,7 @@
 
 	// get the stack trace
 	StackTrace* stackTrace;
-	status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(),
+	status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), this,
 		fCpuState, stackTrace);
 	if (error != B_OK)
 		return error;
@@ -115,3 +119,108 @@
 
 	return B_OK;
 }
+
+
+status_t
+GetStackTraceJob::GetImageDebugInfo(Image* image, ImageDebugInfo*& _info)
+{
+	AutoLocker<Team> teamLocker(fThread->GetTeam());
+
+	while (image->GetImageDebugInfo() == NULL) {
+		// The info has not yet been loaded -- check whether a job has already
+		// been scheduled.
+		AutoLocker<Worker> workerLocker(GetWorker());
+		JobKey key(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO);
+		Job* loadImageDebugInfoJob = GetWorker()->GetJob(key);
+		if (loadImageDebugInfoJob == NULL) {
+			// no job yet -- schedule one
+			loadImageDebugInfoJob = new(std::nothrow) LoadImageDebugInfoJob(
+				fDebuggerInterface, fArchitecture, image);
+			if (loadImageDebugInfoJob == NULL)
+				return B_NO_MEMORY;
+
+			status_t error = GetWorker()->ScheduleJob(loadImageDebugInfoJob);
+			if (error != B_OK)
+				return error;
+		}
+
+		workerLocker.Unlock();
+		teamLocker.Unlock();
+
+		// wait for the job to finish
+		switch (WaitFor(key)) {
+			case JOB_DEPENDENCY_SUCCEEDED:
+			case JOB_DEPENDENCY_NOT_FOUND:
+				// "Not found" can happen due to a race condition between
+				// unlocking the worker and starting to wait.
+				break;
+			case JOB_DEPENDENCY_FAILED:
+			case JOB_DEPENDENCY_ABORTED:
+			default:
+				return B_ERROR;
+		}
+
+		teamLocker.Lock();
+	}
+
+	_info = image->GetImageDebugInfo();
+	_info->AddReference();
+
+	return B_OK;
+}
+
+
+// #pragma mark - GetStackTraceJob
+
+
+LoadImageDebugInfoJob::LoadImageDebugInfoJob(
+	DebuggerInterface* debuggerInterface, Architecture* architecture,
+	Image* image)
+	:
+	fDebuggerInterface(debuggerInterface),
+	fArchitecture(architecture),
+	fImage(image)
+{
+	fImage->AddReference();
+}
+
+
+LoadImageDebugInfoJob::~LoadImageDebugInfoJob()
+{
+	fImage->RemoveReference();
+}
+
+
+JobKey
+LoadImageDebugInfoJob::Key() const
+{
+	return JobKey(fImage, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO);
+}
+
+
+status_t
+LoadImageDebugInfoJob::Do()
+{
+	// get an image info for the image
+	AutoLocker<Team> locker(fImage->GetTeam());
+	ImageInfo imageInfo(fImage->Info());
+	locker.Unlock();
+
+	// create the debug info
+	ImageDebugInfo* debugInfo = new(std::nothrow) ImageDebugInfo(imageInfo,
+		fDebuggerInterface, fArchitecture);
+	if (debugInfo == NULL)
+		return B_NO_MEMORY;
+
+	status_t error = debugInfo->Init();
+	if (error != B_OK) {
+		delete debugInfo;
+		return error;
+	}
+
+	// set the info
+	locker.Lock();
+	fImage->SetImageDebugInfo(debugInfo);
+
+	return B_OK;
+}

Modified: haiku/trunk/src/apps/debugger/Jobs.h
===================================================================
--- haiku/trunk/src/apps/debugger/Jobs.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/Jobs.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -5,19 +5,22 @@
 #ifndef JOBS_H
 #define JOBS_H
 
+#include "ImageDebugInfoProvider.h"
 #include "Worker.h"
 
 
 class Architecture;
 class CpuState;
 class DebuggerInterface;
+class Image;
 class Thread;
 
 
 // job types
 enum {
 	JOB_TYPE_GET_CPU_STATE,
-	JOB_TYPE_GET_STACK_TRACE
+	JOB_TYPE_GET_STACK_TRACE,
+	JOB_TYPE_LOAD_IMAGE_DEBUG_INFO
 };
 
 
@@ -37,18 +40,22 @@
 };
 
 
-class GetStackTraceJob : public Job {
+class GetStackTraceJob : public Job, private ImageDebugInfoProvider {
 public:
 								GetStackTraceJob(
 									DebuggerInterface* debuggerInterface,
-									Architecture* architecture,
-									Thread* thread);
+									Architecture* architecture, Thread* thread);
 	virtual						~GetStackTraceJob();
 
 	virtual	JobKey				Key() const;
 	virtual	status_t			Do();
 
 private:
+	// ImageDebugInfoProvider
+	virtual	status_t			GetImageDebugInfo(Image* image,
+									ImageDebugInfo*& _info);
+
+private:
 			DebuggerInterface*	fDebuggerInterface;
 			Architecture*		fArchitecture;
 			Thread*				fThread;
@@ -56,4 +63,22 @@
 };
 
 
+class LoadImageDebugInfoJob : public Job {
+public:
+								LoadImageDebugInfoJob(
+									DebuggerInterface* debuggerInterface,
+									Architecture* architecture,
+									Image* image);
+	virtual						~LoadImageDebugInfoJob();
+
+	virtual	JobKey				Key() const;
+	virtual	status_t			Do();
+
+private:
+			DebuggerInterface*	fDebuggerInterface;
+			Architecture*		fArchitecture;
+			Image*				fImage;
+};
+
+
 #endif	// JOBS_H

Added: haiku/trunk/src/apps/debugger/SymbolInfo.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/SymbolInfo.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/SymbolInfo.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "SymbolInfo.h"
+
+
+SymbolInfo::SymbolInfo(target_addr_t address, target_size_t size, uint32 type,
+	const BString& name)
+	:
+	fAddress(address),
+	fSize(size),
+	fType(type),
+	fName(name)
+{
+}
+
+
+SymbolInfo::~SymbolInfo()
+{
+}

Added: haiku/trunk/src/apps/debugger/SymbolInfo.h
===================================================================
--- haiku/trunk/src/apps/debugger/SymbolInfo.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/SymbolInfo.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold at gmx.de.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef SYMBOL_INFO_H
+#define SYMBOL_INFO_H
+
+#include <String.h>
+
+#include "ArchitectureTypes.h"
+
+
+class SymbolInfo {
+public:
+								SymbolInfo(target_addr_t address,
+									target_size_t size, uint32 type,
+									const BString& name);
+								~SymbolInfo();
+
+			target_addr_t		Address() const		{ return fAddress; }
+			target_size_t		Size() const		{ return fSize; }
+			uint32				Type() const		{ return fType; }
+			const char*			Name() const		{ return fName.String(); }
+
+private:
+			target_addr_t		fAddress;
+			target_size_t		fSize;
+			uint32				fType;
+			BString				fName;
+};
+
+
+#endif	// SYMBOL_INFO_H

Modified: haiku/trunk/src/apps/debugger/Team.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/Team.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/Team.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -181,6 +181,19 @@
 }
 
 
+Image*
+Team::ImageByAddress(target_addr_t address) const
+{
+	for (ImageList::ConstIterator it = fImages.GetIterator();
+			Image* image = it.Next();) {
+		if (image->ContainsAddress(address))
+			return image;
+	}
+
+	return NULL;
+}
+
+
 const ImageList&
 Team::Images() const
 {

Modified: haiku/trunk/src/apps/debugger/Team.h
===================================================================
--- haiku/trunk/src/apps/debugger/Team.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/Team.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -58,6 +58,7 @@
 			void				RemoveImage(Image* image);
 			bool				RemoveImage(image_id imageID);
 			Image*				ImageByID(image_id imageID) const;
+			Image*				ImageByAddress(target_addr_t address) const;
 			const ImageList&	Images() const;
 
 			void				AddListener(Listener* listener);

Modified: haiku/trunk/src/apps/debugger/arch/Architecture.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/arch/Architecture.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/Architecture.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -5,7 +5,21 @@
 
 #include "Architecture.h"
 
+#include <new>
 
+#include <AutoDeleter.h>
+#include <AutoLocker.h>
+
+#include "CpuState.h"
+#include "DebugInfo.h"
+#include "FunctionDebugInfo.h"
+#include "Image.h"
+#include "ImageDebugInfo.h"
+#include "ImageDebugInfoProvider.h"
+#include "StackTrace.h"
+#include "Team.h"
+
+
 Architecture::Architecture(DebuggerInterface* debuggerInterface)
 	:
 	fDebuggerInterface(debuggerInterface)
@@ -23,3 +37,78 @@
 {
 	return B_OK;
 }
+
+
+status_t
+Architecture::CreateStackTrace(Team* team,
+	ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
+	StackTrace*& _stackTrace)
+{
+	Reference<CpuState> cpuStateReference(cpuState);
+
+	// create the object
+	StackTrace* stackTrace = new(std::nothrow) StackTrace;
+	if (stackTrace == NULL)
+		return B_NO_MEMORY;
+	ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace);
+
+	StackFrame* frame = NULL;
+
+	while (cpuState != NULL) {
+		// get the instruction pointer
+		target_addr_t instructionPointer = cpuState->InstructionPointer();
+		if (instructionPointer == 0)
+			break;
+
+		// get the image for the instruction pointer
+		AutoLocker<Team> teamLocker(team);
+		Image* image = team->ImageByAddress(instructionPointer);
+		Reference<Image> imageReference(image);
+		teamLocker.Unlock();
+
+		// get the image debug info
+		ImageDebugInfo* imageDebugInfo = NULL;
+		if (image != NULL)
+			imageInfoProvider->GetImageDebugInfo(image, imageDebugInfo);
+		Reference<ImageDebugInfo> imageDebugInfoReference(imageDebugInfo, true);
+
+		// get the function
+		FunctionDebugInfo* function = NULL;
+		if (imageDebugInfo != NULL)
+			function = imageDebugInfo->FindFunction(instructionPointer);
+		Reference<FunctionDebugInfo> functionReference(function, true);
+
+		// create the frame using the debug info
+		StackFrame* previousFrame = NULL;
+		CpuState* previousCpuState = NULL;
+		if (function != NULL) {
+			status_t error = function->GetDebugInfo()->CreateFrame(image,
+				function, cpuState, previousFrame, previousCpuState);
+			if (error != B_OK && error != B_UNSUPPORTED)
+				break;
+		}
+
+		// If we have no frame yet, let the architecture create it.
+		if (previousFrame == NULL) {
+			status_t error = CreateStackFrame(image, function, cpuState,
+				previousFrame, previousCpuState);
+			if (error != B_OK)
+				break;
+		}
+
+		cpuStateReference.SetTo(previousCpuState, true);
+
+		previousFrame->SetImage(image);
+		previousFrame->SetFunction(function);
+
+		if (!stackTrace->AddFrame(previousFrame))
+			return B_NO_MEMORY;
+
+		frame = previousFrame;
+		cpuState = previousCpuState;
+	}
+
+	stackTraceDeleter.Detach();
+	_stackTrace = stackTrace;
+	return B_OK;
+}

Modified: haiku/trunk/src/apps/debugger/arch/Architecture.h
===================================================================
--- haiku/trunk/src/apps/debugger/arch/Architecture.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/Architecture.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -12,7 +12,11 @@
 
 class CpuState;
 class DebuggerInterface;
+class FunctionDebugInfo;
+class Image;
+class ImageDebugInfoProvider;
 class Register;
+class StackFrame;
 class StackTrace;
 class Team;
 
@@ -30,8 +34,19 @@
 
 	virtual	status_t			CreateCpuState(const void* cpuStateData,
 									size_t size, CpuState*& _state) = 0;
-	virtual	status_t			CreateStackTrace(Team* team, CpuState* cpuState,
-									StackTrace*& _stackTrace) = 0;
+	virtual	status_t			CreateStackFrame(Image* image,
+									FunctionDebugInfo* function,
+									CpuState* cpuState,
+									StackFrame*& _previousFrame,
+									CpuState*& _previousCpuState) = 0;
+										// returns reference to previous frame
+										// and CPU state; returned CPU state
+										// can be NULL
+
+			status_t			CreateStackTrace(Team* team,
+									ImageDebugInfoProvider* imageInfoProvider,
+									CpuState* cpuState,
+									StackTrace*& _stackTrace);
 										// team is not locked
 
 protected:

Modified: haiku/trunk/src/apps/debugger/arch/ArchitectureTypes.h
===================================================================
--- haiku/trunk/src/apps/debugger/arch/ArchitectureTypes.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/ArchitectureTypes.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -7,6 +7,7 @@
 
 
 typedef uint64 target_addr_t;
+typedef uint64 target_size_t;
 
 
 

Modified: haiku/trunk/src/apps/debugger/arch/CpuState.h
===================================================================
--- haiku/trunk/src/apps/debugger/arch/CpuState.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/CpuState.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -10,7 +10,9 @@
 #include <Referenceable.h>
 #include <Variant.h>
 
+#include "ArchitectureTypes.h"
 
+
 class Register;
 
 
@@ -18,6 +20,7 @@
 public:
 	virtual						~CpuState();
 
+	virtual	target_addr_t		InstructionPointer() const = 0;
 	virtual	bool				GetRegisterValue(const Register* reg,
 									BVariant& _value) = 0;
 };

Modified: haiku/trunk/src/apps/debugger/arch/StackFrame.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/arch/StackFrame.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/StackFrame.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -5,7 +5,68 @@
 
 #include "StackFrame.h"
 
+#include "CpuState.h"
+#include "FunctionDebugInfo.h"
+#include "Image.h"
 
+
+StackFrame::StackFrame(stack_frame_type type, CpuState* cpuState,
+	target_addr_t frameAddress)
+	:
+	fType(type),
+	fCpuState(cpuState),
+	fFrameAddress(frameAddress),
+	fReturnAddress(0),
+	fImage(NULL),
+	fFunction(NULL)
+{
+	fCpuState->AddReference();
+}
+
+
 StackFrame::~StackFrame()
 {
+	SetImage(NULL);
+	SetFunction(NULL);
+	fCpuState->RemoveReference();
 }
+
+
+target_addr_t
+StackFrame::InstructionPointer() const
+{
+	return fCpuState->InstructionPointer();
+}
+
+
+void
+StackFrame::SetReturnAddress(target_addr_t address)
+{
+	fReturnAddress = address;
+}
+
+
+void
+StackFrame::SetImage(Image* image)
+{
+	if (fImage != NULL)
+		fImage->RemoveReference();
+
+	fImage = image;
+
+	if (fImage != NULL)
+		fImage->AddReference();
+}
+
+
+void
+StackFrame::SetFunction(FunctionDebugInfo* function)
+{
+	if (fFunction != NULL)
+		fFunction->RemoveReference();
+
+	fFunction = function;
+
+	if (fFunction != NULL)
+		fFunction->AddReference();
+}

Modified: haiku/trunk/src/apps/debugger/arch/StackFrame.h
===================================================================
--- haiku/trunk/src/apps/debugger/arch/StackFrame.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/StackFrame.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -8,7 +8,6 @@
 #include <OS.h>
 
 #include <Referenceable.h>
-#include <util/DoublyLinkedList.h>
 
 #include "ArchitectureTypes.h"
 
@@ -22,25 +21,39 @@
 
 
 class CpuState;
+class Image;
+class FunctionDebugInfo;
 
 
-class StackFrame : public Referenceable,
-	public DoublyLinkedListLinkImpl<StackFrame> {
+class StackFrame : public Referenceable {
 public:
-	virtual						~StackFrame();
+								StackFrame(stack_frame_type type,
+									CpuState* cpuState,
+									target_addr_t frameAddress);
+								~StackFrame();
 
-	virtual	stack_frame_type	Type() const = 0;
+			stack_frame_type	Type() const			{ return fType; }
+			CpuState*			GetCpuState() const		{ return fCpuState; }
+			target_addr_t		InstructionPointer() const;
+			target_addr_t		FrameAddress() const { return fFrameAddress; }
 
-	virtual	CpuState*			GetCpuState() const = 0;
+			target_addr_t		ReturnAddress() const { return fReturnAddress; }
+			void				SetReturnAddress(target_addr_t address);
 
-	virtual	target_addr_t		InstructionPointer() const = 0;
-	virtual	target_addr_t		FrameAddress() const = 0;
-	virtual	target_addr_t		ReturnAddress() const = 0;
-	virtual	target_addr_t		PreviousFrameAddress() const = 0;
-};
+			Image*				GetImage() const		{ return fImage; }
+			void				SetImage(Image* image);
 
+			FunctionDebugInfo*	Function() const		{ return fFunction; }
+			void				SetFunction(FunctionDebugInfo* function);
 
-typedef DoublyLinkedList<StackFrame> StackFrameList;
+private:
+			stack_frame_type	fType;
+			CpuState*			fCpuState;
+			target_addr_t		fFrameAddress;
+			target_addr_t		fReturnAddress;
+			Image*				fImage;
+			FunctionDebugInfo*	fFunction;
+};
 
 
 #endif	// STACK_FRAME_H

Modified: haiku/trunk/src/apps/debugger/arch/StackTrace.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/arch/StackTrace.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/StackTrace.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -13,13 +13,31 @@
 
 StackTrace::~StackTrace()
 {
-	while (StackFrame* frame = fStackFrames.RemoveHead())
+	for (int32 i = 0; StackFrame* frame = FrameAt(i); i++)
 		frame->RemoveReference();
 }
 
 
-void
+bool
 StackTrace::AddFrame(StackFrame* frame)
 {
-	fStackFrames.Add(frame);
+	if (fStackFrames.AddItem(frame))
+		return true;
+
+	frame->RemoveReference();
+	return false;
 }
+
+
+int32
+StackTrace::CountFrames() const
+{
+	return fStackFrames.CountItems();
+}
+
+
+StackFrame*
+StackTrace::FrameAt(int32 index) const
+{
+	return fStackFrames.ItemAt(index);
+}

Modified: haiku/trunk/src/apps/debugger/arch/StackTrace.h
===================================================================
--- haiku/trunk/src/apps/debugger/arch/StackTrace.h	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/StackTrace.h	2009-06-20 17:20:49 UTC (rev 31142)
@@ -5,6 +5,8 @@
 #ifndef STACK_TRACE_H
 #define STACK_TRACE_H
 
+#include <ObjectList.h>
+
 #include "StackFrame.h"
 
 
@@ -13,15 +15,14 @@
 								StackTrace();
 	virtual						~StackTrace();
 
-			void				AddFrame(StackFrame* frame);
-									// takes over reference
+			bool				AddFrame(StackFrame* frame);
+									// takes over reference (also on error)
 
-			const StackFrameList& Frames() const	{ return fStackFrames; }
+			int32				CountFrames() const;
+			StackFrame*			FrameAt(int32 index) const;
 
-			StackFrame*			TopFrame() const
-									{ return fStackFrames.Head(); }
-			StackFrame*			BottomFrame() const
-									{ return fStackFrames.Tail(); }
+private:
+			typedef BObjectList<StackFrame> StackFrameList;
 
 private:
 			StackFrameList		fStackFrames;

Modified: haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp	2009-06-20 16:49:31 UTC (rev 31141)
+++ haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp	2009-06-20 17:20:49 UTC (rev 31142)
@@ -11,8 +11,7 @@
 
 #include "CpuStateX86.h"
 #include "DebuggerInterface.h"
-#include "StackFrameX86.h"
-#include "StackTrace.h"
+#include "StackFrame.h"
 
 
 ArchitectureX86::ArchitectureX86(DebuggerInterface* debuggerInterface)
@@ -104,59 +103,38 @@
 
 
 status_t
-ArchitectureX86::CreateStackTrace(Team* team, CpuState* _cpuState,
-	StackTrace*& _stackTrace)
+ArchitectureX86::CreateStackFrame(Image* image, FunctionDebugInfo* function,
+	CpuState* _cpuState, StackFrame*& _previousFrame,
+	CpuState*& _previousCpuState)
 {
 	CpuStateX86* cpuState = dynamic_cast<CpuStateX86*>(_cpuState);
 
-	// create the object
-	StackTrace* stackTrace = new(std::nothrow) StackTrace;
-	if (stackTrace == NULL)
-		return B_NO_MEMORY;
-	ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace);
+	uint32 framePointer = cpuState->IntRegisterValue(X86_REGISTER_EBP);
 

[... truncated: 926 lines follow ...]



More information about the Haiku-commits mailing list