[Haiku-commits] r31229 - in haiku/trunk/src/apps/debugger: arch arch/x86 gui/team_window model

bonefish at BerliOS bonefish at mail.berlios.de
Thu Jun 25 00:10:09 CEST 2009


Author: bonefish
Date: 2009-06-25 00:10:07 +0200 (Thu, 25 Jun 2009)
New Revision: 31229
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31229&view=rev

Modified:
   haiku/trunk/src/apps/debugger/arch/Architecture.cpp
   haiku/trunk/src/apps/debugger/arch/Architecture.h
   haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp
   haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.h
   haiku/trunk/src/apps/debugger/gui/team_window/SourceView.cpp
   haiku/trunk/src/apps/debugger/model/StackFrame.cpp
   haiku/trunk/src/apps/debugger/model/StackFrame.h
Log:
* Changes that should already have been part of r31228: StackFrame and
  SourceView.
* Fixed the information flow problem in Architecture::CreateStackTrace()/
  ArchitectureX86::UpdateStackCpuState() by introducing a virtual
  UpdateStackFrameCpuState() which allows the architecture to update the CPU
  state it generated before after the function the state belongs to is known.
  That's where moving the instruction pointer to the previous instruction
  happens now.


Modified: haiku/trunk/src/apps/debugger/arch/Architecture.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/arch/Architecture.cpp	2009-06-24 16:37:11 UTC (rev 31228)
+++ haiku/trunk/src/apps/debugger/arch/Architecture.cpp	2009-06-24 22:10:07 UTC (rev 31229)
@@ -52,6 +52,7 @@
 		return B_NO_MEMORY;
 	ObjectDeleter<StackTrace> stackTraceDeleter(stackTrace);
 
+	bool architectureFrame = false;
 	StackFrame* frame = NULL;
 
 	while (cpuState != NULL) {
@@ -78,6 +79,11 @@
 			function = imageDebugInfo->FindFunction(instructionPointer);
 		Reference<FunctionDebugInfo> functionReference(function, true);
 
+		// If the last frame had been created by the architecture, we update the
+		// CPU state.
+		if (architectureFrame)
+			UpdateStackFrameCpuState(frame, image, function, cpuState);
+
 		// create the frame using the debug info
 		StackFrame* previousFrame = NULL;
 		CpuState* previousCpuState = NULL;
@@ -94,7 +100,9 @@
 				frame == NULL, previousFrame, previousCpuState);
 			if (error != B_OK)
 				break;
-		}
+			architectureFrame = true;
+		} else
+			architectureFrame = false;
 
 		cpuStateReference.SetTo(previousCpuState, true);
 

Modified: haiku/trunk/src/apps/debugger/arch/Architecture.h
===================================================================
--- haiku/trunk/src/apps/debugger/arch/Architecture.h	2009-06-24 16:37:11 UTC (rev 31228)
+++ haiku/trunk/src/apps/debugger/arch/Architecture.h	2009-06-24 22:10:07 UTC (rev 31229)
@@ -43,6 +43,14 @@
 										// returns reference to previous frame
 										// and CPU state; returned CPU state
 										// can be NULL
+	virtual	void				UpdateStackFrameCpuState(
+									const StackFrame* frame,
+									Image* previousImage,
+									FunctionDebugInfo* previousFunction,
+									CpuState* previousCpuState) = 0;
+										// Called after a CreateStackFrame()
+										// with the image/function corresponding
+										// to the CPU state.
 	virtual	status_t			DisassembleCode(FunctionDebugInfo* function,
 									const void* buffer, size_t bufferSize,
 									SourceCode*& _sourceCode) = 0;

Modified: haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp	2009-06-24 16:37:11 UTC (rev 31228)
+++ haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.cpp	2009-06-24 22:10:07 UTC (rev 31229)
@@ -127,35 +127,9 @@
 		frameType = STACK_FRAME_TYPE_SYSCALL;
 		eip -= 2;
 			// int 99, sysenter, and syscall all are 2 byte instructions
-	} else {
+	} else
 		frameType = STACK_FRAME_TYPE_STANDARD;
 
