1.与chatgpt的对话
https://chat.openai.com/share/bc3e3476-fcc0-4200-801d-22108cd7c782
2.实验楼
编译链接的过程
hello.c函数
#include<stdio.h>
int main()
{printf("Hello,World!");
return 0;
}
命令
gcc -E hello.c -o hello.i//预处理
gcc -S hello.i -o hello.s//编译
gcc -c hello.s -o hello.o//汇编
gcc hello.o -o hello//链接
ELF可执行文件
结构:
示例:
动态连接库
动态链接分为可执行程序装载时动态链接和运行时动态链接。
shlibexample.h
#ifndef _SH_LIB_EXAMPLE_H_
#define _SH_LIB_EXAMPLE_H_
#define SUCCESS 0
#define FAILURE (-1)
#ifdef __cplusplus
extern "C" {
#endif
/*
* Shared Lib API Example
* input : none
* output : none
* return : SUCCESS(0)/FAILURE(-1)
*
*/
int SharedLibApi();
#ifdef __cplusplus
}
#endif
#endif /* _SH_LIB_EXAMPLE_H_ */
shlibexample.c
#include <stdio.h>
#include "shlibexample.h"
/*
* Shared Lib API Example
* input : none
* output : none
* return : SUCCESS(0)/FAILURE(-1)
*
*/
int SharedLibApi()
{
printf("This is a shared libary!\n");
return SUCCESS;
}
编译生成so文件
gcc -shared shlibexample.c -o libshlibexample.so -m32
dllibexample.h
#ifndef _DL_LIB_EXAMPLE_H_
#define _DL_LIB_EXAMPLE_H_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Dynamical Loading Lib API Example
* input : none
* output : none
* return : SUCCESS(0)/FAILURE(-1)
*
*/
int DynamicalLoadingLibApi();
#ifdef __cplusplus
}
#endif
#endif /* _DL_LIB_EXAMPLE_H_ */
dllibexample.c
#include <stdio.h>
#include "dllibexample.h"
#define SUCCESS 0
#define FAILURE (-1)
/*
* Dynamical Loading Lib API Example
* input : none
* output : none
* return : SUCCESS(0)/FAILURE(-1)
*
*/
int DynamicalLoadingLibApi()
{
printf("This is a Dynamical Loading libary!\n");
return SUCCESS;
}
编译生成so文件
gcc -shared dllibexample.c -o libdllibexample.so -m32
main.c
int main()
{
printf("This is a Main program!\n");
/* Use Shared Lib */
printf("Calling SharedLibApi() function of libshlibexample.so!\n");
SharedLibApi();
/* Use Dynamical Loading Lib */
void * handle = dlopen("libdllibexample.so",RTLD_NOW);
if(handle == NULL)
{
printf("Open Lib libdllibexample.so Error:%s\n",dlerror());
return FAILURE;
}
int (*func)(void);
char * error;
func = dlsym(handle,"DynamicalLoadingLibApi");
if((error = dlerror()) != NULL)
{
printf("DynamicalLoadingLibApi not found:%s\n",error);
return FAILURE;
}
printf("Calling DynamicalLoadingLibApi() function of libdllibexample.so!\n");
func();
dlclose(handle);
return SUCCESS;
}
编译main.c
gcc main.c -o main -L/home/shiyanlou -lshlibexample -ldl -m32
export LD_LIBRARY_PATH=$PWD
./main
gdb跟踪分析execve
添加exec函数
int Exec(int argc, char *argv[])
{
int pid;
/* fork another process */
pid = fork();
if (pid < 0)
{
/* error occurred */
fprintf(stderr,"Fork Failed!");
exit(-1);
}
else if (pid == 0)
{
/* child process */
printf("This is Child Process!\n");
execlp("/hello","hello",NULL);
}
else
{
/* parent process */
printf("This is Parent Process!\n");
/* parent will wait for the child to complete*/
wait(NULL);
printf("Child Complete!\n");
}
}
修改main函数
MenuConfig("exec","Execute a program",Exec);
help命令可以看到添加了exec函数
跟踪调试
3.分析与总结
1.新的可执行程序在执行时是从其程序入口点开始执行的。在调用 `execve` 系统调用后,操作系统会加载新的程序映像到进程的地址空间,并将控制权转移给新程序的入口点。
2.在静态链接的可执行程序中,所有的依赖关系和库都已经被编译到可执行文件中,因此在执行 `execve` 后,新的程序完全独立于系统中的其他库。相反,在动态链接的可执行程序中,一些库和依赖项在运行时才会被加载,所以在执行 `execve` 后,动态链接程序可能会有一些区别。
3.exec*
函数族包含execve
, execl
, execv
等