diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 885941e..11e4361 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,16 +1,18 @@ FROM mcr.microsoft.com/devcontainers/base:dev-ubuntu-20.04 -# 安装 build-essential +# 安装 build-essential 和调试工具 RUN apt-get update && \ - apt-get install -y --no-install-recommends build-essential && \ -#清理 apt 缓存 + apt-get install -y --no-install-recommends \ + build-essential \ + gdb \ # 添加GDB调试器 + gcc \ + make && \ + # 清理 apt 缓存 apt-get autoremove -y && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -# 设置工作目录(可选) -WORKDIR /workspace +# 设置工作目录 +WORKDIR /workspace -# 可以添加其他的自定义设置,比如复制源代码等 - -CMD ["/bin/bash"] # 可以添加默认命令,比如进入 bash \ No newline at end of file +CMD ["/bin/bash"] \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3205654..6cd008a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,18 +1,23 @@ { "name": "DevContainerExample", - "image": "mcr.microsoft.com/devcontainers/base:dev-ubuntu-20.04", + "postCreateCommand": "sudo apt-get update && sudo apt-get install -y gdb && make", "customizations": { - "vscode": { - "settings": {}, - "extensions": [ - ] - } + "vscode": { + "settings": { + "debug.onTaskErrors": "debugAnyway" + }, + "extensions": [ + "ms-vscode.cpptools" + ] + } }, "portsAttributes": { - "3000": { - "label": "Web Server", - "onAutoForward": "notify" - } - } - } \ No newline at end of file + "3000": { + "label": "Web Server", + "onAutoForward": "notify" + } + }, + "initializeCommand": "gdb -ex 'set confirm off' -ex quit", // 初始化GDB配置 + "postAttachCommand": "make debug" // 假设你的Makefile有debug目标 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a57dd98 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,65 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug fork", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/fork", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "build-fork" + }, + { + "name": "Debug execlp", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/execlp", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "build-execlp" + }, + { + "name": "Debug All", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/fork", // 默认调试fork + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "preLaunchTask": "build-all" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..251d1df --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,35 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build-fork", + "type": "shell", + "command": "make", + "args": ["fork"], + "group": "build", + "problemMatcher": ["$gcc"] + }, + { + "label": "build-execlp", + "type": "shell", + "command": "make", + "args": ["execlp"], + "group": "build", + "problemMatcher": ["$gcc"] + }, + { + "label": "build-all", + "type": "shell", + "command": "make", + "group": "build", + "problemMatcher": ["$gcc"] + }, + { + "label": "clean", + "type": "shell", + "command": "make", + "args": ["clean"], + "group": "build" + } + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile index e1ec215..b22fcf0 100644 --- a/Makefile +++ b/Makefile @@ -2,28 +2,54 @@ # Makefile for base example # include ./make.h - # 目标和源文件 TARGETS = fork execlp SOURCES = $(wildcard $(SRC_DIR)/*.c) # 找到所有的 .c 文件 OBJECTS = $(patsubst $(SRC_DIR)/%.c,%.o,$(SOURCES)) # 将 .c 替换为 .o -# 默认目标 -all: $(TARGETS) +# 调试标志 +DEBUG_FLAGS = -g -O0 +CFLAGS += $(DEBUG_FLAGS) # 确保包含调试信息 -# 链接目标文件生成可执行文件 +# 默认目标 +all: $(TARGETS) + +# 调试目标(与preLaunchTask对应) +debug: CFLAGS += -DDEBUG -Wall -Wextra +debug: $(TARGETS) + +# 链接目标文件生成可执行文件 fork: fork.o $(CC) -o fork fork.o execlp: execlp.o $(CC) -o execlp execlp.o -# 从 .c 文件编译生成 .o 文件 +# 从 .c 文件编译生成 .o 文件 %.o: $(SRC_DIR)/%.c $(CC) $(CFLAGS) $(COMMON_INCLUDE_DIRS) -c $< -o $@ +# 清理目标 clean: - $(RM) -f $(TARGETS) $(OBJECTS) + $(RM) -f $(TARGETS) $(OBJECTS) *.o +# 运行目标 +run-fork: fork + ./fork +run-execlp: execlp + ./execlp + +# GDB调试目标 +gdb-fork: fork + gdb ./fork + +gdb-execlp: execlp + gdb ./execlp + +# 安装目录结构(如果需要) +install-dirs: + mkdir -p $(SRC_DIR) $(BUILD_DIR) + +.PHONY: all debug clean run-fork run-execlp gdb-fork gdb-execlp install-dirs \ No newline at end of file diff --git a/src/execlp.c b/src/execlp.c index 8f077bf..49e757a 100644 --- a/src/execlp.c +++ b/src/execlp.c @@ -3,29 +3,37 @@ #include #include -int main(int argc, char * argv[]) +int main(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 */ - execlp("/bin/ls","ls",NULL); - } - else - { - /* parent process */ - /* parent will wait for the child to complete*/ - wait(NULL); - printf("Child Complete!"); - exit(0); - } -} - + (void)argc; // 明确标记未使用 + (void)argv; // 消除编译器警告 + + pid_t pid = fork(); // 使用pid_t类型更规范 + + if (pid < 0) { + /* 错误处理 */ + perror("Fork Failed"); + exit(EXIT_FAILURE); // 使用标准失败码 + } + else if (pid == 0) { + /* 子进程 */ + execlp("/bin/ls", "ls", (char *)NULL); // 确保NULL转换为(char *) + + // 如果exec失败才会执行到这里 + perror("Exec Failed"); + exit(EXIT_FAILURE); + } + else { + /* 父进程 */ + int status; + wait(&status); // 获取子进程退出状态 + + if (WIFEXITED(status)) { + printf("Child Completed with status: %d\n", WEXITSTATUS(status)); + } else { + printf("Child terminated abnormally\n"); + } + + exit(EXIT_SUCCESS); // 使用标准成功码 + } +} \ No newline at end of file