|
藍森林 http://www.lslnet.com 2006年6月6日 10:18
core dump系列分析之1----高手請進
這個問題大概有95%的人不能答對,請看看下面兩組例子代碼,然後回答兩個問題:
1、解釋為什麼第一組代碼會core dump,第二組卻不會core dump?
2、解釋為什麼各個系統之之間存在這種差別?
--------例程代碼段1---------
如下代碼會發生core dump.
AIX環境請用如下代碼測試
[code]
#include <stdio.h>;
#include <unistd.h>;
int main(void)
{
unsigned long i = 0;
char buf[8000];
char *ptr = NULL;
ptr = (char *)malloc( sizeof( buf ) );
if(ptr == NULL ) {
perror("malloc");
exit(-1);
}
for( i = 0; i < (sizeof( buf ) + 128 ); i ++ ) ptr[i] = 1;
free(ptr);
exit(0);
}
[/code]
HP UNIX環境請用如下代碼測試
[code]
#include <stdio.h>;
#include <unistd.h>;
int main(void)
{
unsigned long i = 0;
char buf[8000];
char *ptr = NULL;
ptr = (char *)malloc( sizeof( buf ) );
if(ptr == NULL ) {
perror("malloc");
exit(-1);
}
for( i = 0; i < (sizeof( buf ) + 12300 ); i ++ ) ptr[i] = 1;
free(ptr);
exit(0);
}
[/code]
SCO UNIX環境請用如下代碼測試
[code]
#include <stdio.h>;
#include <unistd.h>;
int main(void)
{
unsigned long i = 0;
char buf[8000];
char *ptr = NULL;
ptr = (char *)malloc( sizeof( buf ) );
if(ptr == NULL ) {
perror("malloc");
exit(-1);
}
for( i = 0; i < (sizeof( buf ) + 2850 ); i ++ ) ptr[i] = 1;
free(ptr);
exit(0);
}
[/code]
--------例程代碼段2---------
如下代碼不會發生core dump
AIX環境請用如下代碼測試
[code]
#include <stdio.h>;
#include <unistd.h>;
int main(void)
{
unsigned long i = 0;
char buf[8000];
char *ptr = NULL;
ptr = (char *)malloc( sizeof( buf ) );
if(ptr == NULL ) {
perror("malloc");
exit(-1);
}
for( i = 0; i < (sizeof( buf ) + 4 ); i ++ ) ptr[i] = 1;
free(ptr);
exit(0);
}
[/code]
HP UNIX環境請用如下代碼測試
[code]
#include <stdio.h>;
#include <unistd.h>;
int main(void)
{
unsigned long i = 0;
char buf[8000];
char *ptr = NULL;
ptr = (char *)malloc( sizeof( buf ) );
if(ptr == NULL ) {
perror("malloc");
exit(-1);
}
for( i = 0; i < (sizeof( buf ) + 12200 ); i ++ ) ptr[i] = 1;
free(ptr);
exit(0);
}
[/code]
SCO UNIX環境請用如下代碼測試
[code]
#include <stdio.h>;
#include <unistd.h>;
int main(void)
{
unsigned long i = 0;
char buf[8000];
char *ptr = NULL;
ptr = (char *)malloc( sizeof( buf ) );
if(ptr == NULL ) {
perror("malloc");
exit(-1);
}
for( i = 0; i < (sizeof( buf ) + 2048 ); i ++ ) ptr[i] = 1;
free(ptr);
exit(0);
}
[/code] |
core dump系列分析之1----高手請進
自己up一下! |
core dump系列分析之1----高手請進
內厚訪問越界
另外malloc多少並不是說只會malloc多少,
而是說保證你肯定會有這麼多內存可用,如果從系統內存中分配不出這麼多內存,那麼報錯(返回NULL),
但是也可能會分配比你想要的多的內存(多多少由系統決定,而且是隨機的)
所以寫程序時要訪問多少內存就申請多少內存
不要希望能夠使用系統多分配的內存 |
core dump系列分析之1----高手請進
只要遵守紀律,就不會犯錯誤。
人生也是如此,只不過比編程有更複雜的規則!!
哎。。。。 |
core dump系列分析之1----高手請進
贊同樓上的觀點,
我也遇到過同樣的問題,不過當時時間比較緊,沒有仔細研究而已。
在windows下同樣存在這樣的問題,如果使用的內存大於malloc分配的內存時,使用的時候是不會報錯的,只是導致malloc返回的指針內容發生越界,最後在Free的時候總是會Core dump的。 |
core dump系列分析之1----高手請進
neither group1 nor group2 codes are acceptable!!!
I never heard that we can read/write to an unknown memory,
though group2 doesn't core dump, but the code is incorrect! we
should not write such code. any tool such as purify will report
ABW(Array Boundary write) like message.
To coredump or not depend on how memory allocation/management
is implemented in system. It's meaningless to discuss it in C/C++ group,
it should be a good topic for BSD/Linux/Solaris/AIX groups.
Thanks! |
core dump系列分析之1----高手請進
感謝無雙兄的提醒,我將代碼做了對malloc返回的判斷,這樣保證分配是成功的,也就是說系統內存是足夠的。
大家說了程序設計中需要留意的東西,也說了這種使用方式是不安全的,可能(注意是可能)導致core dump。但是問題的根源在哪裡那? |
core dump系列分析之1----高手請進
不知對不對. 不過,高人也。:) |
core dump系列分析之1----高手請進
回cs兄,如上兩組例程特意寫是不安全的,但是有目的的,包括在for循環中每個條件的選擇都是甚重考慮的。
這麼做,最終為了讓大家明白這些unix系統中對於存儲器是如何管理的,應用為什麼會必然發生core dump,為什麼有的程序只是偶爾dump。
如上是討論1,這個結束了將討論2:
不同的core之間的差異,這種差異最終是由操作系統的什麼措施引起的。 |
core dump系列分析之1----高手請進
-->
Repat it! It depends on system, every system might has its unique algorithm
in some corner of memory management.
one thousand different system might have one thousand different implement
of memory management!
that's all I can say for this topic! |
core dump系列分析之1----高手請進
one thousand different system might have one thousand different implement
of memory management!
這個說法不能同意!事實上除了對頁的保戶措施存在差別外(這種算法也不是成千上萬的),對頁的管理調度差別就更小了!
cs兄,看你如此熟悉,可否就以上三個系統做點分析,不用列舉成千上萬的差別。 |
core dump系列分析之1----高手請進
使用malloc只是保證能分配大於等於這個數的內存
所以有時是大於有時是等於
如果訪問越界地址的話那麼在等於情況下就會出錯,因為已訪問到其它段
另外不同系統的內存管理確實不一樣
在linux下
0字節前面是塊的大小
其它系統下使用其它方法保存地址大小以及地址偏移
如鏈表等
這點也是有區別的 |
core dump系列分析之1----高手請進
我就以申請1個字節做為例子來說說我的想法:
當我們用malloc申請內存時,總是從操作系統那邊一頁一頁地申請,即使你申請1個字節的內存,malloc也是從操作系統那邊申請回一整頁的內存。對於應用程序員來說好像只申請到1個字節,但實際上malloc分配的內存應該是一整頁,顯然我們就可以對這一整頁的內存進行訪問,因為是屬於應用程序的內存。當訪問超出這個頁時操作系統就認為你越界了(因為操作系統就分配一頁大小的內存間),就會造成coredump,所以我覺得上面那三個程序的區別在於操作系統對頁大小定義的不一樣。
(以上只是我的一種想法,不知對不對) |
core dump系列分析之1----高手請進
基本正確
不正確的就是不是申請一整頁
而是查找可用的內存池
然後把符合條件的分給它
這個條件是要達到申請大小或以上 |
core dump系列分析之1----高手請進
[quote="無雙"]基本正確
不正確的就是不是申請一整頁
而是查找可用的內存池
然後把符合條件的分給它
這個條件是要達到申請大小或以上[/quote]-->-->
由於UNIX採用的是段頁式管理,分配的最小單位是頁,所以同意caiys的觀點.... |
core dump系列分析之1----高手請進
那不會如果分配一次的話就分配一頁了吧
一頁一般是4K
那麼分配1000次,每次一個INT
那麼內存浪費也太大了吧
我覺得不會每次分配都分配一頁
而是系統有自己的管理機制
雖然系統調度進程進出內存時都是以頁為單位的
但是並不是每次分配都是要一個頁
而是看看當前頁中是不是有可用的空間
如果有繼續分配
當然偶不是很清楚
有時間的話要認真看看 |
core dump系列分析之1----高手請進
頁是存儲的物理單位,對應著塊,是分配的最小單位
如果一個物理塊是4k,而需要5k的空間,則需要調用兩次頁面,浪費3k空間
不會出現樓上所說的現象.............. |
core dump系列分析之1----高手請進
各位討論到了真正的原因,core和不core是於頁面管理相關的(大多數的系統頁面大小為4096字節)。為什麼不同系統存在那個差別是因為上面列舉的三個系統對頁面的保戶算法不同導致的。 |
core dump系列分析之1----高手請進
| core dump系列分析之1----高手請進
受益匪千。各位繼續討論。 |
| |