在調用main函數之前會調用一個特殊的啓動程序
它從內核中獲取 命令行參數和環境變量 供main函數使用
可執行程序以它作爲程序的開始地址
2、C程序的開始和結束
void exit(int statues);
void _Exit(int statues);
#include <unistd.h>
void _exit(int status);
後2個函數立即返回內核
第1個函數首先執行exit handlers,執行flush buffer(all buffered datas be flushed),關掉標準IO庫,用fclose關掉所有打開的streams
注2:exit(0) 等同於 return(0)
注3: #include <stdlib.h>
int atexit(void (*func)(void));
(用於註冊exit handlers)
注4:除了exit系列函數,還有信號可以終止進程
3、命令行參數 和 環境變量
for(i = 0; i <argc; i++)
ISO C和POSIX.1都確保argv[argc]是NULL,所以
for(i = 0; argv[i] != NULL; i++)
extern char **environ;(字符串數組)
i.e: HOME=/home/sar/0
PATH=:/bin:/usr/bin/0
SHELL=/bin/bash/0
USER=sar/0
LOGNAME=sar/0
最早的時候寫成
int main(int argc, char *argv[], char *envp[])
但POSIX.1規定最後一個變量用getenv系列函數來操作
#include <stdlib.h>
int putenv(char *str);
int setenv(const char *name, const *value, int
rewrite);
int unsetenv(const char *name);
4、C程序內存佈局
.data----初始化的數據
.bss----"block started by symbol"(古老的彙編運算符)C declaration
注2:LINUX intel x86下,.text起始於0x08048000,stack底低於
0xC0000000
注3:只有.text 和.data 需要存儲,而.bss在程序開始運行之前全部被設置爲
0或者NULL
注4:可以用size命令查看各部分大小
$size /usr/sh
注5:一般以靜態方式進行編譯的可執行文件通常會很大,那是因爲以普通方
式(共享庫模式)編譯,共享庫從可執行文件移出了通用庫routines,而
通過在內存中爲所有程序維持一份拷貝作爲參考
5、內存分配
#include <stlib.h>
void *malloc(size_t size);
void *calloc(size_t nobj, size_t size);
// a specified number of objects of a specified size,i
// initialzied to all 0 bits
void *realloc(void *ptr, size_t newsize);
// increases or decreases the size of a previously allocated area
void free(void *ptr);
注1: 分配的內存都被確保很好的aligned
注2: 它們一般都是通過sbrk()系統調用來實現
注3: 通常分配的內存比程序的指定要大點,因爲需要一些附加的空間來記錄
分配塊的打消,下一個分配塊的指針等等。所以寫這一部分是件不允許
的事情
注4: 忘記free,那麼只要程序在運行,進程內存的使用就會持續增加直到
無內存可用,這叫leakage
6、setjmp和longjmp(跨越函數的跳躍)
#include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
注1:jmp_buf----數組形式,保存所有需要的信息存儲到stack直到調用
longjmp
val----非0,作爲從setjmp的返回值
if (setjmp(jmbbuffer) != 0)
...
longjmp(jmpbuffer, 1);
注2:這兩個函數在編譯優化的時候並不影響globlal,static和volatile變量
但是影響automatic和register變量。因爲在CPU裏的變量和浮點寄存器
在setjmp調用時就已經存儲好了,其他存儲在內存的變量與longjmp時的
值一樣
7、getrlimit和setrlimit(獲取和設置系統資源限制)
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlptr);
int setrlimit(int resource, const struct rlimit *rlptr);
(0 if OK, nonzero on error)
注1:系統資源----比如data段的大小,程序使用的最大空間等等
注2:resource limits影響調用進程和子進程
resource limits可以設置到shell影響所有進程(ulimit命令)