Skip to content

Instantly share code, notes, and snippets.

@user202729
Last active December 7, 2024 10:39
Show Gist options
  • Save user202729/9fd7947509e15ffba62484969032fd23 to your computer and use it in GitHub Desktop.
Save user202729/9fd7947509e15ffba62484969032fd23 to your computer and use it in GitHub Desktop.
Make process allow gdb to attach to it

For an answer to gdb - Transferring control of ptrace to another process - Unix & Linux Stack Exchange.

To run:

[]$ gcc double-fork-A.c -o A
[]$ gcc -g double-fork-B.c -o B
[]$ ./A
Read from B: 123
No symbol table is loaded.  Use the "file" command.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
0x0000123456789123 in read () from /usr/lib/libc.so.6
#5  0x0000123456789123 in main () at B.c:9
[Inferior 1 (process 123456) detached]

[]$ gcc prctl-A.c -o A
[]$ gcc -g prctl-B.c -o B
[]$ ./A  # need to interrupt manually below
Read from B: 123
No symbol table is loaded.  Use the "file" command.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
0x0000123456789123 in read () from /usr/lib/libc.so.6
#5  0x0000123456789123 in main () at B.c:9
[Inferior 1 (process 123456) detached]
^C
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main() {
int pipe_a_a1[2];
if (pipe(pipe_a_a1) == -1) {
perror("pipe");
exit(1);
}
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(1);
}
pid_t pid = fork();
if (pid == 0) { // Child process (A1)
close(pipe_a_a1[1]); // Close write end
pid_t b_pid = fork();
if (b_pid == 0) { // B process
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
execl("./B", "B", NULL);
perror("execl");
exit(1);
}
close(pipefd[1]);
char buffer[256];
read(pipe_a_a1[0], buffer, sizeof(buffer)); // Wait for signal from A
close(pipe_a_a1[0]);
char pid_str[16];
snprintf(pid_str, sizeof(pid_str), "%d", b_pid);
execl("/usr/bin/gdb", "gdb", "-p", pid_str, "-batch", "-ex", "bt", NULL);
perror("execl");
exit(1);
} else { // Parent process (A)
close(pipe_a_a1[0]); // Close read end
close(pipefd[1]);
char buffer[256];
read(pipefd[0], buffer, sizeof(buffer));
printf("A read from B: %s", buffer);
sleep(1); // Give B time to reach the blocking read
write(pipe_a_a1[1], "go", 2); // Signal A1 to exec gdb
close(pipe_a_a1[1]);
wait(NULL); // Wait for A1 to finish
}
return 0;
}
#include <stdio.h>
int main() {
printf("123\n");
fflush(stdout);
char buffer[256];
fgets(buffer, sizeof(buffer), stdin);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <sys/prctl.h>
int main() {
int pipefd[2];
pid_t pid;
if (pipe(pipefd) == -1) {
perror("pipe");
exit(1);
}
pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
} else if (pid == 0) {
// Child process (B)
prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0);
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
execl("./B", "B", NULL);
perror("execl");
exit(1);
} else {
// Parent process (A)
close(pipefd[1]);
char buffer[256];
read(pipefd[0], buffer, sizeof(buffer));
printf("Read from B: %s", buffer);
// Attach gdb to B
char pid_str[16];
snprintf(pid_str, sizeof(pid_str), "%d", pid);
pid_t gdb_pid = fork();
if (gdb_pid == 0) {
execl("/usr/bin/gdb", "gdb", "-p", pid_str, "-batch", "-ex", "bt", NULL);
perror("execl");
exit(1);
}
// Wait for both processes to finish
waitpid(pid, NULL, 0);
waitpid(gdb_pid, NULL, 0);
}
return 0;
}
#include <stdio.h>
#include <unistd.h>
int main() {
printf("123\n");
fflush(stdout);
char buffer[256];
fgets(buffer, sizeof(buffer), stdin);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment