For Developers‎ > ‎How-Tos‎ > ‎

Setting up Visual Studio Debugger Visualizers

Introduction

Visual Studio allows you to plug in additional "visualizers" to display data in the watch windows. This makes debugging some of our more complex data types much easier. To add macros:

  • Find your autoexp.dat file. Visual Studio reads this file when it launches the debugger to determine how to display various data structures. If you have Visual Studio 8, it is probably at:

    C:\Program Files\Microsoft Visual Studio 8\Common7\Packages\Debugger\autoexp.dat

    (Back it up first!)

  • Copy the definition(s) you want and append it to the end of autoexp.dat.
  • Start the debugger, and be amazed at the fancy new way it displays your favorite objects. When you edit the file, you shouldn't have to restart all of Visual Studio - it will get re-loaded when you start the debugger.

Chromium-specific visualizers

; Custom visualizers for Chromium data types.
[Visualizer]
gfx::Point{
preview(
#("x=", $e.x_, ", y=", $e.y_)
)
}
gfx::Size{
preview(
#("w=", $e.width_, ", h=", $e.height_)
)
}
gfx::Rect{
preview(
#("(", $e.origin_, "), (", $e.size_, ")")
)
}
scoped_refptr<*>{
preview(
#(
#if($e.ptr_ != 0)
(
*$e.ptr_
)
#else
(
#("NULL")
)
)
)
children(
#(
#if($e.ptr_ != 0)
(
#(
#(ptr: *$e.ptr_),
#(refcount: $e.ptr_->ref_count_)
)
)
#else
(
#(
#(ptr: "NULL"),
#(refcount: "NA")
)
)
)
)
}
scoped_array<*>{
preview(
#(
#if($e.array_ != 0)
(
*$e.array_
)
#else
(
#("NULL")
)
)
)
}
scoped_ptr<*>{
preview(
#(
#if($e.ptr_ != 0)
(
*$e.ptr_
)
#else
(
#("NULL")
)
)
)
}
base::RefCounted<*>{
preview(
#(
refcount: $e.ref_count_
)
)
}
base::RefCounted<*>{
preview(
#(
refcount: $e.ref_count_
)
)
} IPC::Message{ ; Breaks down IPC message type ID into class (ie, ViewHost) and index into that class. preview( #( "class=", (((IPC::Message::Header*)$c.header_)->type & ~((1<<12)-1)) >> 12, ", index=", ((IPC::Message::Header*)$c.header_)->type & ((1<<12)-1) ) ) children( #( [actual members]: [$e,!], header_: [(IPC::Message::Header*)$c.header_] ) ) } ; END CHROME-SPECIFIC

WebKit-specific visualizers

; Custom visualizers for WebKit data types.
[Visualizer]
WebCore::String{
preview([$c.m_impl.m_ptr->m_data,su])
stringview([$c.m_impl.m_ptr->m_data,sub])
}

WebCore::DeprecatedString{
preview([$c.dataHandle[0]->_ascii])
stringview([$c.dataHandle[0]->_ascii])
}

KJS::UString{
preview([$c.m_rep.m_ptr->buf,su])
stringview([$c.m_rep.m_ptr->buf,sub])
}

WTF::Vector<*>{
children
(
#(
[actual members]: [$e,!],
#array(expr: ($c.m_buffer.m_buffer)[$i], size: $c.m_size)
)
)

preview
(
#(
"[",
$e.m_size,
"](",
#array(expr: ($c.m_buffer.m_buffer)[$i], size: $c.m_size),
")"
)
)
}

WTF::RefPtr<*>{
preview(
#(
#if($e.m_ptr != 0)
(
*$e.m_ptr
)
#else
(
#("NULL")
)
)
)
}
WTF::PassRefPtr<*>{ preview( #( #if($e.m_ptr != 0) ( *$e.m_ptr ) #else ( #("NULL") ) ) ) } WebCore::IntRect{ preview( #("(", $e.m_location, ",", $e.m_size, ")") ) } WebCore::FloatRect{ preview( #("(", $e.m_location, ",", $e.m_size, ")") ) } WebCore::IntPoint{ preview( #("(", $e.m_x, ",", $e.m_y, ")") ) } WebCore::FloatPoint{ preview( #("(", [$e.m_x,g], ",", [$e.m_y,g], ")") ) } WebCore::IntSize{ preview( #("(", $e.m_width, ",", $e.m_height, ")") ) } WebCore::FloatSize{ preview( #("(", [$e.m_width,g], ",", [$e.m_height,g], ")") ) } WebCore::KURL{ stringview([$c.m_url.m_utf8.m_buffer.m_ptr->m_vector.m_buffer.m_buffer,sb]) preview( #if ($e.m_url.m_utf8.m_buffer.m_ptr != 0) ([$e.m_url.m_utf8.m_buffer.m_ptr->m_vector.m_buffer.m_buffer,s]) #else ( "[null url]" ) ) children ( #( #([actual members]: [$e,!]), #if ($e.m_url.m_utf8.m_buffer.m_ptr != 0) ( #( #(m_url: [$e.m_url.m_utf8.m_buffer.m_ptr->m_vector.m_buffer.m_buffer,s]) ) ) #else ( #(m_url: "NULL") ), m_isValid: [$e.m_isValid], m_parsed: [$e.m_parsed] ) ) }

V8-specific visualizers

; Custom visualizers for V8 data types.
[Visualizer]
v8::internal::HeapObject {
children(
#(
;#([ptr]: (int)&$e),
#([map]: ((v8::internal::Map*)*(int**)(&$e-1)))
)
)
}

v8::internal::Map {
children(
#(
;#([addr]: (char**)(&$e) ),
#([instance_type]: (v8::internal::InstanceType)(int)((char*)(&$e))[4] )
)
)
}

v8::internal::String {
children(
#(
#([HeapObject]: (v8::internal::HeapObject*)&$e),
;#([length]: ((int*)((int)&$e-1))[1]),
#switch((int)((char*)*(int**)(&$e-1))[4])
#case 0x08 ( ; SHORT_ASCII_STRING_TYPE
#(
length: ((int*)((int)&$e-1))[1] >> 0x18,
str: (char*)&(((int*)((int)&$e-1))[2])
)
)
#case 0x18 ( ; SHORT_ASCII_SYMBOL_TYPE
#(
length: ((int*)((int)&$e-1))[1] >> 0x18,
str: (char*)&(((int*)((int)&$e-1))[2])
)
)
#default ( #( str: "cant-display" )
)
)
)
}

v8::internal::Smi {
preview (
#( ((int)&$e) >> 1 )
)
}

v8::String {
children(
#(
#([String]: *(v8::internal::String**)&$e )
)
)
}

v8::Integer {
children(
#(
#if ((((int)*(int*)&$e) & 0x1) == 0) (
#(
[SMI]: (v8::internal::Smi*)*(int**)&$e
)
) #else (
#if (((int)&$e & 0x3) == 0x01) (
#([HeapObject]: (v8::internal::HeapObject*)&$e)
)
)

;#([internalInteger]: *(v8::internal::Integer**)&$e )
)
)
}

Definitions

  • preview: an expression (string literal or expression) to be shown in the Watch, QuickWatch or Command window; if the preview section is present and you also have a AutoExpand rule for it, the AutoExpand rule is ignored.
  • children: offer the possibility to construct hierarchies.
  • stringview: used to compose the string that is shown in the Text, XML or HTML visualizer; for instance when you have a string, it shows a magnifying glass on the right; clicking it opens a modal dialog that displays the full content of the variable.

References


Comments