Skip to content

Commit

Permalink
Print parameters/local variables if available..
Browse files Browse the repository at this point in the history
- If debug information is present, then for each stack frame we now
  also dump all function parameters and local variables and their
  respective values, as well as their first level of children if
  applicable.
  • Loading branch information
anevilyak committed Dec 9, 2012
1 parent 84a00bf commit ad99f88
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 1 deletion.
137 changes: 136 additions & 1 deletion src/apps/debugger/controllers/DebugReportGenerator.cpp
Expand Up @@ -26,15 +26,22 @@
#include "StringUtils.h"
#include "Team.h"
#include "Thread.h"
#include "Type.h"
#include "UiUtils.h"
#include "Value.h"
#include "ValueLoader.h"
#include "ValueLocation.h"
#include "ValueNode.h"
#include "ValueNodeManager.h"


DebugReportGenerator::DebugReportGenerator(::Team* team)
:
BLooper("DebugReportGenerator"),
fTeam(team),
fArchitecture(team->GetArchitecture()),
fTeamDataSem(-1)
fTeamDataSem(-1),
fNodeManager(NULL)
{
fTeam->AddListener(this);
fArchitecture->AcquireReference();
Expand All @@ -45,6 +52,8 @@ DebugReportGenerator::~DebugReportGenerator()
{
fTeam->RemoveListener(this);
fArchitecture->ReleaseReference();
if (fNodeManager != NULL)
fNodeManager->ReleaseReference();
}


Expand All @@ -55,6 +64,10 @@ DebugReportGenerator::Init()
if (fTeamDataSem < B_OK)
return fTeamDataSem;

fNodeManager = new(std::nothrow) ValueNodeManager();
if (fNodeManager == NULL)
return B_NO_MEMORY;

Run();

return B_OK;
Expand Down Expand Up @@ -285,6 +298,23 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,
sizeof(functionName)));

_output << data;
if (frame->CountParameters() == 0
&& frame->CountLocalVariables() == 0) {
continue;
}

_output << "\t\t\tVariables:\n";
status_t result = fNodeManager->SetStackFrame(thread, frame);
if (result != B_OK)
continue;

ValueNodeContainer* container = fNodeManager->GetContainer();
AutoLocker<ValueNodeContainer> containerLocker(container);
for (int32 i = 0; i < container->CountChildren(); i++) {
ValueNodeChild* child = container->ChildAt(i);
_DumpValueNode(_output, frame, child);
}
_output << "\n";
}

_output << "\n\t\tRegisters:\n";
Expand All @@ -304,3 +334,108 @@ DebugReportGenerator::_DumpDebuggedThreadInfo(BString& _output,

return B_OK;
}


status_t
DebugReportGenerator::_DumpValueNode(BString& _output, StackFrame* frame,
ValueNodeChild* child, bool recurse)
{
status_t result = _ResolveLocationIfNeeded(child, frame);
if (result != B_OK)
return result;

_output << "\t\t\t";
if (!recurse)
_output << "\t";
_output << child->Name() << ": ";

ValueNode* node = child->Node();
if (node->LocationAndValueResolutionState() == VALUE_NODE_UNRESOLVED) {
if (_ResolveValueIfNeeded(node, frame) == B_OK) {
Value* value = node->GetValue();
if (value != NULL) {
BString valueData;
value->ToString(valueData);
_output << valueData;
} else
_output << "Unavailable";
} else
_output << "Unknown";
}
if (recurse && node->CountChildren() != 0)
_output << " {";

_output << "\n";

if (recurse) {
if (node->CountChildren() == 0)
return B_OK;

if (node->CountChildren() == 1
&& node->GetType()->Kind() == TYPE_ADDRESS
&& node->ChildAt(0)->GetType()->Kind() == TYPE_COMPOUND) {
// for the case of a pointer to a compound type,
// we want to hide the intervening compound node and print
// the children directly.
status_t result = fNodeManager->AddChildNodes(node->ChildAt(0));
if (result == B_OK) {
result = _ResolveLocationIfNeeded(node->ChildAt(0), frame);
if (result == B_OK) {
node = node->ChildAt(0)->Node();
// attempt to resolve the value here since the node's
// representation may requires its value to be resolved
// before its children can be created
result = _ResolveValueIfNeeded(node, frame);
}
}
}

for (int32 i = 0; i < node->CountChildren(); i++) {
if (fNodeManager->AddChildNodes(node->ChildAt(i)) != B_OK)
continue;

// don't dump compound nodes since we won't traverse into
// them anyways and their top level node has no interesting
// information.
if (node->ChildAt(i)->GetType()->Kind() != TYPE_COMPOUND)
_DumpValueNode(_output, frame, node->ChildAt(i), false);
}
_output << "\t\t\t}\n";
}

return B_OK;
}


status_t
DebugReportGenerator::_ResolveValueIfNeeded(ValueNode* node, StackFrame* frame)
{
ValueLocation* location = NULL;
Value* value = NULL;
ValueLoader loader(fTeam->GetArchitecture(), fTeam->GetTeamMemory(),
fTeam->GetTeamTypeInformation(), frame->GetCpuState());
status_t result = node->ResolvedLocationAndValue(&loader, location,
value);
node->SetLocationAndValue(location, value, result);
if (location != NULL)
location->ReleaseReference();
if (value != NULL)
value->ReleaseReference();

return result;
}


status_t
DebugReportGenerator::_ResolveLocationIfNeeded(ValueNodeChild* child,
StackFrame* frame)
{
ValueLocation* location = NULL;
ValueLoader loader(fTeam->GetArchitecture(), fTeam->GetTeamMemory(),
fTeam->GetTeamTypeInformation(), frame->GetCpuState());
status_t result = child->ResolveLocation(&loader, location);
child->SetLocation(location, result);
if (location != NULL)
location->ReleaseReference();
return result;
}
14 changes: 14 additions & 0 deletions src/apps/debugger/controllers/DebugReportGenerator.h
Expand Up @@ -14,8 +14,13 @@
class entry_ref;
class Architecture;
class BString;
class StackFrame;
class Team;
class Thread;
class Value;
class ValueNode;
class ValueNodeChild;
class ValueNodeManager;


class DebugReportGenerator : public BLooper, public Team::Listener {
Expand All @@ -39,11 +44,20 @@ class DebugReportGenerator : public BLooper, public Team::Listener {
status_t _DumpRunningThreads(BString& output);
status_t _DumpDebuggedThreadInfo(BString& output,
::Thread* thread);
status_t _DumpValueNode(BString& output,
StackFrame* frame, ValueNodeChild* child,
bool recurse = true);

status_t _ResolveLocationIfNeeded(ValueNodeChild* child,
StackFrame* frame);
status_t _ResolveValueIfNeeded(ValueNode* node,
StackFrame* frame);

private:
::Team* fTeam;
Architecture* fArchitecture;
sem_id fTeamDataSem;
ValueNodeManager* fNodeManager;
};

#endif // DEBUG_REPORT_GENERATOR_H

0 comments on commit ad99f88

Please sign in to comment.