程序异常定位

时间:2022-09-17 21:43:00
我做了一个软件,其中一个功能是定位C/C++源码中的异常位置(例如野指针操作,除0),谁有异常程序可以贴出来,我指出异常位置。
限制:
1。 linux平台, c/c++程序
2。 贴出完整代码,可成功编译。
3。 贴出编译命令。

17 个解决方案

#1


= = 你这是找这个测试用例?!
不过还是顶楼主!

#2


windows 平台有吗?

#3


楼主这是开发GDB的节奏啊!

#4


这个会不会当成异常

double d = 5.0/0.00000000001

#5


内存操作异常能猜到吗?

#6


引用 4 楼 bjym1987 的回复:
这个会不会当成异常

double d = 5.0/0.00000000001


以实际运行的结果为标准,如果运行时程序崩溃,就能检测到,不崩溃,就检测不到。

#7


引用 3 楼 zhao4zhong1 的回复:
楼主这是开发GDB的节奏啊!

不是的,和GDB原理完全不同。

#8


引用 5 楼 ilikehigame 的回复:
内存操作异常能猜到吗?

老胸,是要是程序运行过程中崩溃了,就能找到。

#9


进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’
使用命令
gdb 运行程序名 core或core.数字
进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。
如果进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令

#10


引用 9 楼 zhao4zhong1 的回复:
进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’
使用命令
gdb 运行程序名 core或core.数字
进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。
如果进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令


gdb 只能定位到崩溃的函数名,我目前可以定位到哪个语句导致崩溃,如果在循环体内,可以检测第几次循环时导致崩溃。

#11


其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

#12


引用 11 楼 zhao4zhong1 的回复:
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

离题了。。

#13


void SignalHandle(const char* data, int size)
{
    std::string str = std::string(data,size);
    //LOG_IF(ERROR,enable_error())<<str;



static bool log_once = false;
if( !log_once ){
 #define SIZE 200
     void *buffer[SIZE];
    char **strings;
    int nptrs = backtrace(buffer, SIZE);
 strings = backtrace_symbols(buffer, nptrs);
 for (int j = nptrs -1; j >= 0; j--)
     {
  std::string line(strings[j]);
auto lIdx = line.find('[');
auto rIdx = line.find(']');
std::string addr = line.substr(lIdx+1, rIdx - lIdx-1);
std::ostringstream cmd;
cmd<<"addr2line "<<addr<<" -e "<<app_name<<" -f -i -C >>dump."<<process_id<<".txt";
system(cmd.str().c_str());

  LOG_IF(ERROR,enable_error())<<j<<":"<< strings[j]<<":"<< addr;
 }
    free(strings);
log_once = true;
}
}

在Linux下面是些简单的事情。。。。。

#14


引用 12 楼 jack9981gmail 的回复:
Quote: 引用 11 楼 zhao4zhong1 的回复:

其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

离题了。。

一点也不离题!
我通过WriteProcessMemory跨进程写几个字节,楼主是不可能定位出来的。

#15


引用 14 楼 zhao4zhong1 的回复:
Quote: 引用 12 楼 jack9981gmail 的回复:

Quote: 引用 11 楼 zhao4zhong1 的回复:

其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

离题了。。

一点也不离题!
我通过WriteProcessMemory跨进程写几个字节,楼主是不可能定位出来的。


你给段代码,我试试。

#16


引用 13 楼 chenxiaohong3905 的回复:
void SignalHandle(const char* data, int size)
{
    std::string str = std::string(data,size);
    //LOG_IF(ERROR,enable_error())<<str;



static bool log_once = false;
if( !log_once ){
 #define SIZE 200
     void *buffer[SIZE];
    char **strings;
    int nptrs = backtrace(buffer, SIZE);
 strings = backtrace_symbols(buffer, nptrs);
 for (int j = nptrs -1; j >= 0; j--)
     {
  std::string line(strings[j]);
auto lIdx = line.find('[');
auto rIdx = line.find(']');
std::string addr = line.substr(lIdx+1, rIdx - lIdx-1);
std::ostringstream cmd;
cmd<<"addr2line "<<addr<<" -e "<<app_name<<" -f -i -C >>dump."<<process_id<<".txt";
system(cmd.str().c_str());

  LOG_IF(ERROR,enable_error())<<j<<":"<< strings[j]<<":"<< addr;
 }
    free(strings);
log_once = true;
}
}

在Linux下面是些简单的事情。。。。。


我所定位的是执行时,源代码中哪个语句导致程序崩溃,而非运行时内存崩溃的位置。

#17


该回复于2014-11-07 15:12:43被管理员删除

#1


= = 你这是找这个测试用例?!
不过还是顶楼主!

#2


windows 平台有吗?

#3


楼主这是开发GDB的节奏啊!

#4


这个会不会当成异常

double d = 5.0/0.00000000001

#5


内存操作异常能猜到吗?

#6


引用 4 楼 bjym1987 的回复:
这个会不会当成异常

double d = 5.0/0.00000000001


以实际运行的结果为标准,如果运行时程序崩溃,就能检测到,不崩溃,就检测不到。

#7


引用 3 楼 zhao4zhong1 的回复:
楼主这是开发GDB的节奏啊!

不是的,和GDB原理完全不同。

#8


引用 5 楼 ilikehigame 的回复:
内存操作异常能猜到吗?

老胸,是要是程序运行过程中崩溃了,就能找到。

#9


进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’
使用命令
gdb 运行程序名 core或core.数字
进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。
如果进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令

#10


引用 9 楼 zhao4zhong1 的回复:
进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’
使用命令
gdb 运行程序名 core或core.数字
进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。
如果进程意外退出不产生core文件,参考“ulimit -c core文件最大块大小”命令


gdb 只能定位到崩溃的函数名,我目前可以定位到哪个语句导致崩溃,如果在循环体内,可以检测第几次循环时导致崩溃。

#11


其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

#12


引用 11 楼 zhao4zhong1 的回复:
其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

离题了。。

#13


void SignalHandle(const char* data, int size)
{
    std::string str = std::string(data,size);
    //LOG_IF(ERROR,enable_error())<<str;



static bool log_once = false;
if( !log_once ){
 #define SIZE 200
     void *buffer[SIZE];
    char **strings;
    int nptrs = backtrace(buffer, SIZE);
 strings = backtrace_symbols(buffer, nptrs);
 for (int j = nptrs -1; j >= 0; j--)
     {
  std::string line(strings[j]);
auto lIdx = line.find('[');
auto rIdx = line.find(']');
std::string addr = line.substr(lIdx+1, rIdx - lIdx-1);
std::ostringstream cmd;
cmd<<"addr2line "<<addr<<" -e "<<app_name<<" -f -i -C >>dump."<<process_id<<".txt";
system(cmd.str().c_str());

  LOG_IF(ERROR,enable_error())<<j<<":"<< strings[j]<<":"<< addr;
 }
    free(strings);
log_once = true;
}
}

在Linux下面是些简单的事情。。。。。

#14


引用 12 楼 jack9981gmail 的回复:
Quote: 引用 11 楼 zhao4zhong1 的回复:

其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

离题了。。

一点也不离题!
我通过WriteProcessMemory跨进程写几个字节,楼主是不可能定位出来的。

#15


引用 14 楼 zhao4zhong1 的回复:
Quote: 引用 12 楼 jack9981gmail 的回复:

Quote: 引用 11 楼 zhao4zhong1 的回复:

其实电脑开机后物理内存的每个字节都是可读写的,从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页,一页通常为4KB。

离题了。。

一点也不离题!
我通过WriteProcessMemory跨进程写几个字节,楼主是不可能定位出来的。


你给段代码,我试试。

#16


引用 13 楼 chenxiaohong3905 的回复:
void SignalHandle(const char* data, int size)
{
    std::string str = std::string(data,size);
    //LOG_IF(ERROR,enable_error())<<str;



static bool log_once = false;
if( !log_once ){
 #define SIZE 200
     void *buffer[SIZE];
    char **strings;
    int nptrs = backtrace(buffer, SIZE);
 strings = backtrace_symbols(buffer, nptrs);
 for (int j = nptrs -1; j >= 0; j--)
     {
  std::string line(strings[j]);
auto lIdx = line.find('[');
auto rIdx = line.find(']');
std::string addr = line.substr(lIdx+1, rIdx - lIdx-1);
std::ostringstream cmd;
cmd<<"addr2line "<<addr<<" -e "<<app_name<<" -f -i -C >>dump."<<process_id<<".txt";
system(cmd.str().c_str());

  LOG_IF(ERROR,enable_error())<<j<<":"<< strings[j]<<":"<< addr;
 }
    free(strings);
log_once = true;
}
}

在Linux下面是些简单的事情。。。。。


我所定位的是执行时,源代码中哪个语句导致程序崩溃,而非运行时内存崩溃的位置。

#17


该回复于2014-11-07 15:12:43被管理员删除