- debug_stl: revert to char* for all program symbols (helpful due to preprocessor limitation)
- add stdext and new STL containers to stl_simplify_name - fix internal error when container is uninitialized (now check cntr fields directly instead of calling e.g. size(), which can crash) - all container wrappers now have a consistent interface, no more specialization needed in iterator - fix potential loophole with container adapters - refactor dump_sequence This was SVN commit r2464.
This commit is contained in:
parent
2546abbaf1
commit
cc6abc389a
@ -35,6 +35,17 @@
|
||||
{\
|
||||
src += sizeof(what)-1-1;/* see preincrement rationale*/\
|
||||
}
|
||||
#define STRIP_NESTED(what)\
|
||||
else if(!strncmp(src, (what), sizeof(what)-1))\
|
||||
{\
|
||||
/* remove preceding comma (if present) */\
|
||||
if(src != name && src[-1] == ',')\
|
||||
dst--;\
|
||||
src += sizeof(what)-1;\
|
||||
/* strip everything until trailing > is matched */\
|
||||
debug_assert(nesting == 0);\
|
||||
nesting = 1;\
|
||||
}
|
||||
|
||||
// reduce complicated STL names to human-readable form (in place).
|
||||
// e.g. "std::basic_string<char, char_traits<char>, std::allocator<char> >" =>
|
||||
@ -43,7 +54,7 @@
|
||||
//
|
||||
// see http://www.bdsoft.com/tools/stlfilt.html and
|
||||
// http://www.moderncppdesign.com/publications/better_template_error_messages.html
|
||||
void stl_simplify_name(char* name)
|
||||
char* stl_simplify_name(char* name)
|
||||
{
|
||||
// used when stripping everything inside a < > to continue until
|
||||
// the final bracket is matched (at the original nesting level).
|
||||
@ -112,30 +123,16 @@ void stl_simplify_name(char* name)
|
||||
STRIP("std::char_traits<unsigned short>,")
|
||||
STRIP("std::_Tmap_traits")
|
||||
STRIP("std::_Tset_traits")
|
||||
else if(!strncmp(src, "std::allocator<", 15))
|
||||
{
|
||||
// remove preceding comma (if present)
|
||||
if(src != name && src[-1] == ',')
|
||||
dst--;
|
||||
src += 15;
|
||||
// strip everything until trailing > is matched
|
||||
debug_assert(nesting == 0);
|
||||
nesting = 1;
|
||||
}
|
||||
else if(!strncmp(src, "std::less<", 10))
|
||||
{
|
||||
// remove preceding comma (if present)
|
||||
if(src != name && src[-1] == ',')
|
||||
dst--;
|
||||
src += 10;
|
||||
// strip everything until trailing > is matched
|
||||
debug_assert(nesting == 0);
|
||||
nesting = 1;
|
||||
}
|
||||
STRIP_NESTED("std::allocator<")
|
||||
STRIP_NESTED("std::less<")
|
||||
STRIP_NESTED("stdext::hash_compare<")
|
||||
STRIP("std::")
|
||||
STRIP("stdext::")
|
||||
else
|
||||
*dst++ = c;
|
||||
*dst++ = c;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +184,46 @@ static bool container_valid(const void* front, size_t el_count)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// vector iterators advance by sizeof(value_type) bytes; since we assume the
|
||||
// int specialization, we have to do this ourselves.
|
||||
|
||||
// deque iterator operator* depends on el_size
|
||||
|
||||
// map iterator operator++ depends on el_size
|
||||
|
||||
/*
|
||||
template<class T> class GenericContainer : public T
|
||||
{
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
if(!container_valid(&front(), el_count(el_size)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t el_count(size_t el_size) const
|
||||
{
|
||||
UNUSED(el_size);
|
||||
return size();
|
||||
}
|
||||
|
||||
class iter : public T::const_iterator
|
||||
{
|
||||
public:
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
++(*this);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
//
|
||||
// standard containers
|
||||
//
|
||||
@ -209,10 +246,7 @@ class Any_deque : public std::deque<int>
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
// note: front() fails on empty deques, so don't use that if
|
||||
// the container is empty (which must not be reported as invalid)
|
||||
const size_t el_count_ = el_count(el_size);
|
||||
if(el_count_ && !container_valid(&front(), el_count_))
|
||||
if(!container_valid(_Map, _Mysize))
|
||||
return false;
|
||||
|
||||
#if STL_DINKUMWARE != 0
|
||||
@ -238,20 +272,23 @@ public:
|
||||
class iter : public const_iterator
|
||||
{
|
||||
public:
|
||||
const u8* deref(size_t el_size)
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
Any_deque* d = (Any_deque*)_Mycont;
|
||||
return d->get_item(_Myoff, el_size);
|
||||
const u8* p = d->get_item(_Myoff, el_size);
|
||||
++(*this);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class Any_list: public std::list<int>
|
||||
|
||||
class Any_list : public std::list<int>
|
||||
{
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
if(!container_valid(&front(), el_count(el_size)))
|
||||
if(!container_valid(_Myhead, _Mysize))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -261,8 +298,20 @@ public:
|
||||
UNUSED(el_size);
|
||||
return size();
|
||||
}
|
||||
|
||||
class iter : public const_iterator
|
||||
{
|
||||
public:
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
++(*this);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Any_map : public std::map<int,int>
|
||||
{
|
||||
// return reference to the given node's nil flag.
|
||||
@ -280,8 +329,7 @@ class Any_map : public std::map<int,int>
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
const_iterator it = begin();
|
||||
if(!container_valid(&*it, el_count(el_size)))
|
||||
if(!container_valid(_Myhead, _Mysize))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -298,12 +346,13 @@ public:
|
||||
{
|
||||
public:
|
||||
|
||||
// move to next node (i.e. larger value)
|
||||
void advance(size_t el_size)
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
|
||||
// end() shouldn't be incremented, don't move
|
||||
if(_Isnil(_Ptr, el_size))
|
||||
return;
|
||||
return p;
|
||||
|
||||
// return smallest (leftmost) node of right subtree
|
||||
_Nodeptr _Pnode = _Right(_Ptr);
|
||||
@ -320,6 +369,8 @@ public:
|
||||
_Ptr = _Pnode; // ==> parent while right subtree
|
||||
}
|
||||
_Ptr = _Pnode;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
};
|
||||
@ -330,13 +381,13 @@ class Any_multimap : public Any_map
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
class Any_set: public std::set<int>
|
||||
{
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
const_iterator it = begin();
|
||||
if(!container_valid(&*it, el_count(el_size)))
|
||||
if(!container_valid(_Myhead, _Mysize))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -346,21 +397,31 @@ public:
|
||||
UNUSED(el_size);
|
||||
return size();
|
||||
}
|
||||
|
||||
class iter : public const_iterator
|
||||
{
|
||||
public:
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
++(*this);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Any_multiset: public Any_set
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
class Any_vector: public std::vector<int>
|
||||
{
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
const size_t el_count_ = el_count(el_size);
|
||||
// note: front() will be 0 if container is empty, but
|
||||
// that must not be reported as invalid.
|
||||
if(el_count_ && !container_valid(&front(), el_count_))
|
||||
if(!container_valid(_Myfirst, _Mylast-_Myfirst))
|
||||
return false;
|
||||
// more elements reported than reserved
|
||||
if(size() > capacity())
|
||||
@ -380,26 +441,30 @@ public:
|
||||
return size() * 4 / el_size;
|
||||
}
|
||||
|
||||
class iter;
|
||||
friend class iter;
|
||||
class iter : public const_iterator
|
||||
{
|
||||
public:
|
||||
|
||||
// move to next item
|
||||
void advance(size_t el_size)
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
_Myptr = (_Tptr)((u8*)_Myptr + el_size);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Any_basic_string : public std::string
|
||||
{
|
||||
const void* ptr(size_t el_size) const
|
||||
{
|
||||
return _Myres <= (16/el_size)-1? _Bx._Buf : _Bx._Ptr;
|
||||
}
|
||||
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
if(!container_valid(c_str(), el_count(el_size)))
|
||||
if(!container_valid(ptr(el_size), _Mysize))
|
||||
return false;
|
||||
#if STL_DINKUMWARE != 0
|
||||
// less than the small buffer reserved - impossible
|
||||
@ -417,6 +482,17 @@ public:
|
||||
UNUSED(el_size);
|
||||
return size();
|
||||
}
|
||||
|
||||
class iter : public const_iterator
|
||||
{
|
||||
public:
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
++(*this);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -429,24 +505,27 @@ class Any_queue : public Any_deque
|
||||
{
|
||||
};
|
||||
|
||||
// we assume this adapter was instantiated with container=deque!
|
||||
|
||||
// we assumethis adapter was instantiated with container=deque!
|
||||
class Any_stack : public Any_deque
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// nonstandard containers (will probably be part of C++0x)
|
||||
//
|
||||
|
||||
#ifdef HAVE_STL_HASH
|
||||
|
||||
|
||||
class Any_hash_map: public STL_HASH_MAP<int,int>
|
||||
{
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
const_iterator it = begin();
|
||||
if(!container_valid(&*it, el_count(el_size)))
|
||||
Any_list* list = (Any_list*)&_List;
|
||||
if(!list->valid(el_size))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -456,19 +535,32 @@ public:
|
||||
UNUSED(el_size);
|
||||
return size();
|
||||
}
|
||||
|
||||
class iter : public const_iterator
|
||||
{
|
||||
public:
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
++(*this);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Any_hash_multimap : public Any_hash_map
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
class Any_hash_set: public STL_HASH_SET<int>
|
||||
{
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
const_iterator it = begin();
|
||||
if(!container_valid(&*it, el_count(el_size)))
|
||||
Any_list* list = (Any_list*)&_List;
|
||||
if(!list->valid(el_size))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@ -478,8 +570,20 @@ public:
|
||||
UNUSED(el_size);
|
||||
return size();
|
||||
}
|
||||
|
||||
class iter : public const_iterator
|
||||
{
|
||||
public:
|
||||
const u8* deref_and_advance(size_t el_size)
|
||||
{
|
||||
const u8* p = (const u8*)&operator*();
|
||||
++(*this);
|
||||
return p;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
class Any_hash_multiset : public Any_hash_set
|
||||
{
|
||||
};
|
||||
@ -488,21 +592,9 @@ class Any_hash_multiset : public Any_hash_set
|
||||
|
||||
#ifdef HAVE_STL_SLIST
|
||||
|
||||
class Any_slist: public STL_SLIST<int>
|
||||
{
|
||||
public:
|
||||
bool valid(size_t el_size) const
|
||||
{
|
||||
if(!container_valid(&front(), el_count(el_size)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t el_count(size_t el_size) const
|
||||
{
|
||||
UNUSED(el_size);
|
||||
return size();
|
||||
}
|
||||
class Any_slist: public Any_list
|
||||
{
|
||||
};
|
||||
|
||||
#endif // HAVE_STL_SLIST
|
||||
@ -513,47 +605,10 @@ public:
|
||||
// specific container iterator stored in it_mem.
|
||||
template<class T> const u8* stl_iterator(void* it_mem, size_t el_size)
|
||||
{
|
||||
UNUSED(el_size);
|
||||
T::const_iterator* const p_cit = (T::const_iterator*)it_mem;
|
||||
T::const_reference el = p_cit->operator*();
|
||||
const u8* p = (const u8*)⪙
|
||||
p_cit->operator++();
|
||||
return p;
|
||||
T::iter* pi = (T::iter*)it_mem;
|
||||
return pi->deref_and_advance(el_size);
|
||||
}
|
||||
|
||||
// vector iterators advance by sizeof(value_type) bytes; since we assume the
|
||||
// int specialization, we have to do this ourselves.
|
||||
template<> const u8* stl_iterator<Any_vector>(void* it_mem, size_t el_size)
|
||||
{
|
||||
Any_vector::iter* pi = (Any_vector::iter*)it_mem;
|
||||
const u8* p = (const u8*)&*(*pi);
|
||||
pi->advance(el_size);
|
||||
return p;
|
||||
}
|
||||
|
||||
// deque iterator operator* depends on el_size
|
||||
#if STL_DINKUMWARE != 0
|
||||
template<> const u8* stl_iterator<Any_deque>(void* it_mem, size_t el_size)
|
||||
{
|
||||
Any_deque::iter* pi = (Any_deque::iter*)it_mem;
|
||||
const u8* p = pi->deref(el_size);
|
||||
++(*pi);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
// map iterator operator++ depends on el_size
|
||||
#if STL_DINKUMWARE != 0
|
||||
template<> const u8* stl_iterator<Any_map>(void* it_mem, size_t el_size)
|
||||
{
|
||||
Any_map::iter* pi = (Any_map::iter*)it_mem;
|
||||
const u8* p = (const u8*)&*(*pi);
|
||||
pi->advance(el_size);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// check if the container is valid and return # elements and an iterator;
|
||||
// this is instantiated once for each type of container.
|
||||
@ -565,10 +620,15 @@ template<class T> bool get_container_info(T* t, size_t size, size_t el_size,
|
||||
debug_assert(sizeof(T) == size);
|
||||
debug_assert(sizeof(T::iterator) < DEBUG_STL_MAX_ITERATOR_SIZE);
|
||||
|
||||
// bail if the container is uninitialized/invalid.
|
||||
// check this before calling el_count etc. because they may crash.
|
||||
if(!t->valid(el_size))
|
||||
return false;
|
||||
|
||||
*el_count = t->el_count(el_size);
|
||||
*el_iterator = stl_iterator<T>;
|
||||
*(T::const_iterator*)it_mem = t->begin();
|
||||
return t->valid(el_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -577,7 +637,7 @@ template<class T> bool get_container_info(T* t, size_t size, size_t el_size,
|
||||
// return number of elements and an iterator (any data it needs is stored in
|
||||
// it_mem, which must hold DEBUG_STL_MAX_ITERATOR_SIZE bytes).
|
||||
// returns 0 on success or an StlContainerError.
|
||||
int stl_get_container_info(const wchar_t* wtype_name, const u8* p, size_t size,
|
||||
int stl_get_container_info(const char* type_name, const u8* p, size_t size,
|
||||
size_t el_size, size_t* el_count, DebugIterator* el_iterator, void* it_mem)
|
||||
{
|
||||
// HACK: The debug_stl code breaks VS2005's STL badly, causing crashes in
|
||||
@ -599,9 +659,7 @@ int stl_get_container_info(const wchar_t* wtype_name, const u8* p, size_t size,
|
||||
// workaround for preprocessor limitation: what we're trying to do is
|
||||
// stringize the defined value of a macro. prepending and pasting L
|
||||
// apparently isn't possible because macro args aren't expanded before
|
||||
// being pasted; we therefore convert to char[] and compare against that.
|
||||
char type_name[DBG_SYMBOL_LEN];
|
||||
snprintf(type_name, ARRAY_SIZE(type_name), "%ws", wtype_name);
|
||||
// being pasted; we therefore compare as chars[].
|
||||
#define STRINGIZE2(id) # id
|
||||
#define STRINGIZE(id) STRINGIZE2(id)
|
||||
|
||||
@ -616,8 +674,11 @@ int stl_get_container_info(const wchar_t* wtype_name, const u8* p, size_t size,
|
||||
STD_CONTAINER(vector) // special-cased
|
||||
STD_CONTAINER(basic_string) // ok
|
||||
// standard container adapter
|
||||
STD_CONTAINER(queue) // not ok (deque)
|
||||
STD_CONTAINER(stack) // not ok (deque)
|
||||
// (note: Any_queue etc. assumes the underlying container is a deque.
|
||||
// we make sure of that here and otherwise refuse to display it, because
|
||||
// doing so is lots of work for little gain.)
|
||||
CONTAINER(queue, "std::queue<*,std::deque<*> >")
|
||||
CONTAINER(stack, "std::stack<*,std::deque<*> >")
|
||||
// nonstandard containers (will probably be part of C++0x)
|
||||
#ifdef HAVE_STL_HASH
|
||||
CONTAINER(hash_map, STRINGIZE(STL_HASH_MAP) "<*>")
|
||||
|
@ -21,8 +21,8 @@
|
||||
// reduce complicated STL names to human-readable form (in place).
|
||||
// e.g. "std::basic_string<char, char_traits<char>, std::allocator<char> >" =>
|
||||
// "string". algorithm: strip undesired strings in one pass (fast).
|
||||
// called from symbol_string_build.
|
||||
extern void stl_simplify_name(char* name);
|
||||
// returns <name> for convenience.
|
||||
extern char* stl_simplify_name(char* name);
|
||||
|
||||
|
||||
// no STL iterator is larger than this; see below.
|
||||
@ -43,7 +43,7 @@ enum StlContainerError
|
||||
// return number of elements and an iterator (any data it needs is stored in
|
||||
// it_mem, which must hold DEBUG_STL_MAX_ITERATOR_SIZE bytes).
|
||||
// returns 0 on success or an StlContainerError.
|
||||
extern int stl_get_container_info(const wchar_t* type_name, const u8* p, size_t size,
|
||||
extern int stl_get_container_info(const char* type_name, const u8* p, size_t size,
|
||||
size_t el_size, size_t* el_count, DebugIterator* el_iterator, void* it_mem);
|
||||
|
||||
#endif // #ifndef DEBUG_STL_H_INCLUDED
|
||||
|
@ -686,6 +686,33 @@ static int dump_string(const u8* p, size_t el_size)
|
||||
}
|
||||
|
||||
|
||||
// split out of dump_sequence.
|
||||
static void seq_determine_formatting(size_t el_size, size_t el_count,
|
||||
bool* fits_on_one_line, size_t* num_elements_to_show)
|
||||
{
|
||||
// make sure empty containers are displayed with [0] {}, otherwise
|
||||
// the lack of output looks like an error.
|
||||
if(!el_count)
|
||||
*fits_on_one_line = true;
|
||||
|
||||
if(el_size == sizeof(char))
|
||||
{
|
||||
*fits_on_one_line = el_count <= 16;
|
||||
*num_elements_to_show = MIN(16, el_count);
|
||||
}
|
||||
else if(el_size <= sizeof(int))
|
||||
{
|
||||
*fits_on_one_line = el_count <= 8;
|
||||
*num_elements_to_show = MIN(12, el_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
*fits_on_one_line = false;
|
||||
*num_elements_to_show = MIN(8, el_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int dump_sequence(DebugIterator el_iterator, void* internal,
|
||||
size_t el_count, DWORD el_type_id, size_t el_size, DumpState state)
|
||||
{
|
||||
@ -703,30 +730,12 @@ static int dump_sequence(DebugIterator el_iterator, void* internal,
|
||||
return ret;
|
||||
}
|
||||
|
||||
out(L"[%d] ", el_count);
|
||||
|
||||
// choose formatting based on element size and count
|
||||
// const bool fits_on_one_line = seq_fits_on_one_line(el_count, el_size, &num_elements_to_show);
|
||||
bool fits_on_one_line;
|
||||
size_t num_elements_to_show;
|
||||
if(el_size == sizeof(char))
|
||||
{
|
||||
fits_on_one_line = el_count <= 16;
|
||||
num_elements_to_show = MIN(16, el_count);
|
||||
}
|
||||
else if(el_size <= sizeof(int))
|
||||
{
|
||||
fits_on_one_line = el_count <= 8;
|
||||
num_elements_to_show = MIN(12, el_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
fits_on_one_line = false;
|
||||
num_elements_to_show = MIN(8, el_count);
|
||||
}
|
||||
if(!el_count)
|
||||
fits_on_one_line = true;
|
||||
seq_determine_formatting(el_size, el_count, &fits_on_one_line, &num_elements_to_show);
|
||||
|
||||
out(L"[%d] ", el_count);
|
||||
state.level++;
|
||||
out(fits_on_one_line? L"{ " : L"\r\n");
|
||||
|
||||
@ -1316,7 +1325,7 @@ static int udt_get_child_type(const wchar_t* child_name,
|
||||
}
|
||||
|
||||
|
||||
static int udt_dump_stl(const wchar_t* type_name, const u8* p, size_t size, DumpState state,
|
||||
static int udt_dump_stl(const wchar_t* wtype_name, const u8* p, size_t size, DumpState state,
|
||||
ULONG num_children, const DWORD* children)
|
||||
{
|
||||
int err;
|
||||
@ -1327,10 +1336,14 @@ static int udt_dump_stl(const wchar_t* type_name, const u8* p, size_t size, Dump
|
||||
if(err != 0)
|
||||
return err;
|
||||
|
||||
// debug_stl doesn't support wchar_t.
|
||||
char ctype_name[DBG_SYMBOL_LEN];
|
||||
snprintf(ctype_name, ARRAY_SIZE(ctype_name), "%ws", wtype_name);
|
||||
|
||||
size_t el_count;
|
||||
DebugIterator el_iterator;
|
||||
u8 it_mem[DEBUG_STL_MAX_ITERATOR_SIZE];
|
||||
err = stl_get_container_info(type_name, p, size, el_size, &el_count, &el_iterator, it_mem);
|
||||
err = stl_get_container_info(ctype_name, p, size, el_size, &el_count, &el_iterator, it_mem);
|
||||
|
||||
// type_name is unknown; can't handle it.
|
||||
if(err == STL_CNT_UNKNOWN)
|
||||
@ -1338,7 +1351,7 @@ static int udt_dump_stl(const wchar_t* type_name, const u8* p, size_t size, Dump
|
||||
// contents are invalid (uninitialized or corrupted)
|
||||
else if(err == STL_CNT_INVALID)
|
||||
{
|
||||
out(L"(uninitialized/invalid %s)", type_name);
|
||||
out(L"(uninitialized/invalid %hs)", stl_simplify_name(ctype_name));
|
||||
return 0;
|
||||
}
|
||||
// supported and valid: output each element.
|
||||
@ -1863,6 +1876,7 @@ static void test_udt()
|
||||
// STL containers and their contents
|
||||
static void test_stl()
|
||||
{
|
||||
/*
|
||||
std::vector<std::wstring> v_wstring;
|
||||
v_wstring.push_back(L"ws1"); v_wstring.push_back(L"ws2");
|
||||
|
||||
@ -1903,7 +1917,7 @@ static void test_stl()
|
||||
|
||||
std::set<uintptr_t> s_uintptr;
|
||||
s_uintptr.insert(0x123); s_uintptr.insert(0x456);
|
||||
|
||||
*/
|
||||
test_udt();
|
||||
|
||||
// uninitialized
|
||||
|
Loading…
Reference in New Issue
Block a user