[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