>>А вообще мне нужно если программа завершилась сохранить значения ее регистров и
>>последний фрейм стека.
>
>Я хотел сказать если программа завершилась с ощибкой. это кончено не моя тема, ну вот что я написал полазив в инете и посмотрев твою программу, это небольшая демка приблизительно показывающая как ведет себе процесс.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <errno.h>
#include <signal.h>
#include <linux/user.h>
int chld_count;
void analize_status(pid_t pid, int status) {
printf("Analize return code(%i) process pid = %u\n", status, pid);
if(WIFEXITED(status)) {
fprintf(stdout, "Child process exited normally!\n");
}
if(WIFSIGNALED(status)) {
fprintf(stdout, "Child process terminated by signal %d!\n",WTERMSIG(status));
}
if(WIFSTOPPED(status)) {
fprintf(stdout, "waitpid() return - child STOPED!!!\n");
} else {
fprintf(stdout, "waitpid() return - child not stoped!!!\n");
}
}
void printregs(struct user_regs_struct *regs) {
fprintf(stdout, "Registers status:\n"
" eax=0x%08lX esi=0x%08lX ds=0x%04X\n"
" ebx=0x%08lX edi=0x%08lX es=0x%04X\n"
" ecx=0x%08lX esp=0x%08lX ebp=0x%08lX ss=0x%04X\n"
" edx=0x%08lX eip=0x%08lX cs=0x%04X\n"
" eflags=0x%08lX, orig_eax=0x%08lX\n",
regs->ax, regs->si, (int)regs->ds,
regs->bx, regs->di, (int)regs->es,
regs->cx, regs->sp, regs->bp, (int)regs->ss,
regs->dx, regs->ip, (int)regs->cs,
regs->flags, regs->orig_ax);
}
void child_handler(int signo) {
printf("Main: get child signal %i\n", signo);
pid_t pid;
int status;
int i;
struct user_regs_struct regs;
while((pid = waitpid(-1, &status, WNOHANG)) > 0) {
printf("signal: pid: %i\n", pid);
analize_status(pid, status);
if(ptrace(PTRACE_GETREGS, pid, NULL, ®s) != 0)
printf("ptrace error: %s\n", strerror(errno));
else
printregs(®s);
chld_count--;
}
}
int main(int argc, char *argv[])
{
int wait_val;
int status;
pid_t pid;
struct user_regs_struct regs;
switch (pid = fork()) {
case -1:
perror("fork");
break;
case 0: /* запуск дочернего процесса */
printf("Child: Before start trace!\n");
ptrace(PTRACE_TRACEME, 0, 0, 0);
printf("Child: After start trace!\n");
execl("test_wait_sig2", "test_wait_sig", "aaaaaaaaaaaa", NULL);
break;
default: /* РОДИТЕЛЬСКИЙ ПРОЦЕСС */
printf("Run child pid: %u\n", pid);
chld_count = 1;
//подождем первого сигнала от дочернего процесса
waitpid(pid, &status, 0);
analize_status(pid, status);
//Запускаем трассируемый процесс без всякий условий (пусть выполняется).
//ptrace(PTRACE_SINGLESTEP, pid, 0, 0);
ptrace(PTRACE_CONT, pid, 0, 0);
//сами засыпаем секунд на 5
printf("Parent: sleeping ......\n");
sleep(5);
//шлем сигнал процессу child
printf("Parent: Killed child!\n");
kill(pid, SIGSEGV);
//снова ждем остановки дочернего процесса
waitpid(pid, &status, 0);
//возврат просто от того что ребенок остановился?
printf("Parent: retun from wait success(%i)\n", status);
analize_status(pid, status);
//НЕТ ребенок получил какой то сигнал!!! и его не обработал, вернем его ему!(мы то знаем что за сигнал он поулчил)
if (ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACEEXIT) != 0) {
perror("ptrace: error set option PTRACE_O_TRACEEXIT\n");
}
if (ptrace(PTRACE_CONT, pid, 0, SIGSEGV) != 0) {
perror("ptrace: error PTRACE_CONT");
}
//дождемся останова! это должна быть функция exit
waitpid(pid, &status, 0);
analize_status(pid, status);
if(ptrace(PTRACE_GETREGS, pid, NULL, ®s) != 0)
printf("ptrace error PTRACE_GETREGS: %s\n", strerror(errno));
else
printregs(®s);
break;
}
//установим обработчик завершения дочернего процесса
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = &child_handler;
sigaction(SIGCHLD, &sa, NULL);
if (ptrace(PTRACE_CONT, pid, 0, SIGSEGV) != 0) {
perror("ptrace: error last run child PTRACE_O_TRACEEXIT!\n");
}
while(chld_count > 0 ) {
sleep(2);
printf("Parent: wait any kill - child please!!!\n");
}
return 0;
}
вот что она мне выдала:
Run child pid: 3324
Child: Before start trace!
Child: After start trace!
Analize return code(1407) process pid = 3324
waitpid() return - child STOPED!!!
Parent: sleeping ......
run child process 3324
run child process 3324
run child process 3324
run child process 3324
run child process 3324
Parent: Killed child!
Parent: retun from wait success(2943)
Analize return code(2943) process pid = 3324
waitpid() return - child STOPED!!!
Analize return code(394623) process pid = 3324
waitpid() return - child STOPED!!!
Registers status:
eax=0x00000033 esi=0x00000073 ds=0xBFF95188
ebx=0xBFD27EF8 edi=0x00200246 es=0x80484E8
ecx=0x000000A2 esp=0xBFF96422 ebp=0x00000000 ss=0xB7F71FBE
edx=0xB7F2F77B eip=0x0000007B cs=0x0001
eflags=0x00000000, orig_eax=0xBFD27D30
Main: get child signal 17
signal: pid: 3324
Analize return code(11) process pid = 3324
Child process terminated by signal 11!
waitpid() return - child not stoped!!!
ptrace error: No such process
Parent: wait any kill - child please!!!
--------------------------------------------------
смысл такой что сигнал в трассируемый процесс не передается непосредственно, а при получении сигнала этот процесс останавливается и управление передается трассирующему процессу. а если мы хотим что бы этот сигнал обработался надо его самостоятельно передать в трассируемый процесс. да если чилд обрабатывает сигнал, то на ретурн код будет 0.т.е если в нем установить обработчик этого сигнала.
что я смотрел:
http://www.dore.ru/perl/nntp.pl?f=1&gid=22&mid=16862
http://gazette.linux.ru.net/lg81/sandeep.html
ну и ман.