#include #include #include // For the syntax of 'fork' and 'execvp', see 'man 3 fork' and 'man 3 execvp' void print_string(); void fork_a_command(char *cmd); int main(int argc, char *argv[]) { print_string(); printf("\n"); fork_a_command("ls"); return 0; } void print_string() { char str[] = "abc"; printf("string: %s\n", str); } void fork_a_command(char *cmd) { printf("*** The child will be created and execute 'ls'\n"); int childpid = fork(); // create new process in process table // The new child process will look like clone of this process. if (childpid == 0) { // if this is a child char *args[] = {cmd, NULL}; execvp(cmd, args); } else { // else this is the original parent process that ran 'main'. sleep(2); // wait 2 seconds and then print. printf("*** The child should now have executed 'ls'\n"); } } /************************************************************ * GDB EXAMPLE * LOGIN-STUDENTS:tmp% gdb ./a.out * ... * Reading symbols from /tmp/hw1/a.out...done. * (gdb) break main * Breakpoint 1 at 0x4006ac: file fork-exec-example.c, line 12. * (gdb) where * No stack. * (gdb) run * Starting program: /tmp/hw1/./a.out * * Breakpoint 1, main (argc=1, argv=0x7fffffffdc78) at fork-exec-example.c:12 * 12 print_string(); * Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_64 * (gdb) where * #0 main (argc=1, argv=0x7fffffffdc78) at fork-exec-example.c:12 * (gdb) list * 7 void print_string(); * 8 void fork_a_command(char *cmd); * 9 * 10 int main(int argc, char *argv[]) { * 11 * 12 print_string(); * 13 printf("\n"); * 14 fork_a_command("ls"); * 15 return 0; * 16 } * (gdb) echo Try ^Xa to temporarily switch to listing-mode, and then ^Xa\n * Try ^Xa to temporarily switch to listing-mode, and then ^Xa * (gdb) next * string: abc * 13 printf("\n"); * (gdb) next * * 14 fork_a_command("ls"); * (gdb) step * fork_a_command (cmd=0x4007f0 "ls") at fork-exec-example.c:24 * 24 printf("*** The child will be created and execute /bin/ls\n"); * (gdb) list * 19 char str[] = "abc"; * 20 printf("string: %s\n", str); * 21 } * 22 * 23 void fork_a_command(char *cmd) { * 24 printf("*** The child will be created and execute /bin/ls\n"); * 25 int childpid = fork(); // create new process in process table * 26 // The new child process will look like clone of this process. * 27 * 28 if (childpid == 0) { // if this is a child * (gdb) next * *** The child will be created and execute 'ls' * 25 int childpid = fork(); // create new process in process table * (gdb) next * [Detaching after fork from child process 29178] * 28 if (childpid == 0) { // 'childpid == 0' if this is a child * (gdb) a.out fork-exec.c fork-exec-example.c fork-exec.in hw1.txt Makefile * list * 23 void fork_a_command(char *cmd) { * 24 printf("*** The child will be created and execute /bin/ls\n"); * 25 int childpid = fork(); // create new process in process table * 26 // The new child process will look like clone of this process. * 27 * 28 if (childpid == 0) { // if this is a child * 29 char *args[] = {cmd, NULL}; * 30 execvp(cmd, args); * 31 } else { // else this is the original parent process that ran 'main'. * 32 sleep(2); // wait 2 seconds and then print. * (gdb) where * #0 fork_a_command (cmd=0x4007f0 "ls") at fork-exec-example.c:28 * #1 0x00000000004006ca in main (argc=1, argv=0x7fffffffdc78) * at fork-exec-example.c:14 * (gdb) ptype cmd * type = char * * (gdb) ptype childpid * type = int * (gdb) print childpid * $1 = 29178 * (gdb) next * 32 sleep(2); // wait 2 seconds and then print. * (gdb) next * 33 printf("*** The child should now have executed /bin/ls\n"); * (gdb) next * *** The child should now have executed 'ls' * 35 } * (gdb) next * main (argc=1, argv=0x7fffffffdc78) at fork-exec-example.c:15 * 15 return 0; * (gdb) next * 16 } * (gdb) next * 0x00007ffff7a2f555 in __libc_start_main () from /lib64/libc.so.6 * (gdb) quit * A debugging session is active. * * Inferior 1 [process 29085] will be killed. * * Quit anyway? (y or n) y ************************************************************/