1. 程式人生 > >Linux 系統設定 ulimit 以及 Core檔案的生成

Linux 系統設定 ulimit 以及 Core檔案的生成

【轉載】http://blog.sina.com.cn/s/blog_5ff2a8a201011zhr.html

檢視限制情況 ulimit -a

可以看到如下資訊

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
pending signals                 (-i) 1024
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

而我們需要修改的是open files (-n) 1024的值

於是命令就是limit -n 2048(隨各自需要設定)

-----------------------------------------------------------------------------------


功能說明:控制shell程式的資源。

語  法:ulimit [-aHS][-c <core檔案上限>][-d <資料節區大小>][-f <檔案大小>][-m <記憶體大小>][-n <檔案數目>][-p <緩衝區大小>][-s <堆疊大小>][-t <CPU時間>][-u <程式數目>][-v <虛擬記憶體大小>]

補充說明:ulimit為shell內建指令,可用來控制shell執行程式的資源。

參  數:
   -a  顯示目前資源限制的設定。
   -c <core檔案上限>  設定core檔案的最大值,單位為區塊。
   -d <資料節區大小>  程式資料節區的最大值,單位為KB。
   -f <檔案大小>  shell所能建立的最大檔案,單位為區塊。
   -H  設定資源的硬性限制,也就是管理員所設下的限制。
   -m <記憶體大小>  指定可使用記憶體的上限,單位為KB。
   -n <檔案數目>  指定同一時間最多可開啟的檔案數。
   -p <緩衝區大小>  指定管道緩衝區的大小,單位512位元組。
   -s <堆疊大小>  指定堆疊的上限,單位為KB。
   -S  設定資源的彈性限制。
   -t <CPU時間>  指定CPU使用時間的上限,單位為秒。
   -u <程式數目>  使用者最多可開啟的程式數目。
   -v <虛擬記憶體大小>  指定可使用的虛擬記憶體上限,單位為KB。

------------------


1,說明:
ulimit用於shell啟動程序所佔用的資源.

2,類別:
shell內建命令

3,語法格式:
ulimit [-acdfHlmnpsStvw] [size]

4,引數介紹:

QUOTE:
-H 設定硬體資源限制.
-S 設定軟體資源限制.
-a 顯示當前所有的資源限制.
-c size:設定core檔案的最大值.單位:blocks
-d size:設定資料段的最大值.單位:kbytes
-f size:設定建立檔案的最大值.單位:blocks
-l size:設定在記憶體中鎖定程序的最大值.單位:kbytes
-m size:設定可以使用的常駐記憶體的最大值.單位:kbytes
-n size:設定核心可以同時開啟的檔案描述符的最大值.單位:n
-p size:設定管道緩衝區的最大值.單位:kbytes
-s size:設定堆疊的最大值.單位:kbytes
-t size:設定CPU使用時間的最大上限.單位:seconds
-v size:設定虛擬記憶體的最大值.單位:kbytes

5,簡單例項:

1]在RH8的環境檔案/etc/profile中,我們可以看到系統是如何配置ulimit的:

CODE:#grep ulimit /etc/profile
ulimit -S -c 0 > /dev/null 2>&1

這條語句設定了對軟體資源和對core檔案大小的設定

2]如果我們想要對由shell建立的檔案大小作些限制,如:

CODE:#ll h
-rw-r--r-- 1 lee lee 150062 7月 22 02:39 h
#ulimit -f 100 #設定建立檔案的最大塊(一塊=512位元組)
#cat h>newh
File size limit exceeded
#ll newh
-rw-r--r-- 1 lee lee 51200 11月 8 11:47 newh

檔案h的大小是150062位元組,而我們設定的建立檔案的大小是512位元組x100塊=51200位元組
當然系統就會根據你的設定生成了51200位元組的newh檔案.

3]可以像例項1]一樣,把你要設定的ulimit放在/etc/profile這個環境檔案中.


------------------------------------------------------------------------------------------------------------------

當系統中的一些程式在遇到一些錯誤以及crash時,系統會自動產生core檔案記錄crash時刻系統資訊,包括記憶體和暫存器資訊,用以程式設計師日後debug時可以使用。這些錯誤包括段錯誤、非法指令、匯流排錯誤或使用者自己生成的退出資訊等等,一般地,core檔案在當前資料夾中存放。

