当前位置:  技术问答>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指针。

|
学习一下

|
看来还有

|
up之

|
学习了 thanks

|
这个代码有点太长了  再帮你顶一次

    
 
 

您可能感兴趣的文章:

  • linux 下设置环境变量 使用了setenv 和putenv 在程序结束以后 发现变量又变回去了
  • 如何在若干个类中使用同样的变量?变量的值在一个类中赋予,在其它类中调用。
  • linux内核怎么定义汇编全局变量及在c文件中使用这个变量?有关0。11下的字符回显
  • 在shell中使用mail函数的时候如何使用变量
  • 在JBUILDER中如何使用全局变量,最好举一个例子。我也不知道在哪里定义全局变量?
  • 网卡驱动使用全局变量
  • 在ACC变成中要使用发ftp传送文件,但文件名不确定,请问怎么样在程序的FTP中使用字符串变量???
  • 请教:使用什么命令查看导出的环境变量?
  • gdb中使用set给变量赋值的问题
  • Makefile中的变量先使用后定义的问题
  • 条件编译可以使用全局变量吗?
  • 请问使用crontab是否必须设置环境变量?
  • 关于指针变量,struct 变量,指针使用的一些疑惑,望高手指教
  • 怎么样在JSP中使用PHP的变量呀??
  • 如何在Servlet中使用Application变量?
  • RADHAT下怎样使用PATH变量
  • 有没有方法可以使用脚本批量修改bash环境变量
  • 在线等,sed中可以使用变量吗?
  • [请问]如果在sed命令使用环境变量
  • awk程序中使用shell的变量
  • 如何查看某个进程的cpu使用和内存使用情况????
  • redhat9内存使用率高达73%,怎么查看内存具体使用情况
  • 大家好,我想问下有人用过"linux进程的内存使用解析"中推荐使用的"Ben Maurer写的perl脚本"查看内存么
  • 如何查看分区情况和硬盘空间使用情况?
  • ubuntu的问题。查看内存使用情况的问题
  • redhat ent 4 u4上,如何象readhat ent3 u6版本那样使用top可以查看每个逻辑CPU的利用率以及运行进程的资源使用情况?
  • aix 使用什么命令查看剩余内存比较准确
  • 怎么查看磁盘空间的使用情况?
  • 100分求解如何查看内存最高使用值!!
  • AIX 5 如何查看内存的使用情况
  • 怎样使用netstat查看什么程序绑定了什么端口?
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • C++ I/O 成员 tellg():使用输入流读取流指针
  • 在测试memset函数的执行效率时,分为使用Cash和不使用Cash辆种方式,该如何控制是否使用缓存?
  • C++ I/O 成员 tellp():使用输出流读取流指针
  • 求ibm6000的中文使用手册 !从来没用过服务器,现在急需使用它,不知如何使用! 急!!!!!
  • Python不使用print而直接输出二进制字符串
  • 请问:在使用oracle数据库作开发时,是使用pro*c作开发好些,还是使用库函数如oci等好一些啊?或者它们有什么区别或者优缺点啊?
  • Office 2010 Module模式下使用VBA Addressof
  • 急求结果!!假设一个有两个元素的信号量集S,表示了一个磁带驱动器系统,其中进程1使用磁带机A,进程2同时使用磁带机A和B,进程3使用磁带机B。
  • windows下tinyxml.dll下载安装使用(c++解析XML库)
  • c#中SAPI使用总结——SpVoice的使用方法
  • tcmalloc内存泄露优化c++开源库下载,安装及使用介绍
  • Python不使用print而直接输出二进制字符串 iis7站长之家
  • sharepoint 2010 使用STSNavigate函数实现文件下载举例
  • 共享内存一般是怎么使用的,是同消息队列配合使用么
  • 使用libpcap读取tcpdump抓取的文件并解析c代码实例
  • Jsp可否使用带有GUI的JavaBean,如何使用?
  • c/c++预处理命令预#,##使用介绍
  • asp程序使用的access在Linux下如何使用!
  • 在div中使用css让文字底部对齐的方法
  • 新装的Linux使用root用户不能使用FTP?
  • Python namedtuple(命名元组)使用实例
  • LINUX下使用Eclipse,如何使用交叉编译器?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3