flat assembler
Message board for the users of flat assembler.

Index > Linux > Exception handling

Goto page Previous  1, 2, 3
Author
Thread Post new topic Reply to topic
f0dder



Joined: 19 Feb 2004
Posts: 3170
Location: Denmark
f0dder
After a bit of reading, it would seem that proper exception handling *is* possible - even if a bit clunky. The document I found basically hinted that you'd need a thread set up for handling async exceptions/signals properly... but at least sync exceptions/signals do get delivered to the thread that caused them.

I still think errno is bloody ugly though, even with the per-thread hack that violates "errno is an int" Smile
Post 03 Oct 2006, 11:08
View user's profile Send private message Visit poster's website Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 454
Location: Czech republic, Slovak republic
Feryno
Unfortunatelly I haven't found SYSCALL_SIGNAL, SYSCALL_SIGACTION in x64 Linux (but there is rt_sigaction, I'm going to try it).
Multithread idea looks well.
Skeleton for multiprocess handling for 64-bits (easy portable to 32-bit world) - may help for trying in multithread handling

Code:
start:

        mov     eax,sys_fork
        syscall                         ; make second copy of program
; child has return value=0, parent return value = child's PID
; see: man fork
        or      rax,rax
        js      exit1                   ; something went wrong...
        jnz     parent_proc

child_proc:
; see:
; man ptrace
; look for PTRACE_TRACEME
; Any signal delivered to this process will cause it to stop and its parent to
; be notified via wait.
        xor     r10,r10
        xor     edx,edx
        xor     esi,esi
        mov     edi,PTRACE_TRACEME
        mov     eax,sys_ptrace
        syscall

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; put the core of your program here ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

parent_proc:
        mov     [child_PID],rax

parent_signal_wait:
        xor     r10,r10
        mov     edx,WUNTRACED
        lea     rsi,[child_status]
;       or      rdi,-1
; use -1 for wait to child's children too, but we want to wait for child only
        mov     rdi,qword [child_PID]
        mov     eax,sys_wait4
        syscall
        or      rax,rax
        jns     wait_L1
msg_err_wait_exit:
        lea     rax,[msg_err_wait]
        jmp     exit_msg

wait_L1:
        mov     eax,dword [child_status]
WIFSTOPPED              =       7Fh
        test    al,WIFSTOPPED
        jnz     wait_L2
; Child exited ? Then we do the same...
; WEXITSTATUS eax
        and     eax,0000FF00h
        sar     eax,8

; al=exitstatus
; display the exit status
;...
        jmp     exit0

wait_L2:
; WIFSIGNALED eax
        and     eax,7Fh
        inc     eax
        sar     al,1

        jle     wait_L3

; display hexa content of AL register:
; ...

        jmp     exit0

wait_L3:
        mov     eax,dword [child_status]

        cmp     al,WIFSTOPPED
        jnz     wait_L7

;       WSTOPSIG        eax
        and     eax,0000FF00h
        sar     eax,8
; al holds signal now

; 0. display message with the signal number
; 1. then handle the exception and at the end choose only one of 1.A. or 1.B.
; 1.A. resume program:
;       mov     r10d,SIGCONT
;       xor     edx,edx
;       mov     rsi,qword [child_PID]
;       mov     edi,PTRACE_CONT
;       mov     eax,sys_ptrace
;       syscall
; 1.B. or kill the program:
;       xor     r10,r10
;       xor     edx,edx
;       mov     rsi,qword [child_PID]
;       mov     edi,PTRACE_KILL
;       mov     eax,sys_ptrace
;       syscall

wait_L7:
        jmp     parent_signal_wait

exit0:
        xor     edi,edi 
exit:   mov     eax,sys_exit
        syscall

exit1:  mov     edi,1
        jmp     exit
    

The above skeleton is from fdbg. I still don't know what to do when the child forks - something in the above code is missing. The above handling idea is the same as every debugger's job (it is an auto-debugger, or self-debugger).
Post 12 Jan 2007, 09:32
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 454
Location: Czech republic, Slovak republic
Feryno
if you want new thread instead of new process, then use
sys_clone with CLONE_THREAD
instead of
sys_fork

you need to mmap space for new thread (new stack, ...) before sys_clone

how to skip instruction causing singal ?
0. read registers sys_ptrace with PTRACE_GETREGS and get RIP (EIP) register
(offset of instruction pointer differs in x64 and x86 platform)
1. determine size of instruction:
1A read 16 bytes (2 qwords in x64, 4 dwords in x86) sys_ptrace PTRACE_PEEKTEXT
1B determine the size of the instruction by disassembling it, the most difficult task
you can use disasm engine for x64 or simplify it not to disassemble
the whole instruction but to determine instruction size only
I don't know whether there is any disasm engine for x86 written in asm
2. add instruction size to user.user_regs.rip (or ...eip)
3. write registers sys_ptrace PTRACE_SETREGS
4. continue run sys_ptrace PTRACE_CONT

After doing this you can only hope that skipping instruction doesn't alter program run too much...
Post 18 Jan 2007, 06:45
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.