The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"проблема с ptrace"
Отправлено NuINu, 16-Ноя-08 21:24 
>>А вообще мне нужно если программа завершилась сохранить значения ее регистров и
>>последний фрейм стека.
>
>Я хотел сказать если программа завершилась с ощибкой.

это кончено не моя тема, ну вот что я написал полазив в инете и посмотрев твою программу, это небольшая демка приблизительно показывающая как ведет себе процесс.

#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
ну и ман.

 

Ваше сообщение
Имя*:
EMail:
Для отправки новых сообщений в текущей нити на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
  Введите код, изображенный на картинке: КОД
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.

На сайте действует частичное премодерирование - после публикации некоторые сообщения от анонимов могут автоматически скрываться ботом. После проверки модератором ошибочно скрытые сообщения раскрываются. Для ускорения раскрытия можно воспользоваться ссылкой "Сообщить модератору", указав в качестве причины обращения "скрыто по ошибке".



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру