C程序内存布局
进程退出函数
void _exit(int status);
void _Exit(int status);
voit exit(int status);
void atexit(void (*func)()); // 注册进程退出时调用的函数
函数内跳转
使用goto语句即可实现函数内跳转,此种跳转只需修改指令指针,不需修改堆栈指针。
线程内跳转
跳转函数:
#include <setjmp.h>
int setjmp(jmp_buf env); // 第一次返回0,调用longjmp跳转至此处时返回longjmp所设置的参数
void longjmp(jmp_buf env, int res); // 跳转至setjmp处进行非局部跳转时,需修改指令指针和堆栈指针,指令指针用于重新定位程序执行位置,堆栈指针用于恢复执行环境。有一个问题?在longjmp之后,函数栈是否会完全恢复到第一次调用setjmp时的样子(亦即,栈内的局部变量是否会回滚)。标准并未对此作答,但我们却可以用volatile关键字来保证局部变量不回滚;那如果我们就想回滚怎么办?没办法!
示例程序:
#include <unistd.h> #include <setjmp.h> #include <stdio.h> #include <stdlib.h> #include <string.h> static jmp_buf jmpbuffer; void jumpByCondition(char* str); int main(int argc, char *argv[]) { const int s_maxBuffer = 256; char buff[s_maxBuffer]; int val = 0; register int regVal = 0; volatile int volVal = 0; if (setjmp(jmpbuffer) != 0) { printf("error val=%d, regVal=%d, volVal=%d\n", val, regVal, volVal); exit(1); } while (fgets(buff, s_maxBuffer, stdin)) { ++val; ++regVal; ++volVal; jumpByCondition(buff); } exit(0); } void jumpByCondition(char* str) { if (strstr(str, "jump") != NULL ) { longjmp(jmpbuffer, 1); } else { int len = strlen(str); if (len - 1 > 0 && str[len - 1] == '\n') str[len - 1] = '\0'; puts(str); } }
进程资源
函数:
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *pLimit); // 成功返回0,出错返回非0
int setrlimit(int resource, const struct rlimt *pLimit); // 成功返回0,出错返回非0
struct rmlit
{
int rlim_cur; // 软限制(当前限制)
int rlim_max; // 硬限制(最大限制)
};进程资源常值意义
RLIMIT_AS 进程可用存储区的最大长度 RLIMIT_CORE
core文件的最大字节数,若为0则表示阻止创建core文件
RLIMIT_CPU CPU时间的最大量值(单位秒),若超过此限制则向进程发送SIGXCPU信号 RLIMIT_DATA 初始化数据段、BSS段、堆的总长度限制 RLIMIT_FSIZE 可创建的文件的最大长度,超过此长度时向进程发送SIGXFSZ信号 RLIMIT_LOCKS 一个进程可持有文件锁的最大数量 RLIMIT_MEMLOCK 进程使用mlock可锁定的最大字节长度 RLIMIT_NOFILE 进程能打开的最大文件数 RLIMIT_NPPROC 每个用户ID可拥有的最大子进程数 RLIMIT_RSS 最大驻内存集的字节长度 RLIMIT_SBSIZE 用户在任一给定时间内可以占用的套接字缓冲区的最大长度 RLIMIT_STACK 栈的字节长度 RLIMIT_VMEM RLIMIT_AS的同意词 打印进程资源限制#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/resource.h> #define PRINT_RLIMIT(res) printrlimit(#res, res) void printrlimit(const char* name, int resID); int main(int argc, char *argv[]) { PRINT_RLIMIT(RLIMIT_AS); PRINT_RLIMIT(RLIMIT_CORE); PRINT_RLIMIT(RLIMIT_CPU); PRINT_RLIMIT(RLIMIT_DATA); PRINT_RLIMIT(RLIMIT_FSIZE); PRINT_RLIMIT(RLIMIT_LOCKS); PRINT_RLIMIT(RLIMIT_MEMLOCK); PRINT_RLIMIT(RLIMIT_NOFILE); #ifdef RLIMIT_NPPROC PRINT_RLIMIT(RLIMIT_NPPROC); #endif PRINT_RLIMIT(RLIMIT_RSS); #ifdef RLIMIT_SBSIZE PRINT_RLIMIT(RLIMIT_SBSIZE); #endif PRINT_RLIMIT(RLIMIT_STACK); #ifdef RLIMIT_VMEM PRINT_RLIMIT(RLIMIT_VMEM); #endif exit(0); } void printrlimit(const char* name, int resID) { struct rlimit limit; if (getrlimit(resID, &limit) != 0) { printf("getrlimit error. resid=%d\n", resID); exit(1); } printf("%14s curlim:", name); if (limit.rlim_cur == RLIM_INFINITY) { printf("(infinity)"); } else { printf("%10ld", limit.rlim_cur); } printf(" maxlim:"); if (limit.rlim_max == RLIM_INFINITY) { printf("(infinity)"); } else { printf("%10ld", limit.rlim_max); } putchar('\n'); }