-
Notifications
You must be signed in to change notification settings - Fork 431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(ebpf): correct value of exit and signal code for sched_process_exit #4564
fix(ebpf): correct value of exit and signal code for sched_process_exit #4564
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!
As exit_code might contain a signal value, it would be great to extract that also, so a new arg "signal" should be added in the case of PF_SIGNALED is set.
ea18817
to
f6d22e2
Compare
2163ca3
to
b0a256a
Compare
7bd8240
to
d533a5f
Compare
When a process exits normally via exit(n), the exit code is stored in the upper byte (exit_code << 8). The lower byte is used for signal information if the process was terminated by a signal. Also, align the type of exit_code used at struct task_struct.
d533a5f
to
a13d497
Compare
@OriGlassman FYI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🚀
I've tested with this trigger:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
// Signal handler for SIGUSR1
void handle_sigusr1(int sig) {
printf("Child process %d received SIGUSR1\n", getpid());
}
int main() {
printf("Forking processes...\n");
// Create first child process
pid_t pid1 = fork();
if (pid1 == 0) {
printf("Child process 1 running, PID: %d\n", getpid());
sleep(10);
printf("Child process 1 exiting normally\n");
exit(1); // Exit with code 1
} else if (pid1 < 0) {
perror("fork");
return 1;
}
// Create second child process
pid_t pid2 = fork();
if (pid2 == 0) {
printf("Child process 2 running, PID: %d\n", getpid());
sleep(10);
printf("Child process 2 exiting normally\n");
exit(2); // Exit with code 2
} else if (pid2 < 0) {
perror("fork");
return 1;
}
// Create third child process (to be signaled and terminated, since it doesn't handle SIGUSR1)
pid_t pid3 = fork();
if (pid3 == 0) {
printf("Child process 3 running, PID: %d\n", getpid());
while (1) {
sleep(1); // Keep running until signaled
}
} else if (pid3 < 0) {
perror("fork");
return 1;
}
// Create fourth child process (to be signaled and handled)
pid_t pid4 = fork();
if (pid4 == 0) {
// Install signal handler for SIGUSR1
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handle_sigusr1;
sigaction(SIGUSR2, &sa, NULL);
printf("Child process 4 running, PID: %d\n", getpid());
sleep(10);
printf("Child process 4 killing itself\n");
kill(getpid(), SIGKILL);
} else if (pid4 < 0) {
perror("fork");
return 1;
}
// Create fourth child process (to be signaled and handled)
pid_t pid5 = fork();
if (pid5 == 0) {
// Install signal handler for SIGUSR2
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handle_sigusr1;
sigaction(SIGUSR2, &sa, NULL);
printf("Child process 5 running, PID: %d\n", getpid());
sleep(10);
printf("Child process 5 exiting normally\n");
exit(5); // Exit with code 5
} else if (pid4 < 0) {
perror("fork");
return 1;
}
// Parent process
sleep(1);
// Send SIGUSR1 to child processes 3 and 4
printf("Parent sending SIGUSR1 to child PID: %d\n", pid3);
kill(pid3, SIGUSR1);
printf("Parent sending SIGUSR2 to child PID: %d\n", pid4);
kill(pid4, SIGUSR2);
printf("Parent sending SIGUSR2 to child PID: %d\n", pid5);
kill(pid5, SIGUSR2);
// Wait for all child processes to finish
int status;
waitpid(pid1, &status, 0);
if (WIFEXITED(status)) {
printf("Child process 1 exited with status: %d\n", WEXITSTATUS(status));
}
waitpid(pid2, &status, 0);
if (WIFEXITED(status)) {
printf("Child process 2 exited with status: %d\n", WEXITSTATUS(status));
}
waitpid(pid3, &status, 0);
if (WIFSIGNALED(status)) {
printf("Child process 3 was terminated by signal: %d\n", WTERMSIG(status));
}
waitpid(pid4, &status, 0);
if (WIFSIGNALED(status)) {
printf("Child process 4 was terminated by signal: %d\n", WTERMSIG(status));
}
waitpid(pid5, &status, 0);
if (WIFEXITED(status)) {
printf("Child process 5 exited with status: %d\n", WEXITSTATUS(status));
}
printf("Parent process exiting\n");
exit(77);
}
And got the following output:
11:46:04:850047 1000 exiter 1405739 1405739 0 sched_process_exit exit_code: 0, signal_code: 10, process_group_exit: true
11:46:04:850112 1000 exiter 1405740 1405740 0 sched_process_exit exit_code: 0, signal_code: 9, process_group_exit: true
11:46:04:850122 1000 exiter 1405741 1405741 0 sched_process_exit exit_code: 5, signal_code: 0, process_group_exit: true
11:46:13:849992 1000 exiter 1405737 1405737 0 sched_process_exit exit_code: 1, signal_code: 0, process_group_exit: true
11:46:13:850050 1000 exiter 1405738 1405738 0 sched_process_exit exit_code: 2, signal_code: 0, process_group_exit: true
11:46:13:850373 1000 exiter 1405736 1405736 0 sched_process_exit exit_code: 77, signal_code: 0, process_group_exit: true
Thank you @geyslan for the test :) |
/fast-forward |
1. Explain what the PR does
a13d497 fix: get exit code and signal values
2. Explain how to test it
Use the following code to trigger:
Tracee before this PR:
Tracee after this PR:
3. Other comments
fix #4566