core檔案有時可能在你發生錯誤時,並沒有出現在你當前的資料夾中,發生這種情況的原因有兩個:一個是當前終端被設定為不能彈出core檔案;另一種則是core檔案被指定了路徑。

對於前者,我們可以使用ulimit命令對core檔案的大小進行設定。一般預設情況下,core檔案的大小被設定為0,這樣系統就不dump出core檔案了。這時,使用命令:ulimit -c unlimited進行設定,就可以把core檔案的大小設定為無限大,同時也可以使用數字來替代unlimited,對core檔案的上限制做更精確的設定。

除了可以設定core檔案的大小之外,還可以對core檔案的名稱進行一些規定。這種設定是對/proc/sys/kernel/core_pattern和/proc/sys/kernel/core_uses_pid這兩個檔案進行修改。改動這兩個檔案的方法如下:

echo <pattern> > /proc/sys/kernel/core_pattern

echo <"0"/"1"> /proc/sys/kernel/core_uses_pid

並且注意,只有超級使用者才可以修改這兩個表。

core_pattern接受的是core檔名稱的pattern,它包含任何字串,並且用%作為轉移符號生成一些標示符,為core檔名稱加入特殊含義。已定義的標示符有如下這些:

%%:相當於%

%p:相當於<pid>

%u:相當於<uid>

%g:相當於<gid>

%s:相當於導致dump的訊號的數字

%t:相當於dump的時間

%e:相當於執行檔案的名稱

%h:相當於hostname

除以上這些標誌位外,還規定:

1、末尾的單個%可以直接去除;

2、%加上除上述以外的任何字元,%和該字元都會被去除;

3、所有其他字元都作為一般字元加入名稱中;

4、core檔案的名稱最大值為64個位元組(包括'\0');

5、core_pattern中預設的pattern為core;

6、為了保持相容性,通過設定core_uses_pid,可以在core檔案的末尾加上%p;

7、pattern中可以包含路徑資訊。

------------------------------------------------------------------------------------------------------------------

下面的資料是從網際網路上整理的來的,參考文獻如下:

1. 可以用ulimit -a 檢視一下棧的大小。
在核心2.6.20下, stack size 為8192 kbytes
如果這裡沒有限制,就棧的大小就只受記憶體的限制。2G是上限。

2. core 檔案
    * 開啟或關閉core檔案的生成
ulimit -c 可以檢視是否開啟此選項,若為0則為關閉;
ulimit -c 0可手動關閉
ulimit -c 1000 為設定core檔案大小最大為1000k

ulimit -c unlimited 設定core檔案大小為不限制大小


很多系統在預設的情況下是關閉生成core檔案的,這個命令可以加到你的profile中去

3.設定Core Dump的核心轉儲檔案目錄和命名規則


在預設的情況下,很多系統的core檔案是生成在你執行程式的目錄下,或者你在程式中chdir後的那個目錄,然後在core檔案的後面加了一個pid。在實際工作中,這樣可能會造成很多目錄下產生core檔案,不便於管理,實際上,在2.6下,core檔案的生成位置和檔名的命名都是可以配置的。


/proc/sys/kernel/core_uses_pid可以控制產生的core檔案的檔名中是否新增pid作為擴充套件,如果新增則檔案內容為1,否則為0
proc/sys/kernel/core_pattern可以設定格式化的core檔案儲存位置或檔名,比如原來檔案內容是core-%e
可以這樣修改:
echo "/tmp/core-%e-%p" > core_pattern
將會控制所產生的core檔案會存放到/corefile目錄下,產生的檔名為core-命令名-pid-時間戳
以下是引數列表:
    %p - insert pid into filename 新增pid
    %u - insert current uid into filename 添加當前uid
    %g - insert current gid into filename 添加當前gid
    %s - insert signal that caused the coredump into the filename 新增導致產生core的訊號
    %t - insert UNIX time that the coredump occurred into filename 新增core檔案生成時的unix時間
    %h - insert hostname where the coredump happened into filename 新增主機名
    %e - insert coredumping executable name into filename 新增命令名

當然,你可以用下列方式來完成
sysctl -w kernel.core_pattern=/tmp/core-%e-%p


這些操作一旦計算機重啟,則會丟失,如果你想持久化這些操作,可以在 /etc/sysctl.conf檔案中增加:
kernel.core_pattern=/tmp/core%p


加好後,如果你想不重啟看看效果的話,則用下面的命令:
sysctl -p /etc/sysctl.conf

------------------------------------------------------------------------------------------------------------------

高手指教:

    解決的問題:
         現有一程式P 長期在伺服器上執行,目前經常是每1天死掉一次(段錯誤)。

    目前解決方法:
         用SecureCRT開一個終端,並在服務其上設定ulimit -c nulimited,然後啟動程式P。用ulimite -a 命令查詢結果如下:

         core file size       (blocks, -c) unlimited
         data seg size           (kbytes, -d) unlimited
         file size             (blocks, -f) unlimited
         pending signals                 (-i) 1024
         max locked memory    (kbytes, -l) 32
          ............
         表明core檔案可以生成。

         並測試利用kill -6 pid能夠core檔案。

   目前的困難:

         當執行ulimit -c nulimited終端 (並且該終端將程式P啟動到後臺了 ./P &)關閉,程式P死掉後並沒有生成 core檔案。
         經試驗後發現ulimit 命令與終端有關。

   高手指教:
          如何設定能夠生成core 檔案,與終端無關
          即,程式啟動,關閉終端,當程式死掉(段錯誤)後能夠生成core檔案。


/etc/security/limits.conf (中設定 redhat衍生系linux)

/etc/profile中的:
# No core files by default
ulimit -S -c 0 > /dev/null 2>&1

註釋掉上面一行。

還有其他UNIX類作業系統也有自己的配置檔案可以設定。

------------------------------------------------------------------------------------------------------------------

gdb core 多執行緒
在linux環境下除錯多執行緒,總覺得不像.NET那麼方便。這幾天就為找一個死鎖的bug折騰好久,介紹一下用過的方法吧。

多執行緒如果dump,多為段錯誤,一般都涉及記憶體非法讀寫。可以這樣處理,使用下面的命令開啟系統開關,讓其可以在死掉的時候生成core檔案。  
ulimit -c unlimited
這樣的話死掉的時候就可以在當前目錄看到core.pid(pid為程序號)的檔案。接著使用gdb:
gdb ./bin ./core.pid
進去後,使用bt檢視死掉時棧的情況,在使用frame命令。

還有就是裡面某個執行緒停住,也沒死,這種情況一般就是死鎖或者涉及訊息接受的超時問題(聽人說的,沒有遇到過)。遇到這種情況,可以使用:
gcore pid (除錯程序的pid號)
手動生成core檔案,在使用pstack(linux下好像不好使)檢視堆疊的情況。如果都看不出來,就仔細檢視程式碼,看看是不是在if,return,break,continue這種語句操作是忘記解鎖,還有巢狀鎖的問題,都需要分析清楚了。

最後,說一句,靜心看程式碼,捶胸頓足是沒有用的。

-------------------------------------

