Windows how to find disk number of mounted VHD?

Q. Once you mount a VHD on Windows, how to find the disk number ‘n’ of the mounted vhd? This is required to access the mounted VHD in the disk form as \\.\PhyiscalDriven.

Ans:

Use below diskpart command, it lists all the mounted VHDs and their corresponding disk numbers.

DISKPART> list vdisk
VDisk ### Disk ### State Type File
 --------- -------- -------------------- --------- ----
 VDisk 0 Disk 2 Attached not open Expandable S:\UBMD.vhd
 VDisk 1 Disk 1 Attached not open Expandable C:\resOCB\test_0.vhd

From the example S:\UBMD.vhd is mounted at disk number 2 and C:\resOCB\test_0.vhd is mounted at disk number 1.

Advertisements

GDB: Get stack trace of all threads of running process

Q. How to get the stack trace of a running c/c++ process on Unix.

Ans:

1. Attach GDB to a running process:

Get the pid of running process foo. $ps -aef | grep foo
Attach gdb to the pid of process foo
$sudo gdb -p 21884

2. Save the stack trace of all running threads in a log file.

(gdb) set pagination off
(gdb) set logging on
 Copying output to gdb.txt.
(gdb) thread apply all bt

3. Detach gdb from running process

(gdb) detach
 Detaching from program: foo, process 21884

After this you’ll find the stack trace of all the threads of your running process in file text gdb.txt This is extremely useful to debug the hung process.

GDB: print the c++ STL object

For me debugging becomes painful in Unix compared to Windows.

I came across an interesting problem. I had to display the contents of unordered_set of a running process on Ubuntu server. I attached the GDB to running process and tried to display the contents. Here is what I got:

1. Attach GDB to a running process:

Get the pid of running process foo. $ps -aef | grep foo Attach gdb to the pid of process foo $sudo gdb -p pid

2. Display the unordered_set contents

(gdb) print set_contents
$1 = {<std::tr1::__unordered_set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, false>> = {<std::tr1::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, std::tr1::__detail::_Prime_rehash_policy, false, true, true>> = {<std::tr1::__detail::_Rehash_base<std::tr1::__detail::_Prime_rehash_policy, std::tr1::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, std::tr1::__detail::_Prime_rehash_policy, false, true, true> >> = {<No data fields>}, <std::tr1::__detail::_Hash_code_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, false>> = {
        _M_extract = {<std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<No data fields>}, <No data fields>},
        _M_eq = {<std::binary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool>> = {<No data fields>}, <No data fields>},
        _M_h1 = {<std::unary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long>> = {<No data fields>}, <No data fields>},
        _M_h2 = {<No data fields>}}, <std::tr1::__detail::_Map_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, true, std::tr1::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::_Identity<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::tr1::__detail::_Mod_range_hashing, std::tr1::__detail::_Default_ranged_hash, std::tr1::__detail::_Prime_rehash_policy, false, true, true> >> = {<No data fields>},
      _M_node_allocator = {<__gnu_cxx::new_allocator<std::tr1::__detail::_Hash_node<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, false> >> = {<No data fields>}, <No data fields>}, _M_buckets = 0x1fc6550, _M_bucket_count = 11, _M_element_count = 1, _M_rehash_policy = {
        _M_max_load_factor = 1, _M_growth_factor = 2,
        _M_next_resize = 11}}, <No data fields>}, <No data fields>}

There is no way you can make out what are the contents of STL object with this output.

Then I came across this article: https://sourceware.org/gdb/wiki/STLSupport

Following steps helped me to achieve my goal:

1. Check-out the latest Python libstdc++ printers to a place on your machine. In a local directory, do:
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python

2. Add the following to your ~/.gdbinit. The path needs to match where the python module above was checked-out. So if checked out to: /home/maude/gdb_printers/, the path would be as written in the example:

python
import sys
sys.path.insert(0, '/home/maude/gdb_printers/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

After this GDB started displaying the contents of unordered_set as expected:

(gdb) print set_contents 
$1 = std::unordered_set with 1 elements = {"2014-03-15/449782CE-10E6-4233-A143-61CB6314E103" }