当前位置: 技术问答>linux和unix
使用MDB查看变量的值(1)
来源: 互联网 发布时间:2016-10-02
本文导语: 本文地址:http://blog.csdn.net/lw1a2/archive/2009/10/06/4636469.aspx 使用MDB查看变量的值(1) LW1A2@163.COM 本节描述使用MDB查看core文件中变量的基本知识 基本概念: 一般程序发生coredump,80%的可能是由于参数的值...
本文地址:http://blog.csdn.net/lw1a2/archive/2009/10/06/4636469.aspx
使用MDB查看变量的值(1)
LW1A2@163.COM
本节描述使用MDB查看core文件中变量的基本知识
基本概念:
一般程序发生coredump,80%的可能是由于参数的值不对造成的(其他可能是堆栈溢出、多线程等问题造成的)。对于可以复现的问题,一般拿到函数堆栈,通过走读代码基本上就可以定位。对于无法复现的问题,大部分情况需要通过查看变量的值来定位。(注:网上很多文章都是介绍通过反汇编定位哪条语句引起的coredump,个人认为这种方法比较繁琐(需要重新编译),且对优化后的程序用处不大,本文就不讨论了。)
变量可以分为两类,一类是基本类型,例如int等,可以在函数堆栈里直接看到值;另一类是类类型,包括string,STL和用户自定义类型等,这种类型在函数堆栈里会显示它的地址。
使用“地址/格式”这种形式,可以查看地址中保存的值。例如,有代码:
int *p = new int(2010);
假设p=0x8011320,则使用8011320/D,就可以显示2010。常用的格式如下:
X:十六进制int(一般用来显示地址)
D:十进制有符号int
U:十进制无符号int
E:十进制无符号long long
e:十进制有符号long long
s:显示字符串
查看变量的值时,一定要有源代码(至少要有函数声明),否则就无法知道变量的类型,许多地址取值操作就无法实施。
实例:
OS:Solaris10(x86)
编译器:Sun Studio 11
1) 看实参的值,普通函数,参数为内置类型(int类型)。
有如下程序:
view plaincopy to clipboardprint?
void f(int i)
{
throw 0;
}
int main()
{
int i = 1;
f(i);
return 0;
}
void f(int i)
{
throw 0;
}
int main()
{
int i = 1;
f(i);
return 0;
}
编译(CC –o 1 coretest.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471f4 libc.so.1`_lwp_kill+7(1, 6)
0804720c libc.so.1`raise+0x1f(6)
08047254 libc.so.1`abort+0xcd(fee28ef0, a8, 804727c, fee14653, fee28ef0,
fee29a20)
08047264 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
80472ac, fefc0568, 80472ac, fee14ab9)
0804727c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
080472ac libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 805092a, 80472e4)
080472c8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472e4 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050b78, 0)
0804730c void f+0x37(1)
0804732c main+0x1f(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
其中1即为参数i的值。
2) 看实参的值,普通函数,参数为类类型。
有如下程序:
view plaincopy to clipboardprint?
class A
{
public:
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
class A
{
public:
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
编译(CC –o 1 coretest2.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471f4 libc.so.1`_lwp_kill+7(1, 6)
0804720c libc.so.1`raise+0x1f(6)
08047254 libc.so.1`abort+0xcd(fee28ef0, a8, 804727c, fee14653, fee28ef0,
fee29a20)
08047264 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
80472ac, fefc0568, 80472ac, fee14ab9)
0804727c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
080472ac libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 805092a, 80472e0)
080472c8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472e0 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050b80, 0)
08047308 void f+0x37(8047320)
0804732c main+0x26(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
因为函数原型为void f(const A& a),a为引用类型,所以8047320为a的地址(16进制),即m_i的地址,所以m_i的值为:
> 8047320/X
0x8047320: 3
m_j的地址为m_i的地址加4,所以m_j的值为:
> 8047320+4/X
0x8047324: 7
3) 看实参的值,普通函数,参数为类类型(有虚函数表)。
有如下程序:
view plaincopy to clipboardprint?
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
编译(CC –o 1 coretest3.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471e4 libc.so.1`_lwp_kill+7(1, 6)
080471fc libc.so.1`raise+0x1f(6)
08047244 libc.so.1`abort+0xcd(fee28ef0, a8, 804726c, fee14653, fee28ef0,
fee29a20)
08047254 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
804729c, fefc0568, 804729c, fee14ab9)
0804726c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
0804729c libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 8050a4a, 80472d8)
080472b8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472d8 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050d58, 0)
08047300 void f+0x37(804731c)
0804732c main+0x32(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
因为函数原型为void f(const A& a),a为引用类型,所以804731c为a的地址(16进制)。因为类型A含有虚函数,所以804731c指向的内容8060fa4为虚函数表的地址:
> 804731c/X
0x804731c: 8060fa4
> 8060fa4/X
1`__1cBAG__vtbl_:
1`A::__vtbl: 8050d80
> 8060fa4::nm
Value Size Type Bind Other Shndx Name
0x08060fa4|0x0000000c|OBJT |WEAK |0x0 |18 |1`__1cBAG__vtbl_
m_i的地址为a的地址加4,所以m_i的值为:
> 804731c+4/X
0x8047320: 3
m_j的地址为m_i的地址加4,所以m_j的值为:
> 804731c+4+4/X
0x8047324: 7
4) 看实参的值,成员函数,参数为类类型(有虚函数表)。
有如下程序:
view plaincopy to clipboardprint?
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
class B
{
public:
void f(const A& a)
{
throw 0;
}
};
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
B b;
b.f(a);
return 0;
}
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
class B
{
public:
void f(const A& a)
{
throw 0;
}
};
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
B b;
b.f(a);
return 0;
}
编译(CC –o 1 –g coretest4.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471e4 libc.so.1`_lwp_kill+7(1, 6)
080471fc libc.so.1`raise+0x1f(6)
08047244 libc.so.1`abort+0xcd(fee28ef0, a8, 804726c, fee14653, fee28ef0,
fee29a20)
08047254 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
804729c, fefc0568, 804729c, fee14ab9)
0804726c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
0804729c libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 8050a4a, 80472d0)
080472b8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472d0 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050d94, 0)
080472f8 void B::f+0x37(804731b, 804731c)
0804732c main+0x39(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
因为f为非静态成员函数,所以第一个参数(804731b)为this指针,第二个参数(804731c)为a的地址,其他变量查看方法同3)
注:如果f为静态成员函数,则不存在this指针。
使用MDB查看变量的值(1)
LW1A2@163.COM
本节描述使用MDB查看core文件中变量的基本知识
基本概念:
一般程序发生coredump,80%的可能是由于参数的值不对造成的(其他可能是堆栈溢出、多线程等问题造成的)。对于可以复现的问题,一般拿到函数堆栈,通过走读代码基本上就可以定位。对于无法复现的问题,大部分情况需要通过查看变量的值来定位。(注:网上很多文章都是介绍通过反汇编定位哪条语句引起的coredump,个人认为这种方法比较繁琐(需要重新编译),且对优化后的程序用处不大,本文就不讨论了。)
变量可以分为两类,一类是基本类型,例如int等,可以在函数堆栈里直接看到值;另一类是类类型,包括string,STL和用户自定义类型等,这种类型在函数堆栈里会显示它的地址。
使用“地址/格式”这种形式,可以查看地址中保存的值。例如,有代码:
int *p = new int(2010);
假设p=0x8011320,则使用8011320/D,就可以显示2010。常用的格式如下:
X:十六进制int(一般用来显示地址)
D:十进制有符号int
U:十进制无符号int
E:十进制无符号long long
e:十进制有符号long long
s:显示字符串
查看变量的值时,一定要有源代码(至少要有函数声明),否则就无法知道变量的类型,许多地址取值操作就无法实施。
实例:
OS:Solaris10(x86)
编译器:Sun Studio 11
1) 看实参的值,普通函数,参数为内置类型(int类型)。
有如下程序:
view plaincopy to clipboardprint?
void f(int i)
{
throw 0;
}
int main()
{
int i = 1;
f(i);
return 0;
}
void f(int i)
{
throw 0;
}
int main()
{
int i = 1;
f(i);
return 0;
}
编译(CC –o 1 coretest.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471f4 libc.so.1`_lwp_kill+7(1, 6)
0804720c libc.so.1`raise+0x1f(6)
08047254 libc.so.1`abort+0xcd(fee28ef0, a8, 804727c, fee14653, fee28ef0,
fee29a20)
08047264 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
80472ac, fefc0568, 80472ac, fee14ab9)
0804727c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
080472ac libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 805092a, 80472e4)
080472c8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472e4 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050b78, 0)
0804730c void f+0x37(1)
0804732c main+0x1f(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
其中1即为参数i的值。
2) 看实参的值,普通函数,参数为类类型。
有如下程序:
view plaincopy to clipboardprint?
class A
{
public:
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
class A
{
public:
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
编译(CC –o 1 coretest2.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471f4 libc.so.1`_lwp_kill+7(1, 6)
0804720c libc.so.1`raise+0x1f(6)
08047254 libc.so.1`abort+0xcd(fee28ef0, a8, 804727c, fee14653, fee28ef0,
fee29a20)
08047264 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
80472ac, fefc0568, 80472ac, fee14ab9)
0804727c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
080472ac libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 805092a, 80472e0)
080472c8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472e0 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050b80, 0)
08047308 void f+0x37(8047320)
0804732c main+0x26(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
因为函数原型为void f(const A& a),a为引用类型,所以8047320为a的地址(16进制),即m_i的地址,所以m_i的值为:
> 8047320/X
0x8047320: 3
m_j的地址为m_i的地址加4,所以m_j的值为:
> 8047320+4/X
0x8047324: 7
3) 看实参的值,普通函数,参数为类类型(有虚函数表)。
有如下程序:
view plaincopy to clipboardprint?
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
void f(const A& a)
{
throw 0;
}
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
f(a);
return 0;
}
编译(CC –o 1 coretest3.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471e4 libc.so.1`_lwp_kill+7(1, 6)
080471fc libc.so.1`raise+0x1f(6)
08047244 libc.so.1`abort+0xcd(fee28ef0, a8, 804726c, fee14653, fee28ef0,
fee29a20)
08047254 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
804729c, fefc0568, 804729c, fee14ab9)
0804726c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
0804729c libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 8050a4a, 80472d8)
080472b8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472d8 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050d58, 0)
08047300 void f+0x37(804731c)
0804732c main+0x32(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
因为函数原型为void f(const A& a),a为引用类型,所以804731c为a的地址(16进制)。因为类型A含有虚函数,所以804731c指向的内容8060fa4为虚函数表的地址:
> 804731c/X
0x804731c: 8060fa4
> 8060fa4/X
1`__1cBAG__vtbl_:
1`A::__vtbl: 8050d80
> 8060fa4::nm
Value Size Type Bind Other Shndx Name
0x08060fa4|0x0000000c|OBJT |WEAK |0x0 |18 |1`__1cBAG__vtbl_
m_i的地址为a的地址加4,所以m_i的值为:
> 804731c+4/X
0x8047320: 3
m_j的地址为m_i的地址加4,所以m_j的值为:
> 804731c+4+4/X
0x8047324: 7
4) 看实参的值,成员函数,参数为类类型(有虚函数表)。
有如下程序:
view plaincopy to clipboardprint?
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
class B
{
public:
void f(const A& a)
{
throw 0;
}
};
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
B b;
b.f(a);
return 0;
}
class A
{
public:
virtual ~A(){}
int m_i;
int m_j;
};
class B
{
public:
void f(const A& a)
{
throw 0;
}
};
int main()
{
A a;
a.m_i = 3;
a.m_j = 7;
B b;
b.f(a);
return 0;
}
编译(CC –o 1 –g coretest4.cpp)、运行,会产生core文件。
使用MDB:
bash-3.00# mdb core
Loading modules: [ libc.so.1 ld.so.1 ]
> $G
C++ symbol demangling enabled
> $C
080471e4 libc.so.1`_lwp_kill+7(1, 6)
080471fc libc.so.1`raise+0x1f(6)
08047244 libc.so.1`abort+0xcd(fee28ef0, a8, 804726c, fee14653, fee28ef0,
fee29a20)
08047254 libCrun.so.1`void __Cimpl::default_terminate+0x18(fee28ef0, fee29a20,
804729c, fefc0568, 804729c, fee14ab9)
0804726c libCrun.so.1`void std::terminate+0x1b(0, fee29804, fee28ef0, 28,
fee1537d, 0)
0804729c libCrun.so.1`void __Cimpl::ex_terminate+0x39(8047440, fee29804,
fee28ef0, 0, 8050a4a, 80472d0)
080472b8 libCrun.so.1`_ex_throw_body+0x79(fee29a20, 0)
080472d0 libCrun.so.1`void __Crun::ex_throw+0x52(fee29a6c, 8050d94, 0)
080472f8 void B::f+0x37(804731b, 804731c)
0804732c main+0x39(1, 8047358, 8047360)
0804734c _start+0x7a(1, 80474a8, 0, 80474ac, 80474e0, 80474f5)
因为f为非静态成员函数,所以第一个参数(804731b)为this指针,第二个参数(804731c)为a的地址,其他变量查看方法同3)
注:如果f为静态成员函数,则不存在this指针。
|
学习一下
|
看来还有
|
up之
|
学习了 thanks
|
这个代码有点太长了 再帮你顶一次