hrev44992 adds 5 changesets to branch 'master' old head: adf4c44437c52c3654290af5fe0a33728e7aa7f4 new head: ad99f882d332df8e2ad38587380eaa73f0b63be2 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=ad99f88+%5Eadf4c44 ---------------------------------------------------------------------------- c1034c6: Pull a ValueNodeManager class out of VariableTableModel. - The intention is to have a class which handles the actual management of the variable node graph, creating child nodes and such. This way the GUI, CLI and report generator don't have to each reimplement these low-level parts and can instead concentrate on their relevant representations thereof. 13c04a3: Adapt VariablesView to use the ValueNodeManager. 2c32e74: 64-bit fixes. 84a00bf: Make string size available in value location. ad99f88: Print parameters/local variables if available.. - 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. [ Rene Gollent <anevilyak@xxxxxxxxx> ] ---------------------------------------------------------------------------- 8 files changed, 491 insertions(+), 243 deletions(-) src/apps/debugger/Jamfile | 1 + .../controllers/DebugReportGenerator.cpp | 137 ++++++++- .../debugger/controllers/DebugReportGenerator.h | 14 + .../debugger/debug_managers/ValueNodeManager.cpp | 234 +++++++++++++++ .../debugger/debug_managers/ValueNodeManager.h | 54 ++++ .../gui/team_window/VariablesView.cpp | 286 +++---------------- .../value/value_nodes/CStringValueNode.cpp | 6 + .../value/value_nodes/VariableValueNodeChild.h | 2 + ############################################################################ Commit: c1034c63fbb8debcff35b726c9aa3c48bbd8d2b2 URL: http://cgit.haiku-os.org/haiku/commit/?id=c1034c6 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sat Dec 8 02:15:38 2012 UTC Pull a ValueNodeManager class out of VariableTableModel. - The intention is to have a class which handles the actual management of the variable node graph, creating child nodes and such. This way the GUI, CLI and report generator don't have to each reimplement these low-level parts and can instead concentrate on their relevant representations thereof. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index ac597c6..1eb7571 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -263,6 +263,7 @@ Application Debugger : ValueLoader.cpp ValueNode.cpp ValueNodeContainer.cpp + ValueNodeManager.cpp # value/type_handlers BListTypeHandler.cpp diff --git a/src/apps/debugger/debug_managers/ValueNodeManager.cpp b/src/apps/debugger/debug_managers/ValueNodeManager.cpp new file mode 100644 index 0000000..4dce046 --- /dev/null +++ b/src/apps/debugger/debug_managers/ValueNodeManager.cpp @@ -0,0 +1,234 @@ +/* + * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx. + * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Distributed under the terms of the MIT License. + */ + +#include "ValueNodeManager.h" + +#include "AutoLocker.h" + +#include "StackFrame.h" +#include "Thread.h" +#include "TypeHandlerRoster.h" +#include "ValueNode.h" +#include "Variable.h" +#include "VariableValueNodeChild.h" + + +ValueNodeManager::ValueNodeManager() + : + fContainer(NULL), + fStackFrame(NULL), + fThread(NULL) +{ +} + + +ValueNodeManager::~ValueNodeManager() +{ + SetStackFrame(NULL, NULL); +} + + +status_t +ValueNodeManager::SetStackFrame(Thread* thread, + StackFrame* stackFrame) +{ + if (fContainer != NULL) { + AutoLocker<ValueNodeContainer> containerLocker(fContainer); + + fContainer->RemoveListener(this); + + fContainer->RemoveAllChildren(); + containerLocker.Unlock(); + fContainer->ReleaseReference(); + fContainer = NULL; + } + + fStackFrame = stackFrame; + fThread = thread; + + if (fStackFrame != NULL) { + fContainer = new(std::nothrow) ValueNodeContainer; + if (fContainer == NULL) + return B_NO_MEMORY; + + status_t error = fContainer->Init(); + if (error != B_OK) { + delete fContainer; + fContainer = NULL; + return error; + } + + AutoLocker<ValueNodeContainer> containerLocker(fContainer); + + fContainer->AddListener(this); + + for (int32 i = 0; Variable* variable = fStackFrame->ParameterAt(i); + i++) { + _AddNode(variable); + } + + for (int32 i = 0; Variable* variable + = fStackFrame->LocalVariableAt(i); i++) { + _AddNode(variable); + } + } + + return B_OK; +} + + +bool +ValueNodeManager::AddListener(ValueNodeContainer::Listener* listener) +{ + return fListeners.AddItem(listener); +} + + +void +ValueNodeManager::RemoveListener(ValueNodeContainer::Listener* listener) +{ + fListeners.RemoveItem(listener); +} + + +void +ValueNodeManager::ValueNodeChanged(ValueNodeChild* nodeChild, + ValueNode* oldNode, ValueNode* newNode) +{ + if (fContainer == NULL) + return; + + AutoLocker<ValueNodeContainer> containerLocker(fContainer); + + if (oldNode != NULL) + newNode->CreateChildren(); + + for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) + fListeners.ItemAt(i)->ValueNodeChanged(nodeChild, oldNode, newNode); +} + + +void +ValueNodeManager::ValueNodeChildrenCreated(ValueNode* node) +{ + if (fContainer == NULL) + return; + + for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) + fListeners.ItemAt(i)->ValueNodeChildrenCreated(node); +} + + +void +ValueNodeManager::ValueNodeChildrenDeleted(ValueNode* node) +{ + if (fContainer == NULL) + return; + + for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) + fListeners.ItemAt(i)->ValueNodeChildrenDeleted(node); +} + + +void +ValueNodeManager::ValueNodeValueChanged(ValueNode* valueNode) +{ + if (fContainer == NULL) + return; + + AutoLocker<ValueNodeContainer> containerLocker(fContainer); + + // check whether we know the node + ValueNodeChild* nodeChild = valueNode->NodeChild(); + if (nodeChild == NULL) + return; + + if (valueNode->ChildCreationNeedsValue() + && !valueNode->ChildrenCreated()) { + status_t error = valueNode->CreateChildren(); + if (error != B_OK) + return; + + for (int32 i = 0; i < valueNode->CountChildren(); i++) { + ValueNodeChild* child = valueNode->ChildAt(i); + _CreateValueNode(child); + AddChildNodes(child); + } + } + + for (int32 i = fListeners.CountItems() - 1; i >= 0; i--) + fListeners.ItemAt(i)->ValueNodeValueChanged(valueNode); +} + + +void +ValueNodeManager::_AddNode(Variable* variable) +{ + // create the node child for the variable + ValueNodeChild* nodeChild = new (std::nothrow) VariableValueNodeChild( + variable); + BReference<ValueNodeChild> nodeChildReference(nodeChild, true); + if (nodeChild == NULL || !fContainer->AddChild(nodeChild)) { + delete nodeChild; + return; + } + + // automatically add child nodes for the top level nodes + AddChildNodes(nodeChild); +} + + +status_t +ValueNodeManager::_CreateValueNode(ValueNodeChild* nodeChild) +{ + if (nodeChild->Node() != NULL) + return B_OK; + + // create the node + ValueNode* valueNode; + status_t error; + if (nodeChild->IsInternal()) { + error = nodeChild->CreateInternalNode(valueNode); + } else { + error = TypeHandlerRoster::Default()->CreateValueNode(nodeChild, + nodeChild->GetType(), valueNode); + } + + if (error != B_OK) + return error; + + nodeChild->SetNode(valueNode); + valueNode->ReleaseReference(); + + return B_OK; +} + + +status_t +ValueNodeManager::AddChildNodes(ValueNodeChild* nodeChild) +{ + AutoLocker<ValueNodeContainer> containerLocker(fContainer); + + // create a value node for the value node child, if doesn't have one yet + ValueNode* valueNode = nodeChild->Node(); + if (valueNode == NULL) { + status_t error = _CreateValueNode(nodeChild); + if (error != B_OK) + return error; + valueNode = nodeChild->Node(); + } + + // check if this node requires child creation + // to be deferred until after its location/value have been resolved + if (valueNode->ChildCreationNeedsValue()) + return B_OK; + + // create the children, if not done yet + if (valueNode->ChildrenCreated()) + return B_OK; + + return valueNode->CreateChildren(); +} diff --git a/src/apps/debugger/debug_managers/ValueNodeManager.h b/src/apps/debugger/debug_managers/ValueNodeManager.h new file mode 100644 index 0000000..603648a --- /dev/null +++ b/src/apps/debugger/debug_managers/ValueNodeManager.h @@ -0,0 +1,54 @@ +/* + * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxx. + * Distributed under the terms of the MIT License. + */ +#ifndef VALUE_NODE_MANAGER_H +#define VALUE_NODE_MANAGER_H + +#include <Referenceable.h> + +#include "ValueNodeContainer.h" + +class StackFrame; +class Thread; +class Variable; + + +class ValueNodeManager : public BReferenceable, + private ValueNodeContainer::Listener { +public: + ValueNodeManager(); + virtual ~ValueNodeManager(); + + status_t SetStackFrame(Thread* thread, + StackFrame* frame); + + bool AddListener( + ValueNodeContainer::Listener* listener); + void RemoveListener( + ValueNodeContainer::Listener* listener); + + virtual void ValueNodeChanged(ValueNodeChild* nodeChild, + ValueNode* oldNode, ValueNode* newNode); + virtual void ValueNodeChildrenCreated(ValueNode* node); + virtual void ValueNodeChildrenDeleted(ValueNode* node); + virtual void ValueNodeValueChanged(ValueNode* node); + + ValueNodeContainer* GetContainer() const { return fContainer; }; + + status_t AddChildNodes(ValueNodeChild* nodeChild); + +private: + typedef BObjectList<ValueNodeContainer::Listener> ListenerList; + + void _AddNode(Variable* variable); + status_t _CreateValueNode(ValueNodeChild* nodeChild); + +private: + ValueNodeContainer* fContainer; + StackFrame* fStackFrame; + Thread* fThread; + ListenerList fListeners; +}; + +#endif // VALUE_NODE_MANAGER_H ############################################################################ Commit: 13c04a36b0f40ffc7c6684ce09b51ce5a8ab596e URL: http://cgit.haiku-os.org/haiku/commit/?id=13c04a3 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sat Dec 8 21:13:39 2012 UTC Adapt VariablesView to use the ValueNodeManager. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 8bf7363..7a6f7d9 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -50,7 +50,7 @@ #include "ValueHandlerRoster.h" #include "ValueLocation.h" #include "ValueNode.h" -#include "ValueNodeContainer.h" +#include "ValueNodeManager.h" #include "Variable.h" #include "VariableValueNodeChild.h" #include "VariablesViewState.h" @@ -451,17 +451,10 @@ private: ValueNodeChild* nodeChild, bool isPresentationNode = false, bool isOnlyChild = false); - void _AddNode(Variable* variable); - status_t _CreateValueNode(ValueNodeChild* nodeChild); - status_t _AddChildNodes(ValueNodeChild* nodeChild); - -// ModelNode* _GetNode(Variable* variable, -// TypeComponentPath* path) const; private: Thread* fThread; - StackFrame* fStackFrame; - ValueNodeContainer* fContainer; + ValueNodeManager* fNodeManager; ContainerListener* fContainerListener; NodeList fNodes; NodeTable fNodeTable; @@ -841,8 +834,8 @@ VariablesView::ContainerListener::ModelNodeRestoreViewStateRequested( VariablesView::VariableTableModel::VariableTableModel() : - fStackFrame(NULL), - fContainer(NULL), + fThread(NULL), + fNodeManager(NULL), fContainerListener(NULL), fNodeTable() { @@ -851,13 +844,18 @@ VariablesView::VariableTableModel::VariableTableModel() VariablesView::VariableTableModel::~VariableTableModel() { - SetStackFrame(NULL, NULL); + if (fNodeManager != NULL) + fNodeManager->ReleaseReference(); } status_t VariablesView::VariableTableModel::Init() { + fNodeManager = new(std::nothrow) ValueNodeManager(); + if (fNodeManager == NULL) + return B_NO_MEMORY; + return fNodeTable.Init(); } @@ -870,10 +868,8 @@ VariablesView::VariableTableModel::SetContainerListener( return; if (fContainerListener != NULL) { - if (fContainer != NULL) { - AutoLocker<ValueNodeContainer> containerLocker(fContainer); - fContainer->RemoveListener(fContainerListener); - } + if (fNodeManager != NULL) + fNodeManager->RemoveListener(fContainerListener); fContainerListener->SetModel(NULL); } @@ -883,10 +879,8 @@ VariablesView::VariableTableModel::SetContainerListener( if (fContainerListener != NULL) { fContainerListener->SetModel(this); - if (fContainer != NULL) { - AutoLocker<ValueNodeContainer> containerLocker(fContainer); - fContainer->AddListener(fContainerListener); - } + if (fNodeManager != NULL) + fNodeManager->AddListener(fContainerListener); } } @@ -895,17 +889,9 @@ void VariablesView::VariableTableModel::SetStackFrame(Thread* thread, StackFrame* stackFrame) { - if (fContainer != NULL) { - AutoLocker<ValueNodeContainer> containerLocker(fContainer); - - if (fContainerListener != NULL) - fContainer->RemoveListener(fContainerListener); + fThread = thread; - fContainer->RemoveAllChildren(); - containerLocker.Unlock(); - fContainer->ReleaseReference(); - fContainer = NULL; - } + fNodeManager->SetStackFrame(thread, stackFrame); fNodeTable.Clear(true); @@ -917,38 +903,19 @@ VariablesView::VariableTableModel::SetStackFrame(Thread* thread, NotifyNodesRemoved(TreeTablePath(), 0, count); } - fStackFrame = stackFrame; - fThread = thread; - - if (fStackFrame != NULL) { - fContainer = new(std::nothrow) ValueNodeContainer; - if (fContainer == NULL) - return; - - status_t error = fContainer->Init(); - if (error != B_OK) { - delete fContainer; - fContainer = NULL; - return; - } - - AutoLocker<ValueNodeContainer> containerLocker(fContainer); - - if (fContainerListener != NULL) - fContainer->AddListener(fContainerListener); - - for (int32 i = 0; Variable* variable = fStackFrame->ParameterAt(i); - i++) { - _AddNode(variable); - } + if (stackFrame == NULL) + return; - for (int32 i = 0; Variable* variable - = fStackFrame->LocalVariableAt(i); i++) { - _AddNode(variable); - } + ValueNodeContainer* container = fNodeManager->GetContainer(); + AutoLocker<ValueNodeContainer> containerLocker(container); -// if (!fNodes.IsEmpty()) -// NotifyNodesAdded(TreeTablePath(), 0, fNodes.CountItems()); + for (int32 i = 0; i < container->CountChildren(); i++) { + VariableValueNodeChild* child = dynamic_cast<VariableValueNodeChild *>( + container->ChildAt(i)); + _AddNode(child->GetVariable(), NULL, child); + // top level nodes get their children added immediately + // so those won't invoke our callback hook. Add them directly here. + ValueNodeChildrenCreated(child->Node()); } } @@ -957,19 +924,14 @@ void VariablesView::VariableTableModel::ValueNodeChanged(ValueNodeChild* nodeChild, ValueNode* oldNode, ValueNode* newNode) { - if (fContainer == NULL) - return; - - AutoLocker<ValueNodeContainer> containerLocker(fContainer); + AutoLocker<ValueNodeContainer> containerLocker( + fNodeManager->GetContainer()); ModelNode* modelNode = fNodeTable.Lookup(nodeChild); if (modelNode == NULL) return; - if (oldNode != NULL) { - ValueNodeChildrenDeleted(oldNode); - newNode->CreateChildren(); + if (oldNode != NULL) NotifyNodeChanged(modelNode); - } } @@ -977,10 +939,8 @@ void VariablesView::VariableTableModel::ValueNodeChildrenCreated( ValueNode* valueNode) { - if (fContainer == NULL) - return; - - AutoLocker<ValueNodeContainer> containerLocker(fContainer); + AutoLocker<ValueNodeContainer> containerLocker( + fNodeManager->GetContainer()); // check whether we know the node ValueNodeChild* nodeChild = valueNode->NodeChild(); @@ -1016,10 +976,8 @@ VariablesView::VariableTableModel::ValueNodeChildrenCreated( void VariablesView::VariableTableModel::ValueNodeChildrenDeleted(ValueNode* node) { - if (fContainer == NULL) - return; - - AutoLocker<ValueNodeContainer> containerLocker(fContainer); + AutoLocker<ValueNodeContainer> containerLocker( + fNodeManager->GetContainer()); // check whether we know the node ValueNodeChild* nodeChild = node->NodeChild(); @@ -1058,10 +1016,8 @@ VariablesView::VariableTableModel::ValueNodeChildrenDeleted(ValueNode* node) void VariablesView::VariableTableModel::ValueNodeValueChanged(ValueNode* valueNode) { - if (fContainer == NULL) - return; - - AutoLocker<ValueNodeContainer> containerLocker(fContainer); + AutoLocker<ValueNodeContainer> containerLocker( + fNodeManager->GetContainer()); // check whether we know the node ValueNodeChild* nodeChild = valueNode->NodeChild(); @@ -1072,19 +1028,6 @@ VariablesView::VariableTableModel::ValueNodeValueChanged(ValueNode* valueNode) if (modelNode == NULL) return; - if (valueNode->ChildCreationNeedsValue() - && !valueNode->ChildrenCreated()) { - status_t error = valueNode->CreateChildren(); - if (error != B_OK) - return; - - for (int32 i = 0; i < valueNode->CountChildren(); i++) { - ValueNodeChild* child = valueNode->ChildAt(i); - _CreateValueNode(child); - _AddChildNodes(child); - } - } - // check whether the value actually changed Value* value = valueNode->GetValue(); if (value == modelNode->GetValue()) @@ -1214,11 +1157,8 @@ VariablesView::VariableTableModel::GetValueAt(void* object, int32 columnIndex, void VariablesView::VariableTableModel::NodeExpanded(ModelNode* node) { - if (fContainer == NULL) - return; - - AutoLocker<ValueNodeContainer> containerLocker(fContainer); - + AutoLocker<ValueNodeContainer> containerLocker( + fNodeManager->GetContainer()); // add children of all children // If the node only has a hidden child, add the child's children instead. @@ -1230,7 +1170,7 @@ VariablesView::VariableTableModel::NodeExpanded(ModelNode* node) // add the children for (int32 i = 0; ModelNode* child = node->ChildAt(i); i++) - _AddChildNodes(child->NodeChild()); + fNodeManager->AddChildNodes(child->NodeChild()); } @@ -1365,150 +1305,12 @@ VariablesView::VariableTableModel::_AddNode(Variable* variable, // if the node is hidden, add its children if (node->IsHidden()) - _AddChildNodes(nodeChild); + fNodeManager->AddChildNodes(nodeChild); return B_OK; } -void -VariablesView::VariableTableModel::_AddNode(Variable* variable) -{ - // create the node child for the variable - ValueNodeChild* nodeChild = new (std::nothrow) VariableValueNodeChild( - variable); - BReference<ValueNodeChild> nodeChildReference(nodeChild, true); - if (nodeChild == NULL || !fContainer->AddChild(nodeChild)) { - delete nodeChild; - return; - } - - // create the model node - status_t error = _AddNode(variable, NULL, nodeChild, false); - if (error != B_OK) - return; - - // automatically add child nodes for the top level nodes - _AddChildNodes(nodeChild); -} - - -status_t -VariablesView::VariableTableModel::_CreateValueNode(ValueNodeChild* nodeChild) -{ - if (nodeChild->Node() != NULL) - return B_OK; - - // create the node - ValueNode* valueNode; - status_t error; - if (nodeChild->IsInternal()) { - error = nodeChild->CreateInternalNode(valueNode); - } else { - error = TypeHandlerRoster::Default()->CreateValueNode(nodeChild, - nodeChild->GetType(), valueNode); - } - - if (error != B_OK) - return error; - - nodeChild->SetNode(valueNode); - valueNode->ReleaseReference(); - - return B_OK; -} - - -status_t -VariablesView::VariableTableModel::_AddChildNodes(ValueNodeChild* nodeChild) -{ - // create a value node for the value node child, if doesn't have one yet - ValueNode* valueNode = nodeChild->Node(); - if (valueNode == NULL) { - status_t error = _CreateValueNode(nodeChild); - if (error != B_OK) - return error; - valueNode = nodeChild->Node(); - } - - // check if this node requires child creation - // to be deferred until after its location/value have been resolved - if (valueNode->ChildCreationNeedsValue()) - return B_OK; - - // create the children, if not done yet - if (valueNode->ChildrenCreated()) - return B_OK; - - return valueNode->CreateChildren(); -} - - -//VariablesView::ModelNode* -//VariablesView::VariableTableModel::_GetNode(Variable* variable, -// TypeComponentPath* path) const -//{ -// // find the variable node -// ModelNode* node; -// for (int32 i = 0; (node = fNodes.ItemAt(i)) != NULL; i++) { -// if (node->GetVariable() == variable) -// break; -// } -// if (node == NULL) -// return NULL; -// -// // Now walk along the path, finding the respective child node for each -// // component (might be several components at once). -// int32 componentCount = path->CountComponents(); -// for (int32 i = 0; i < componentCount;) { -// ModelNode* childNode = NULL; -// -// for (int32 k = 0; (childNode = node->ChildAt(k)) != NULL; k++) { -// TypeComponentPath* childPath = childNode->Path(); -// int32 childComponentCount = childPath->CountComponents(); -// if (childComponentCount > componentCount) -// continue; -// -// for (int32 componentIndex = i; -// componentIndex < childComponentCount; componentIndex++) { -// TypeComponent childComponent -// = childPath->ComponentAt(componentIndex); -// TypeComponent pathComponent -// = path->ComponentAt(componentIndex); -// if (childComponent != pathComponent) { -// if (componentIndex + 1 == childComponentCount -// && pathComponent.HasPrefix(childComponent)) { -// // The last child component is a prefix of the -// // corresponding path component. We consider this a -// // match, but need to recheck the component with the -// // next node level. -// childComponentCount--; -// break; -// } -// -// // mismatch -- skip the child -// childNode = NULL; -// break; -// } -// } -// -// if (childNode != NULL) { -// // got a match -- skip the matched children components -// i = childComponentCount; -// break; -// } -// } -// -// if (childNode == NULL) -// return NULL; -// -// node = childNode; -// } -// -// return node; -//} - - bool VariablesView::VariableTableModel::GetTreePath(ModelNode* node, TreeTablePath& _path) const diff --git a/src/apps/debugger/value/value_nodes/VariableValueNodeChild.h b/src/apps/debugger/value/value_nodes/VariableValueNodeChild.h index efa05fe..372057e 100644 --- a/src/apps/debugger/value/value_nodes/VariableValueNodeChild.h +++ b/src/apps/debugger/value/value_nodes/VariableValueNodeChild.h @@ -21,6 +21,8 @@ public: virtual Type* GetType() const; virtual ValueNode* Parent() const; + Variable* GetVariable() const { return fVariable; }; + virtual status_t ResolveLocation(ValueLoader* valueLoader, ValueLocation*& _location); ############################################################################ Commit: 2c32e7436061bec593041522f1419875aaa27660 URL: http://cgit.haiku-os.org/haiku/commit/?id=2c32e74 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sat Dec 8 23:19:12 2012 UTC 64-bit fixes. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 7a6f7d9..dfde0f0 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1139,7 +1139,7 @@ VariablesView::VariableTableModel::GetValueAt(void* object, int32 columnIndex, if (piece.type != VALUE_PIECE_LOCATION_MEMORY) return false; - data.SetToFormat("[@ 0x%llx]", piece.address); + data.SetToFormat("[@ %#" B_PRIx64 "]", piece.address); _value.SetTo(data); return true; } @@ -1212,13 +1212,13 @@ VariablesView::VariableTableModel::GetToolTipForTablePath( BString pieceData; switch (piece.type) { case VALUE_PIECE_LOCATION_MEMORY: - pieceData.SetToFormat("(%ld): Address: 0x%llx, Size: " - "%lld bytes", i, piece.address, piece.size); + pieceData.SetToFormat("(%" B_PRId32 "): Address: %#" B_PRIx64 + ", Size: %" B_PRId64 " bytes", i, piece.address, piece.size); break; case VALUE_PIECE_LOCATION_REGISTER: { Architecture* architecture = fThread->GetTeam()->GetArchitecture(); - pieceData.SetToFormat("(%ld): Register (%s)", + pieceData.SetToFormat("(%" B_PRId32 "): Register (%s)", i, architecture->Registers()[piece.reg].Name()); break; ############################################################################ Commit: 84a00bf8879f6d8e2158e301aff8e3f94d11afa9 URL: http://cgit.haiku-os.org/haiku/commit/?id=84a00bf Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sat Dec 8 23:29:12 2012 UTC Make string size available in value location. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/value/value_nodes/CStringValueNode.cpp b/src/apps/debugger/value/value_nodes/CStringValueNode.cpp index 3b5f90c..f3e4a09 100644 --- a/src/apps/debugger/value/value_nodes/CStringValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/CStringValueNode.cpp @@ -84,6 +84,12 @@ CStringValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, ValuePieceLocation piece; piece.SetToMemory(addressData.ToUInt64()); + error = valueLoader->LoadStringValue(addressData, maxSize, valueData); + if (error != B_OK) + return error; + + piece.size = valueData.Length(); + ValueLocation* stringLocation = new(std::nothrow) ValueLocation( valueLoader->GetArchitecture()->IsBigEndian(), piece); ############################################################################ Revision: hrev44992 Commit: ad99f882d332df8e2ad38587380eaa73f0b63be2 URL: http://cgit.haiku-os.org/haiku/commit/?id=ad99f88 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sun Dec 9 03:30:40 2012 UTC Print parameters/local variables if available.. - 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. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/controllers/DebugReportGenerator.cpp b/src/apps/debugger/controllers/DebugReportGenerator.cpp index 996e67f..d8a16d7 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.cpp +++ b/src/apps/debugger/controllers/DebugReportGenerator.cpp @@ -26,7 +26,13 @@ #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) @@ -34,7 +40,8 @@ DebugReportGenerator::DebugReportGenerator(::Team* team) BLooper("DebugReportGenerator"), fTeam(team), fArchitecture(team->GetArchitecture()), - fTeamDataSem(-1) + fTeamDataSem(-1), + fNodeManager(NULL) { fTeam->AddListener(this); fArchitecture->AcquireReference(); @@ -45,6 +52,8 @@ DebugReportGenerator::~DebugReportGenerator() { fTeam->RemoveListener(this); fArchitecture->ReleaseReference(); + if (fNodeManager != NULL) + fNodeManager->ReleaseReference(); } @@ -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; @@ -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"; @@ -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; +} diff --git a/src/apps/debugger/controllers/DebugReportGenerator.h b/src/apps/debugger/controllers/DebugReportGenerator.h index 1ea4dff..03d7f5c 100644 --- a/src/apps/debugger/controllers/DebugReportGenerator.h +++ b/src/apps/debugger/controllers/DebugReportGenerator.h @@ -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 { @@ -39,11 +44,20 @@ private: 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