Ⅰ linux 設置堆棧大小 為無限制
你好。
執行命令ulimit -a,查看棧大小的限制。
通過使用 ulimit -s 數字 進行設置。
Ⅱ linux堆棧地址錯誤與報錯函數偏移怎麼算
一般察看函數運行時堆棧的方法是使用GDB(bt命令)之類的外部調試器,但是,有些時候為了分析程序的BUG,(主要針對長時間運行程序的分析),在程序出錯時列印出函數的調用堆棧是非常有用的。
在glibc頭文件"execinfo.h"中聲明了三個函數用於獲取當前線程的函數調用堆棧。
[cpp] view plain print?
int backtrace(void **buffer,int size)
該函數用於獲取當前線程的調用堆棧,獲取的信息將會被存放在buffer中,它是一個指針列表。參數 size 用來指定buffer中可以保存多少個void* 元素。函數返回值是實際獲取的指針個數,最大不超過size大小
在buffer中的指針實際是從堆棧中獲取的返回地址,每一個堆棧框架有一個返回地址
注意:某些編譯器的優化選項對獲取正確的調用堆棧有干擾,另外內聯函數沒有堆棧框架;刪除框架指針也會導致無法正確解析堆棧內容
[cpp] view plain print?
char ** backtrace_symbols (void *const *buffer, int size)
backtrace_symbols將從backtrace函數獲取的信息轉化為一個字元串數組. 參數buffer應該是從backtrace函數獲取的指針數組,size是該數組中的元素個數(backtrace的返回值)
函數返回值是一個指向字元串數組的指針,它的大小同buffer相同.每個字元串包含了一個相對於buffer中對應元素的可列印信息.它包括函數名,函數的偏移地址,和實際的返回地址
現在,只有使用ELF二進制格式的程序才能獲取函數名稱和偏移地址.在其他系統,只有16進制的返回地址能被獲取.另外,你可能需要傳遞相應的符號給鏈接器,以能支持函數名功能(比如,在使用GNU ld鏈接器的系統中,你需要傳遞(-rdynamic), -rdynamic可用來通知鏈接器將所有符號添加到動態符號表中,如果你的鏈接器支持-rdynamic的話,建議將其加上!)
該函數的返回值是通過malloc函數申請的空間,因此調用者必須使用free函數來釋放指針.
注意:如果不能為字元串獲取足夠的空間函數的返回值將會為NULL
[cpp] view plain print?
void backtrace_symbols_fd (void *const *buffer, int size, int fd)
backtrace_symbols_fd與backtrace_symbols 函數具有相同的功能,不同的是它不會給調用者返回字元串數組,而是將結果寫入文件描述符為fd的文件中,每個函數對應一行.它不需要調用malloc函數,因此適用於有可能調用該函數會失敗的情況
下面是glibc中的實例(稍有修改):
[cpp] view plain print?
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
/* Obtain a backtrace and print it to @code{stdout}. */
void print_trace (void)
{
void *array[10];
size_t size;
char **strings;
size_t i;
size = backtrace (array, 10);
strings = backtrace_symbols (array, size);
if (NULL == strings)
{
perror("backtrace_synbols");
Exit(EXIT_FAILURE);
}
printf ("Obtained %zd stack frames.\n", size);
for (i = 0; i < size; i++)
printf ("%s\n", strings[i]);
free (strings);
strings = NULL;
}
/* A mmy function to make the backtrace more interesting. */
void mmy_function (void)
{
print_trace ();
}
int main (int argc, char *argv[])
{
mmy_function ();
return 0;
}
輸出如下:
[cpp] view plain print?
Obtained 4 stack frames.
./execinfo() [0x80484dd]
./execinfo() [0x8048549]
./execinfo() [0x8048556]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0x70a113]
我們還可以利用這backtrace來定位段錯誤位置。
通常情況系,程序發生段錯誤時系統會發送SIGSEGV信號給程序,預設處理是退出函數。我們可以使用 signal(SIGSEGV, &your_function);函數來接管SIGSEGV信號的處理,程序在發生段錯誤後,自動調用我們准備好的函數,從而在那個函數里來獲取當前函數調用棧。
舉例如下:
[cpp] view plain print?
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <execinfo.h>
#include <signal.h>
void mp(int signo)
{
void *buffer[30] = {0};
size_t size;
char **strings = NULL;
size_t i = 0;
size = backtrace(buffer, 30);
fprintf(stdout, "Obtained %zd stack frames.nm\n", size);
strings = backtrace_symbols(buffer, size);
if (strings == NULL)
{
perror("backtrace_symbols.");
exit(EXIT_FAILURE);
}
for (i = 0; i < size; i++)
{
fprintf(stdout, "%s\n", strings[i]);
}
free(strings);
strings = NULL;
exit(0);
}
void func_c()
{
*((volatile char *)0x0) = 0x9999;
}
void func_b()
{
func_c();
}
void func_a()
{
func_b();
}
int main(int argc, const char *argv[])
{
if (signal(SIGSEGV, mp) == SIG_ERR)
perror("can't catch SIGSEGV");
func_a();
return 0;
}
編譯程序:
gcc -g -rdynamic test.c -o test; ./test
輸出如下:
[cpp] view plain print?
Obtained6stackframes.nm
./backstrace_debug(mp+0x45)[0x80487c9]
[0x468400]
./backstrace_debug(func_b+0x8)[0x804888c]
./backstrace_debug(func_a+0x8)[0x8048896]
./backstrace_debug(main+0x33)[0x80488cb]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x129113]
(這里有個疑問: 多次運行的結果是/lib/i368-Linux-gnu/libc.so.6和[0x468400]的返回地址是變化的,但不變的是後三位, 不知道為什麼)
接著:
objmp -d test > test.s
在test.s中搜索804888c如下:
[cpp] view plain print?
8048884 <func_b>:
8048884: 55 push %ebp
8048885: 89 e5 mov %esp, %ebp
8048887: e8 eb ff ff ff call 8048877 <func_c>
804888c: 5d pop %ebp
804888d: c3 ret
其中80488c時調用(call 8048877)C函數後的地址,雖然並沒有直接定位到C函數,通過匯編代碼, 基本可以推出是C函數出問題了(pop指令不會導致段錯誤的)。
我們也可以通過addr2line來查看
[cpp] view plain print?
addr2line 0x804888c -e backstrace_debug -f
輸出:
[cpp] view plain print?
func_b
/home/astrol/c/backstrace_debug.c:57
以下是簡單的backtrace原理實現:
Ⅲ linux的常用命令及技巧
一。 通用命令:
1. date :print or set the system date and time2. stty -a: 可以查看或者列印控制字元(Ctrl-C, Ctrl-D, Ctrl-Z等)3. passwd: print or set the system date and time (用passwd -h查看)4. logout, login: 登錄shell的登錄和注銷命令5. pwd: print or set the system date and time6. more, less, head tail: 顯示或部分顯示文件內容.7. lp/lpstat/cancel, lpr/lpq/lprm: 列印文件.8. 更改文件許可權: chmod u+x...9. 刪除非空目錄:rm -fr dir10.拷貝目錄: cp -R dir11. fg jobid :可以將一個後台進程放到前台。Ctrl-z 可以將前台進程掛起(suspend), 然後可以用bg jobid 讓其到後台運行。job & 可以直接讓job直接在後台運行。12. kill 的作用: send a signal to a process. eg: kill -9 發送的是SIG_KILL信號。。。 具體發送什麼信號 可以通過 man kill 查看。13. ps 的用法, ps -e 或 ps -o pid,ppid,session,tpgid, comm (其中session顯示的sessionid, tpgid顯示前台進程組id, comm顯示命令名稱。)二 .ubuntu常用命令:
1. dpkg: package manager for Debian* 安裝: dpkg -i package* 卸載: dpkg -r package* 卸載並刪除配置文件: dpkg -P |--purge package* 如果安裝一個包時。說依賴某些庫。 可以先 apt-get install somelib...* 查看軟體包安裝內容 :dpkg -L package* 查看文件由哪個軟體包提供: dpkg -S filename* 另外 dpkg還有 dselect和aptitude 兩個frontend.2. apt* 安裝: apt-get install packs* apt-get update : 更新源* apt-get upgrade: 升級系統。* apt-get dist-upgrade: 智能升級。安裝新軟體包,刪除廢棄的軟體包* apt-get -f install : -f == --fix broken 修復依賴* apt-get autoremove: 自動刪除無用的軟體* apt-get remove packages :刪除軟體* apt-get remove package --purge 刪除包並清除配置文件* 清除所以刪除包的殘余配置文件: dpkg -l |grep ^rc|awk '{print $2}' |tr [/n] [ ]|sudo xargs dpkg -P* 安裝軟體時候包的臨時存放目錄 : /var/cache/apt/archives* 清除該目錄: apt-get clean* 清除該目錄的舊版本的軟體緩存: apt-get autoclean* 查詢軟體some的依賴包: apt-cache depends some* 查詢軟體some被哪些包依賴: apt-get rdepends some* 搜索軟體: apt-cache search name|regexp* 查看軟體包的作用:apt-cache show package* 查看一個軟體的編譯依賴庫: apt-cache showsrc packagename|grep Build-Depends* 下載軟體的源代碼 : apt-get source packagename (注: sources.list 中應該有 deb-src 源)* 安裝軟體包源碼的同時, 安裝其編譯環境 :apt-get build-dep packagename (有deb-src源)* 如何將本地光碟加入安裝源列表: apt-cdrom add3. 系統命令:* 查看內核版本: uname -a* 查看ubuntu 版本: cat /etc/issue* 查看網卡狀態 : ethtool eth0* 查看內存,cpu的信息: cat /proc/meminfo ; cat /proc/cpuinfo(/proc下面的有很多系統信息)* 列印文件系統空間使用情況: df -h* 查看硬碟分區情況: fdisk -l* 產看文件大小: -h filename;* 查看目錄大小: -hs dirname ; -h dirname是查看目錄下所有文件的大小* 查看內存的使用: free -m|-g|-k* 查看進程: ps -e 或ps -aux -->顯示用戶* 殺掉進程: kill pid* 強制殺掉: killall -9 processname4. 網路相關: * 配置 ADSL: sudo pppoeconf* ADSL手工撥號: sudo pon dsl-provider* 激活 ADSL : sudo /etc/ppp/pppoe_on_boot* 斷開 ADSL: sudo poff* 根據IP查網卡地址: arping IP地址* 產看本地網路信息(包括ip等): ifconfig | ifconfig eth0* 查看路由信息: netstat -r* 關閉網卡: sudo ifconfig eth0 down* 啟用網卡: sudo ifconfig eth0 up* 添加一個服務: sudo update-rc.d 服務名 defaults 99* 刪除一個服務: sudo update-rc.d 服務名 remove* 臨時重啟一個服務: /etc/init.d/服務名 restart* 臨時關閉一個服務: /etc/init.d/服務名 stop* 臨時啟動一個服務: /etc/init.d/服務名 start* 控制台下顯示中文: sudo apt-get install zhcon* 查找某個文件: whereis filename 或 find 目錄 -name 文件名*通過ssh傳輸文件scp -rp /path/filename username@remoteIP:/path #將本地文件拷貝到伺服器上scp -rp username@remoteIP:/path/filename /path #將遠程文件從伺服器下載到本地5. 壓縮:*解壓縮 a.tar.gz: tar zxvf a.tar.gz*解壓縮 a.tar.bz2: tar jxvf a.tar.bz2*壓縮aaa bbb目錄為xxx.tar.gz: tar zcvf xxx.tar.gz aaa bbb*壓縮aaa bbb目錄為xxx.tar.bz2: tar jcvf xxx.tar.bz2 aaa bbb
6. Nautilus:特殊 URI 地址* computer:/// - 全部掛載的設備和網路* network:/// - 瀏覽可用的網路* burn:/// - 一個刻錄 CDs/DVDs 的數據虛擬目錄* smb:/// - 可用的 windows/samba 網路資源* x-nautilus-desktop:/// - 桌面項目和圖標* file:/// - 本地文件* trash:/// - 本地回收站目錄* ftp:// - FTP 文件夾* ssh:// - SSH 文件夾* fonts:/// - 字體文件夾,可將字體文件拖到此處以完成安裝* themes:/// - 系統主題文件夾* 顯示隱藏文件: Ctrl+h* 顯示地址欄: Ctrl+l* 查看已安裝字體: 在nautilus的地址欄里輸入」fonts:///「,就可以查看本機所有的fonts
7.補充部分:
* 查看本地所有的tpc,udp監聽埠: netstat -tupln (t=tcp, u=udp, p=program, l=listen, n=numric)* 通過man搜說相關命令: man -k keyword . eg: man -k user* 或者用 apropos* 統計文件所佔用的實際磁碟空間: ( - estimate file space usage)* 統計文件中的字元,位元組數: wc -c/-l/-w (wc - print the number of newlines, words, and bytes in files)* 查看文件的內容: od -x/-c/.... (od - mp files in octal and other formats)我認為od最有用的就是文件的位元組流了: od -t x1 filename查看文件的 Ascii 碼形式: od -t c filename (其中統計信息最左邊的是: 位元組數)* 查找命令所在文件的位置: which od 輸出: /usr/bin/od查看該文件由哪個包提供: dpkg -S /usr/bin/od 輸出: coreutils: /usr/bin/od再查看coreutils包的全部內容就知道了linux的核心命令: dpkg -L coreutils然後 info coreutils 哈哈,認真學吧, 滿世界都是命令!* 可以用man 命令產看某個命令的所有section 的解釋: man -a tty然後用q,和next 轉換到下一個section的解釋* bash 的好用的快捷鍵:ctrl+a:游標移到行首。ctrl+b:游標左移一個字母ctrl+c:殺死當前進程。ctrl+d:退出當前 Shell。ctrl+e:游標移到行尾。ctrl+h:刪除游標前一個字元,同 backspace 鍵相同。ctrl+k:清除游標後至行尾的內容。ctrl+l:清屏,相當於clear。ctrl+r:搜索之前打過的命令。會有一個提示,根據你輸入的關鍵字進行搜索bash的historyctrl+u: 清除游標前至行首間的所有內容。ctrl+w: 移除游標前的一個單詞ctrl+t: 交換游標位置前的兩個字元ctrl+y: 粘貼或者恢復上次的刪除ctrl+d: 刪除游標所在字母;注意和backspace以及ctrl+h的區別,這2個是刪除游標前的字元ctrl+f: 游標右移ctrl+z : 把當前進程轉到後台運行,使用』 fg 『命令恢復。比如top -d1 然後ctrl+z ,到後台,然後fg,重新恢復* 快速粘貼:先在一個地方選中文字,在欲粘貼的地方按滑鼠 中鍵 即可。* 等效中鍵:a 、按下滑輪等效於中鍵。b、同時按下滑鼠 左右鍵,等效於中鍵。* 快速重啟X服務: 同時按下: Alt + Ctrl + Backspace 三個鍵。* 打開運行窗口: 同時按下 Alt + F2 鍵。* 戴屏: a、全屏:直接按下 PrtScr 鍵。b、當前窗口:同時按下 Alt + PrtScr 鍵。c、延時戴屏:在 終端 或 運行窗口中輸入命令: gnome-screenshot --delay 3 ,將延時 3 秒後戴屏。* 直接將 文件管理器 中的文件拖到 GNOME終端 中就可以在終端中得到完整的路徑名。 8.ulimitulimit:顯示(或設置)用戶可以使用的資源的限制(limit),這限制分為軟限制(當前限制)和硬限制(上限),其中硬限制是軟限制的上限值,應用程序在運行過程中使用的系統資源不超過相應的軟限制,任何的超越都導致進程的終止。ulimited 不限制用戶可以使用的資源,但本設置對可打開的最大文件數(max open files)和可同時運行的最大進程數(max user processes)無效-a 列出所有當前資源極限-c 設置core文件的最大值.單位:blocks-d 設置一個進程的數據段的最大值.單位:kbytes-f Shell 創建文件的文件大小的最大值,單位:blocks-h 指定設置某個給定資源的硬極限。如果用戶擁有 root 用戶許可權,可以增大硬極限。任何用戶均可減少硬極限-l 可以鎖住的物理內存的最大值-m 可以使用的常駐內存的最大值,單位:kbytes-n 每個進程可以同時打開的最大文件數-p 設置管道的最大值,單位為block,1block=512bytes-s 指定堆棧的最大值:單位:kbytes-S 指定為給定的資源設置軟極限。軟極限可增大到硬極限的值。如果 -H 和 -S 標志均未指定,極限適用於以上二者-t 指定每個進程所使用的秒數,單位:seconds-u 可以運行的最大並發進程數-v Shell可使用的最大的虛擬內存,單位:kbyteseg: ulimit -c 1000(可以先通過ulimit -c 查看原來的值)
Ⅳ 求教關於linux的堆棧設置
在/etc/profile 的最後面添加ulimit -s unlimited 保存,source /etc/profile使修改文件生效
linux查看修改線程默認棧空間大小 :ulimit -s
1、通過命令 ulimit -s 查看linux的默認棧空間大小,默認情況下 為10240 即10M
2、通過命令 ulimit -s 設置大小值 臨時改變棧空間大小:ulimit -s 102400, 即修改為100M
3、可以在/etc/rc.local 內 加入 ulimit -s 102400 則可以開機就設置棧空間大小
4、在/etc/security/limits.conf 中也可以改變棧空間大小:
#<domain> <type> <item> <value>
* soft stack 102400
重新登錄,執行ulimit -s 即可看到改為102400 即100M
Ⅳ linux上多線程程序崩潰使用什麼方法可以記錄堆棧
gcc編譯時加-g參數,然後用gdb去跑,掛掉的時候使用bt命令就可以看到某一線程的調用棧了,你可以使用thread命令去切換線程,就可以看到不同線程的調用棧了,具體去網路一下gdb的用法就行了。 另: 還可以把堆棧錯誤給mp core,如果你覺得有必...
Ⅵ Redhat Linux中怎樣自動設置線程堆棧大小
不是可以直接用線程屬性進行設置嗎?
我寫了一個小程序。如下:
#include <pthread.h>
#include <limits.h>#define Thread_NUM 5void *MultiThread_soap_serve(){ sleep(5); printf("new pthread!!\n");}//PTHREAD_STACK_MIN 經過計算是16K。//64*16K = 1M,線程堆棧應該是夠用的。#define MICHAEL_SET_PTHREAD_STACK_SIZE 64int main(){ pthread_attr_t attr; pthread_attr_init(&attr); size_t stacksize = MICHAEL_SET_PTHREAD_STACK_SIZE*PTHREAD_STACK_MIN; //stacksize =PTHREAD_STACK_MIN; //stackaddr=(void*)malloc((N+1)*PTHREAD_STACK_MIN); //pthread_attr_getstack(&attr,&statckattr,&stacksize); //pthread_attr_setstack(&attr,stackaddr,); pthread_attr_setstacksize(&attr,stacksize); int iThreadNum = 0; pthread_t PSoapThread[Thread_NUM]; for ( ; iThreadNum < Thread_NUM ; iThreadNum++ ) { pthread_create(&PSoapThread[iThreadNum],&attr,MultiThread_soap_serve,(void *)NULL); } pthread_attr_destroy(&attr); while(1) { sleep(10); printf("main!!\n"); }}
Ⅶ Linux/Unix下程序的堆棧大小是怎麼定的
在/etc/profile 的最後面添加ulimit -s unlimited 保存,source /etc/profile使修改文件生效 linux查看修改線程默認棧空間大小 :ulimit -s 1、通過命令 ulimit -s 查看linux的默認棧空間大小,默認情況下 為10240 即10M
Ⅷ linux 怎麼查看segmentation fault堆棧
gdb ExeName
(gdb)core core.xx
(gdb)bt
core mp 一般是在segmentation fault(段錯誤)的情況下產生的文件,需要通過ulimit來設置才會得到的。關於Linux命令的介紹,看看《linux就該這么學》,具體關於這一章地址3w(dot)linuxprobe/chapter-02(dot)html.
Ⅸ Redhat linux常用的命令有哪些
<1>ls:列目錄。
用法:ls或ls
dirName,參數:-a顯示所有文件,-l詳悉列出文件。
<2>mkdir:建目錄。
用法:mkdir
dirName,參數:-p建多級目錄,如:mkdir
a/b/c/d/e/f
-p
<3>mount:掛載分區或鏡像文件(.iso,.img)文件。
用法:
a.磁碟分區:mount
deviceName
mountPoint
-o
options,其中deviceName是磁碟分區的設備名,比如/dev/hda1,/dev/cdrom,/dev/fd0,mountPoint是掛載點,它是一個目錄,options是參數,如果分區是linux分區,一般不用-o
options,如果是windows分區那options可以是iocharset=cp936,這樣windows分區里的中文文件名就能顯示出來了。用例:比如/dev/hda5是linux分區,我要把它掛到目錄a上(如沒目錄a那就先mkdir
a),mount
/dev/hda5
a,這樣目錄a里的東西就是分區hda5里的東西了,比如hda1是windows分區,要把它掛到b上,mount
/dev/hda1
b
-o
iocharset=cp936。
b.鏡像文件:mount
fileName
mountPoint
-o
loop,fileName是鏡像文件名(*.iso,*.img),其它的不用說了,跟上面一樣。用例:如我有一個a.iso光碟鏡像文件,mount
a.iso
a
-o
loop,這樣進入目錄a你就能瀏覽a.iso的內容了,*.img文件的用法一樣。
<4>find:查找文件。
用法:find
inDir
-name
filename,inDir是你要在哪個目錄找,filename是你要找的文件名(可以用通配符),用通配符時filename做好用單引號引起來,否則有時會出錯,用例:find
.
-name
test*,在當前目錄查找以test開頭的文件。
<5>grep:在文件里查找指定的字元串。
用法:grep
string
filename,在filename(可用通配符)里查找string(最好用雙引號引起來)。參數:-r在所有子目錄里的filename里找。用例:grep
hello
*.c
-r在當前目錄下(包括子目錄)的所有.c文件里查找hello。
<5>vi:編輯器。不用說,用linux的話,這個東西一定要會用。
用法:(只能簡單說一下),vi
filename。filename就是你要編輯的文本文件。用了執行vi
filename後,你可能會發現你無法編輯文本內容,不要著急,這是因為vi還沒進入編輯狀態,按a或i就可以進入編輯狀態了,進入編輯狀態後你就可以編輯文本了。要退出編輯狀態按Esc鍵就可以了。以下操作均要在非編輯狀態下。查找文本:輸入/和你要查找的文本並回車。退出:
輸入:
和q並回車,如果你修改了文本,那麼你要用:q!回車才能退出。保存:輸入:
w回車,如果是只讀文件要用:
w!。保存退出:輸入:
wq回車,如果是只讀就:
wq!回車。取消:
按u就可以了,按一次就取消一步,可按多次取消多步。復制粘貼一行文本:把游標移到要復制的行上的任何地方,按yy(就是連按兩次y),把游標移到要粘貼地方的上一行,按p,剛才那行文本就會被插入到游標所在行的下一行,原來游標所在行後面所有行會自動下移一行。復制粘貼多行文本:跟復制一行差不多,只是yy改成先輸入要復制的行數緊接著按yy,後面的操作一樣。把游標移到指定行:輸入:和行號並回車,比如移到123行:123回車,移到結尾回車。
Ⅹ linux上程序溢出了 怎麼查看堆棧
我暈, 你到底是在什麼發行版? 從提示上來看,要用 apt-get install 來裝,說明是 ubuntu/debian之類的linux發行版,你怎麼又會去用 rpm 來查詢和安裝? 你不說你是什麼發行版,樓上回答的人也不管,直接就讓你用rpm,誤人子弟啊。正確的方法是,sudo apt-get install build-essential這個才是你的系統應該用的,裝好後命令行下運行gcc -v就會列印出你使用gcc的版本信息了,然後就可以用了,比如gcc -o test test.c就會編譯test.c,生成可執行文件 test然後./test就會運行test 我再暈,樓主,提示你沒有test.c,你的C源文件呢?我這里是用test.c做例子,你的源文件叫什麼名字,你就把test.c換成你的文件的名字啊。另外,你要把你的源文件先保存在linux機器上,比方說放到了 /home/yourname/aaa那你要先cd /home/yourname/aaa然後再gcc -o test test.c