[nemiver] Don't loop forever on cycles (Closes: #584464)
- From: Dodji Seketeli <dodji src gnome org>
- To: svn-commits-list gnome org
- Subject: [nemiver] Don't loop forever on cycles (Closes: #584464)
- Date: Tue, 2 Jun 2009 17:03:45 -0400 (EDT)
commit 519c0f829a52346443f6d59882c5d63fb4e253a7
Author: Dodji Seketeli <dodji redhat com>
Date: Tue Jun 2 22:11:01 2009 +0200
Don't loop forever on cycles (Closes: #584464)
* src/dbgengine/nmv-i-var-walker.h:
(IVarWalker::set_maximum_member_depth,
IVarWalker::get_maximum_member_depth): New abstract
ifaces.
* src/dbgengine/nmv-var-walker.cc (VarWalker::set_maximum_member_depth,
VarWalker::get_maximum_member_depth): New concrete implementations.
* src/dbgengine/nmv-varobj-walker.cc (VarobjWalker::set_maximum_member_depth,
VarobjWalker::get_maximum_member_depth): Likewise.
(VarobjWalker::on_variable_unfolded_signal: Add a max depth guard to avoid
looping forever on some huge datastructures.
(VarobjWalker::do_walk_variable_real): Likewise. Don't
dereference pointers, otherwise we might cycle forever on
datastructures that have cycles. Make sure to pass the right
variable to the visited_variable_signal.
---
src/dbgengine/nmv-i-var-walker.h | 7 +++-
src/dbgengine/nmv-var-walker.cc | 15 ++++++++
src/dbgengine/nmv-varobj-walker.cc | 65 ++++++++++++++++++++++++++-------
src/persp/dbgperspective/Makefile.am | 3 +-
4 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/src/dbgengine/nmv-i-var-walker.h b/src/dbgengine/nmv-i-var-walker.h
index ade767e..8575659 100644
--- a/src/dbgengine/nmv-i-var-walker.h
+++ b/src/dbgengine/nmv-i-var-walker.h
@@ -87,7 +87,12 @@ public:
/// gets the debugger the walker is connected to
virtual IDebuggerSafePtr get_debugger () const = 0;
-};//end IVarWalker
+
+ /// accessor of the maximum depth of variable members to explore.
+ /// this can prevent inifite recursions.
+ virtual void set_maximum_member_depth (unsigned a_max_depth) = 0;
+ virtual unsigned get_maximum_member_depth () const = 0;
+}; // end IVarWalker
NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/dbgengine/nmv-var-walker.cc b/src/dbgengine/nmv-var-walker.cc
index ba61343..bbd1bad 100644
--- a/src/dbgengine/nmv-var-walker.cc
+++ b/src/dbgengine/nmv-var-walker.cc
@@ -114,6 +114,10 @@ public:
const IDebugger::VariableSafePtr get_variable () const;
IDebuggerSafePtr get_debugger () const ;
+
+ void set_maximum_member_depth (unsigned a_max_depth);
+
+ unsigned get_maximum_member_depth () const;
};//end class VarWalker
void
@@ -318,6 +322,17 @@ VarWalker::get_debugger () const
return m_debugger.do_dynamic_cast<IDebugger> ();
}
+void
+VarWalker::set_maximum_member_depth (unsigned)
+{
+}
+
+unsigned
+VarWalker::get_maximum_member_depth () const
+{
+ return 0;
+}
+
//the dynmod used to instanciate the VarWalker service object
//and return an interface on it.
struct VarWalkerDynMod : public DynamicModule {
diff --git a/src/dbgengine/nmv-varobj-walker.cc b/src/dbgengine/nmv-varobj-walker.cc
index fef2953..462b3b5 100644
--- a/src/dbgengine/nmv-varobj-walker.cc
+++ b/src/dbgengine/nmv-varobj-walker.cc
@@ -27,6 +27,7 @@
#include "nmv-i-var-walker.h"
#include "nmv-gdb-engine.h"
#include "common/nmv-sequence.h"
+#include "nmv-i-lang-trait.h"
using std::list;
using std::map;
@@ -41,8 +42,7 @@ typedef SafePtr<nemiver::GDBEngine, ObjectRef, ObjectUnref> GDBEngineSafePtr;
NEMIVER_BEGIN_NAMESPACE (nemiver)
-const UString VAR_WALKER_COOKIE="var-walker-cookie";
-
+static const unsigned MAX_DEPTH = 256;
class VarobjWalker : public IVarWalker, public sigc::trackable
{
@@ -59,13 +59,17 @@ class VarobjWalker : public IVarWalker, public sigc::trackable
// The count of on going variable unfolding
int m_variable_unfolds;
+ unsigned m_max_depth;
+
VarobjWalker (); // Don't call this constructor.
public:
+
VarobjWalker (DynamicModule *a_dynmod) :
IVarWalker (a_dynmod),
m_do_walk (false),
- m_variable_unfolds (0)
+ m_variable_unfolds (0),
+ m_max_depth (MAX_DEPTH)
{
}
@@ -93,11 +97,17 @@ public:
IDebuggerSafePtr get_debugger () const;
+ void set_maximum_member_depth (unsigned a_max_depth);
+
+ unsigned get_maximum_member_depth () const;
+
void delete_varobj_if_necessary ();
- void do_walk_variable_real (const IDebugger::VariableSafePtr);
+ void do_walk_variable_real (const IDebugger::VariableSafePtr,
+ unsigned a_max_depth);
- void on_variable_unfolded_signal (const IDebugger::VariableSafePtr a_var);
+ void on_variable_unfolded_signal (const IDebugger::VariableSafePtr a_var,
+ unsigned max_depth);
void on_variable_created_signal (const IDebugger::VariableSafePtr a_var);
}; // end class VarobjWalker.
@@ -166,7 +176,7 @@ VarobjWalker::do_walk_variable (const UString &)
THROW ("expecting a non null m_variable!");
}
}
- do_walk_variable_real (m_variable);
+ do_walk_variable_real (m_variable, m_max_depth);
}
@@ -187,6 +197,22 @@ VarobjWalker::get_debugger () const
}
void
+VarobjWalker::set_maximum_member_depth (unsigned a_max_depth)
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ m_max_depth = a_max_depth;
+}
+
+unsigned
+VarobjWalker::get_maximum_member_depth () const
+{
+ LOG_FUNCTION_SCOPE_NORMAL_DD;
+
+ return m_max_depth;
+}
+
+void
VarobjWalker::delete_varobj_if_necessary ()
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -201,18 +227,28 @@ VarobjWalker::delete_varobj_if_necessary ()
}
void
-VarobjWalker::do_walk_variable_real (const IDebugger::VariableSafePtr a_var)
+VarobjWalker::do_walk_variable_real (const IDebugger::VariableSafePtr a_var,
+ unsigned a_max_depth)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
THROW_IF_FAIL (a_var);
- if (a_var->needs_unfolding ()) {
+ LOG_DD ("internal var name: " << a_var->internal_name ()
+ << "depth: " << (int) a_max_depth);
+
+ if (a_max_depth == 0)
+ return;
+
+ if (a_var->needs_unfolding ()
+ && m_debugger->get_language_trait ().is_variable_compound (a_var)) {
LOG_DD ("needs unfolding");
m_variable_unfolds++;
m_debugger->unfold_variable
- (a_var, sigc::mem_fun (*this,
- &VarobjWalker::on_variable_unfolded_signal));
+ (a_var,
+ sigc::bind (sigc::mem_fun (*this,
+ &VarobjWalker::on_variable_unfolded_signal),
+ a_max_depth - 1));
} else if (!a_var->members ().empty ()) {
LOG_DD ("children need visiting");
visited_variable_node_signal ().emit (a_var);
@@ -220,20 +256,21 @@ VarobjWalker::do_walk_variable_real (const IDebugger::VariableSafePtr a_var)
for (it = a_var->members ().begin ();
it != a_var->members ().end ();
++ it) {
- do_walk_variable_real (*it);
+ do_walk_variable_real (*it, a_max_depth - 1);
}
} else {
LOG_DD ("else finished ?. m_variable_unfolds: "
<< (int) m_variable_unfolds);
visited_variable_node_signal ().emit (a_var);
if (m_variable_unfolds == 0)
- visited_variable_signal ().emit (a_var);
+ visited_variable_signal ().emit (m_variable);
}
}
void
-VarobjWalker::on_variable_unfolded_signal (const IDebugger::VariableSafePtr a_var)
+VarobjWalker::on_variable_unfolded_signal (const IDebugger::VariableSafePtr a_var,
+ unsigned a_max_depth)
{
LOG_FUNCTION_SCOPE_NORMAL_DD;
@@ -241,7 +278,7 @@ VarobjWalker::on_variable_unfolded_signal (const IDebugger::VariableSafePtr a_va
m_variable_unfolds--;
visited_variable_node_signal ().emit (a_var);
- do_walk_variable_real (a_var);
+ do_walk_variable_real (a_var, a_max_depth);
if (m_variable_unfolds == 0) {
THROW_IF_FAIL (m_variable);
visited_variable_signal ().emit (m_variable);
diff --git a/src/persp/dbgperspective/Makefile.am b/src/persp/dbgperspective/Makefile.am
index 74d08d5..a81d704 100644
--- a/src/persp/dbgperspective/Makefile.am
+++ b/src/persp/dbgperspective/Makefile.am
@@ -97,7 +97,8 @@ libdbgperspectiveplugin_la_LDFLAGS= -module -avoid-version -Wl,--as-needed
libdbgperspectiveplugin_la_LIBADD= \
@NEMIVERDBGPERSP_LIBS@ \
$(top_builddir)/src/common/libnemivercommon.la \
-$(top_builddir)/src/uicommon/libnemiveruicommon.la
+$(top_builddir)/src/uicommon/libnemiveruicommon.la \
+$(top_builddir)/src/dbgengine/libdebuggerutils.la
INCLUDES= NEMIVERDBGPERSP_CFLAGS@ -DENABLE_NLS=1 -DDATADIR=\"${datadir}\" \
-I$(top_srcdir)/src \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]