-		// If this is not a top-frame, we offset eip to the previous (calling)
-		// instruction.
-		if (!isTopFrame && function != NULL && eip > function->Address()) {
-			size_t bufferSize = eip - function->Address();
-			void* buffer = malloc(bufferSize);
-			if (buffer != NULL) {
-				ssize_t bytesRead = fDebuggerInterface->ReadMemory(
-					function->Address(), buffer, bufferSize);
-				if (bytesRead == (ssize_t)bufferSize) {
-					DisassemblerX86 disassembler;
-					target_addr_t instructionAddress;
-					target_size_t instructionSize;
-					if (disassembler.Init(function->Address(),
-							buffer, bufferSize) == B_OK
-						&& disassembler.GetPreviousInstruction(eip,
-							instructionAddress, instructionSize) == B_OK) {
-						eip -= instructionSize;
-						cpuState->SetIntRegister(X86_REGISTER_EIP, eip);
-					}
-				}
-
-				free(buffer);
-			}
-		}
-	}
-
 	// create the stack frame
 	StackFrame* frame = new(std::nothrow) StackFrame(frameType, cpuState,
 		framePointer, eip);
@@ -176,11 +150,6 @@
 		frame->SetReturnAddress(frameData[1]);
 		previousCpuState->SetIntRegister(X86_REGISTER_EBP, frameData[0]);
 		previousCpuState->SetIntRegister(X86_REGISTER_EIP, frameData[1]);
-			// TODO: Actually it's the instruction before! We're currently
-			// offsetting it at the beginning of this method, but that's not
-			// correct, since for the previous stack frame there could be more
-			// debug info. Problem is that we don't have the function for the
-			// previous stack frame available at this point.
 	}
 
 	_previousFrame = frameReference.Detach();
@@ -189,6 +158,47 @@
 }
 
 
+void
+ArchitectureX86::UpdateStackFrameCpuState(const StackFrame* frame,
+	Image* previousImage, FunctionDebugInfo* previousFunction,
+	CpuState* previousCpuState)
+{
+	// This is not a top frame, so we want to offset eip to the previous
+	// (calling) instruction.
+	CpuStateX86* cpuState = dynamic_cast<CpuStateX86*>(previousCpuState);
+
+	// get eip
+	uint32 eip = cpuState->IntRegisterValue(X86_REGISTER_EIP);
+	if (previousFunction == NULL || eip <= previousFunction->Address())
+		return;
+	target_addr_t functionAddresss = previousFunction->Address();
+
+	// allocate a buffer for the function code to disassemble
+	size_t bufferSize = eip - functionAddresss;
+	void* buffer = malloc(bufferSize);
+	if (buffer == NULL)
+		return;
+	MemoryDeleter bufferDeleter(buffer);
+
+	// read the code
+	ssize_t bytesRead = fDebuggerInterface->ReadMemory(functionAddresss, buffer,
+		bufferSize);
+	if (bytesRead != (ssize_t)bufferSize)
+		return;
+
+	// disassemble to get the previous instruction
+	DisassemblerX86 disassembler;
+	target_addr_t instructionAddress;
+	target_size_t instructionSize;
+	if (disassembler.Init(functionAddresss, buffer, bufferSize) == B_OK
+		&& disassembler.GetPreviousInstruction(eip, instructionAddress,
+			instructionSize) == B_OK) {
+		eip -= instructionSize;
+		cpuState->SetIntRegister(X86_REGISTER_EIP, eip);
+	}
+}
+
+
 status_t
 ArchitectureX86::DisassembleCode(FunctionDebugInfo* function,
 	const void* buffer, size_t bufferSize, SourceCode*& _sourceCode)

Modified: haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.h
===================================================================
--- haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.h	2009-06-24 16:37:11 UTC (rev 31228)
+++ haiku/trunk/src/apps/debugger/arch/x86/ArchitectureX86.h	2009-06-24 22:10:07 UTC (rev 31229)
@@ -28,6 +28,11 @@
 									CpuState* cpuState, bool isTopFrame,
 									StackFrame*& _previousFrame,
 									CpuState*& _previousCpuState);
+	virtual	void				UpdateStackFrameCpuState(
+									const StackFrame* frame,
+									Image* previousImage,
+									FunctionDebugInfo* previousFunction,
+									CpuState* previousCpuState);
 	virtual	status_t			DisassembleCode(FunctionDebugInfo* function,
 									const void* buffer, size_t bufferSize,
 									SourceCode*& _sourceCode);

