如何為自己的進程產生core 文件,又不想退出這個進程?
系統只在程序崩潰退出時自動產生core file。 有的人像自己處理異常信號,然后自己產生一個core file,然后繼續運行。那該怎么辦呢? 如果自己在想產生core file的時候,調用abort 函數來生成文件,core文件是生成了,但自己的進程也退出了。為了進程退出,在網上找到兩個辦法:
=============================================
方法一: 先fork創建一個子進程,子進程擁有和父進程一樣的
內存空間了,然后在子進程觸發abort信號,讓子進程進行core
dump。 這個fork看來還比較有意思的,子進程擁有父進程的一樣
的內存空間,上次才看到有人想定時存檔備份進程數據時,也是想fork一個
子進程出來,說是這樣父進程在備份時也不用同步等待了。子進程可以
訪問父進程的內容吧。
=============================================
方法來自
http://stackoverflow.com/questions/131439/how-can-a-c-program-produce-a-core-dump-of-itself-without-terminating
#include
#include
#include
#include
#include
#include
#include
#include
#define mcrosec 1000000
void create_dump(void)
{
int * invalid = NULL;
if(!fork()) {
// Crash the app in your favorite way here
abort(); //和 kill(getpid(), SIGABRT);應該一樣的
*invalid = 42; //應該不會到這里來了吧。
}
}
int main(int argc,char **argv)
{
int i =0;
while(1){
usleep( 2*mcrosec);
i++;
printf("ddd\n");
if( i==5)
create_dump();
}
return 0;
}
-------------------------------------------------------
使用gdb分析一下這個core文件哈
widebright@:~/桌面$ gdb -core core
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
.
[New Thread 3320]
Core was generated by `./a.out'.
Program terminated with signal 6, Aborted.
#0 0x00982416 in __kernel_vsyscall ()
(gdb) file ./a.out
Reading symbols from /home/widebright/桌面/a.out...done.
(gdb) bt ///查出錯時候的堆棧
#0 0x00982416 in __kernel_vsyscall ()
#1 0x00ec6e71 in ?? ()
#2 0x00ff8ff4 in ?? ()
#3 0x00eca34e in ?? ()
#4 0x00000006 in ?? ()
#5 0xbfa5fd80 in ?? ()
#6 0x0804845f in create_dump () at main.c:18
#7 0x0804849c in main (argc=1, argv=0xbfa5ff04) at main.c:31
(gdb) frame 7 //切換的調用main的調用堆棧環境上去
#7 0x0804849c in main (argc=1, argv=0xbfa5ff04) at main.c:31
31 create_dump();
(gdb) print i //i 等於5的時候調用的dump 呵呵
$1 = 5
=========================================
方法二:調用gcore命令為指定的進程生成core 文件
=========================================
http://forums.freebsd.org/archive/index.php/t-8268.html
char cmd[50];
sprintf(cmd, "gcore %u", getpid());
system(cmd);
-----------------------------------
widebright@:~/桌面$ ps -ef |grep a.out
1000 3665 3546 0 10:53 pts/0 00:00:00 ./a.out
1000 3669 3665 0 10:53 pts/0 00:00:00 [a.out]
1000 3686 2937 0 10:53 pts/2 00:00:00 grep --color=auto a.out
widebright@:~/桌面$ sudo gcore 3665
[sudo] password for widebright:
0x00c5b416 in __kernel_vsyscall ()
Saved corefile core.3665
---------------------------
widebright@:~/桌面$ gdb -core core.3665
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
.
[New Thread 3665]
Core was generated by `/home/widebright/桌面/a.out'.
#0 0x00c5b416 in __kernel_vsyscall ()
(gdb) file a.out
Reading symbols from /home/widebright/桌面/a.out...done.
(gdb) bt
#0 0x00c5b416 in __kernel_vsyscall ()
#1 0x00d2afc0 in ?? ()
#2 0x00d5c1ac in ?? ()
#3 0xbfed8b90 in ?? ()
#4 0x08048481 in main (argc=1, argv=0xbfed8c74) at main.c:27
(gdb) p i
No symbol "i" in current context.
(gdb) frame 4
#4 0x08048481 in main (argc=1, argv=0xbfed8c74) at main.c:27
27 usleep( 2*mcrosec);
(gdb) p i
$1 = 48
=============================
在我機器上gcore命令就個shell腳本,自動生成一個gdb的腳本,attach 指定的進程,然后調用gcore這個gdb 命令生成core文件,然后detach讓進程繼續進行。
(gdb) help generate-core-file
Save a core file with the current state of the debugged process.
Argument is optional filename. Default filename is 'core.'.
(gdb) help gcore
Save a core file with the current state of the debugged process.
Argument is optional filename. Default filename is 'core.'.
如果在測試過程中遇到某個進程的CPU利用率過高或者卡死而需要去調試該進程時,可以利用gdb命令生成coredump文件,然后再去調試coredump文件來定位問題。
那么如何使用gdb生成coredump文件呢?其實步驟很簡單:
1. 安裝好gdb,然后使用命令 'gdb'。(假設需要調試的進程號為 21509)
2. 使用 ‘attach 21590’命令將gdb附加到進程21509上。
3. 使用‘gcore core_name’命令生成coredump文件core_name。
4. 使用‘detach’命令斷開連接。
5.使用‘q’命令退出gdb。
此時,在當前目錄下就會產生一個名為core_name的coredump文件。下面就可以利用gdb工具來對該coredump文件進行調試了。