1,說明:
ulimit用於shell啟動程序所佔用的資源.
2,類別:
shell內建命令
3,語法格式:
ulimit [-acdfHlmnpsStvw] [size]
4,引數介紹:
-H 設定硬體資源限制.
-S 設定軟體資源限制.
-a 顯示當前所有的資源限制.
-c size:設定core檔案的最大值.單位:blocks
-d size:設定資料段的最大值.單位:kbytes
-f size:設定建立檔案的最大值.單位:blocks
-l size:設定在記憶體中鎖定程序的最大值.單位:kbytes
-m size:設定可以使用的常駐記憶體的最大值.單位:kbytes
-n size:設定核心可以同時開啟的檔案描述符的最大值.單位:n
-p size:設定管道緩衝區的最大值.單位:kbytes
-s size:設定堆疊的最大值.單位:kbytes
-t size:設定CPU使用時間的最大上限.單位:seconds
-v size:設定虛擬記憶體的最大值.單位:kbytes 5,簡單例項:
5.舉例
在Linux下寫程式的時候,如果程式比較大,經常會遇到“段錯誤”(segmentation fault)這樣的問題,這主要就是由於Linux系統初始的堆疊大小(stack size)太小的緣故,一般為10M。我一般把stack size設定成256M,這樣就沒有段錯誤了!命令為:
ulimit   -s 262140
如果要系統自動記住這個配置,就編輯/etc/profile檔案,在 “ulimit -S -c 0 > /dev/null 2>&1”行下,新增“ulimit   -s 262140”,儲存重啟系統就可以了!
1]在RH8的環境檔案/etc/profile中,我們可以看到系統是如何配置ulimit的:
#grep ulimit /etc/profile
ulimit -S -c 0 > /dev/null 2>&1
這條語句設定了對軟體資源和對core檔案大小的設定
2]如果我們想要對由shell建立的檔案大小作些限制,如:
#ll h
-rw-r--r-- 1 lee lee 150062 7月 22 02:39 h
#ulimit -f 100 #設定建立檔案的最大塊(一塊=512位元組)
#cat h>newh
File size limit exceeded
#ll newh
-rw-r--r-- 1 lee lee 51200 11月 8 11:47 newh
檔案h的大小是150062位元組,而我們設定的建立檔案的大小是512位元組x100塊=51200位元組
當然系統就會根據你的設定生成了51200位元組的newh檔案.
3]可以像例項1]一樣,把你要設定的ulimit放在/etc/profile這個環境檔案中.
用途
設定或報告使用者資源極限。
語法
ulimit [ -H ] [ -S ] [ -a ] [ -c ] [ -d ] [ -f ] [ -m ] [ -n ] [ -s ] [ -t ] [ Limit ]
描述
ulimit 命令設定或報告使用者程序資源極限,如 /etc/security/limits 檔案所定義。檔案包含以下預設值極限:
fsize = 2097151
core = 2097151
cpu = -1
data = 262144
rss = 65536
stack = 65536
nofiles = 2000
當新使用者新增到系統中時,這些值被作為預設值使用。當向系統中新增使用者時,以上值通過 mkuser 命令設定,或通過 chuser 命令更改。
極限分為軟性或硬性。通過 ulimit 命令,使用者可將軟極限更改到硬極限的最大設定值。要更改資源硬極限,必須擁有 root 使用者許可權。
很多系統不包括以上一種或數種極限。 特定資源的極限在指定 Limit 引數時設定。Limit 引數的值可以是每個資源中指定單元中的數字,或者為值 unlimited。要將特定的 ulimit 設定為 unlimited,可使用詞 unlimited。
    注:在 /etc/security/limits 檔案中設定預設極限就是設定了系統寬度極限, 而不僅僅是建立使用者時使用者所需的極限。
省略 Limit 引數時,將會打印出當前資源極限。除非使用者指定 -H 標誌,否則打印出軟極限。當用戶指定一個以上資源時,極限名稱和單元在值之前列印。如果未給予選項,則假定帶有了 -f 標誌。
由於 ulimit 命令影響當前 shell 環境,所以它將作為 shell 常規內建命令提供。如果在獨立的命令執行環境中呼叫該命令,則不影響呼叫者環境的檔案大小極限。以下示例中正是這種情況:
nohup ulimit -f 10000
env ulimit 10000
一旦通過程序減少了硬極限,若無 root 特權則無法增加,即使返回到原值也不可能。
關於使用者和系統資源極限的更多資訊,請參見 AIX 5L Version 5.3 Technical Reference: Base Operating System and Extensions Volume 1 中的 getrlimit、setrlimit 或 vlimit 子例程。
標誌
-a     列出所有當前資源極限。
-c     以 512 位元組塊為單位,指定核心轉儲的大小。
-d     以 K 位元組為單位指定資料區域的大小。
-f     使用 Limit 引數時設定檔案大小極限(以塊計),或者在未指定引數時報告檔案大小極限。預設值為 -f 標誌。
-H     指定設定某個給定資源的硬極限。如果使用者擁有 root 使用者許可權,可以增大硬極限。任何使用者均可減少硬極限。
-m     以 K 位元組為單位指定物理儲存器的大小。
-n     指定一個程序可以擁有的檔案描述符的數量的極限。
-s     以 K 位元組為單位指定堆疊的大小。
-S     指定為給定的資源設定軟極限。軟極限可增大到硬極限的值。如果 -H 和 -S 標誌均未指定,極限適用於以上二者。
-t     指定每個程序所使用的秒數。
退出狀態
返回以下退出值:
0     成功完成。
>0     拒絕對更高的極限的請求,或發生錯誤。
示例
要將檔案大小極限設定為 51,200 位元組,輸入:
ulimit -f 100