Modified: haiku/trunk/src/apps/debugger/gui/team_window/SourceView.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/gui/team_window/SourceView.cpp	2009-06-24 16:37:11 UTC (rev 31228)
+++ haiku/trunk/src/apps/debugger/gui/team_window/SourceView.cpp	2009-06-24 22:10:07 UTC (rev 31229)
@@ -601,8 +601,11 @@
 			if (line >= (uint32)LineCount())
 				continue;
 
+			bool isTopFrame = i == 0
+				&& frame->Type() != STACK_FRAME_TYPE_SYSCALL;
+
 			Marker* marker = new(std::nothrow) InstructionPointerMarker(
-				line, i == 0, frame == fStackFrame);
+				line, isTopFrame, frame == fStackFrame);
 			if (marker == NULL || !fIPMarkers.AddItem(marker)) {
 				delete marker;
 				break;

Modified: haiku/trunk/src/apps/debugger/model/StackFrame.cpp
===================================================================
--- haiku/trunk/src/apps/debugger/model/StackFrame.cpp	2009-06-24 16:37:11 UTC (rev 31228)
+++ haiku/trunk/src/apps/debugger/model/StackFrame.cpp	2009-06-24 22:10:07 UTC (rev 31229)
@@ -15,11 +15,12 @@
 
 
 StackFrame::StackFrame(stack_frame_type type, CpuState* cpuState,
-	target_addr_t frameAddress)
+	target_addr_t frameAddress, target_addr_t instructionPointer)
 	:
 	fType(type),
 	fCpuState(cpuState),
 	fFrameAddress(frameAddress),
+	fInstructionPointer(instructionPointer),
 	fReturnAddress(0),
 	fImage(NULL),
 	fFunction(NULL),
@@ -39,13 +40,6 @@
 }
 
 
-target_addr_t
-StackFrame::InstructionPointer() const
-{
-	return fCpuState->InstructionPointer();
-}
-
-
 void
 StackFrame::SetReturnAddress(target_addr_t address)
 {

Modified: haiku/trunk/src/apps/debugger/model/StackFrame.h
===================================================================
--- haiku/trunk/src/apps/debugger/model/StackFrame.h	2009-06-24 16:37:11 UTC (rev 31228)
+++ haiku/trunk/src/apps/debugger/model/StackFrame.h	2009-06-24 22:10:07 UTC (rev 31229)
@@ -14,8 +14,8 @@
 
 
 enum stack_frame_type {
-	STACK_FRAME_TYPE_TOP,			// top-most frame
-	STACK_FRAME_TYPE_STANDARD,		// non-top-most standard frame
+	STACK_FRAME_TYPE_SYSCALL,		// syscall frame
+	STACK_FRAME_TYPE_STANDARD,		// standard frame
 	STACK_FRAME_TYPE_SIGNAL,		// signal handler frame
 	STACK_FRAME_TYPE_FRAMELESS		// dummy frame for a frameless function
 };
@@ -42,14 +42,17 @@
 public:
 								StackFrame(stack_frame_type type,
 									CpuState* cpuState,
-									target_addr_t frameAddress);
+									target_addr_t frameAddress,
+									target_addr_t instructionPointer);
 								~StackFrame();
 
 			stack_frame_type	Type() const			{ return fType; }
 			CpuState*			GetCpuState() const		{ return fCpuState; }
-			target_addr_t		InstructionPointer() const;
 			target_addr_t		FrameAddress() const { return fFrameAddress; }
 
+			target_addr_t		InstructionPointer() const
+									{ return fInstructionPointer; }
+
 			target_addr_t		ReturnAddress() const { return fReturnAddress; }
 			void				SetReturnAddress(target_addr_t address);
 
@@ -76,6 +79,7 @@
 			stack_frame_type	fType;
 			CpuState*			fCpuState;
 			target_addr_t		fFrameAddress;
+			target_addr_t		fInstructionPointer;
 			target_addr_t		fReturnAddress;
 			Image*				fImage;
 			FunctionDebugInfo*	fFunction;




More information about the Haiku-commits mailing list