Re: Segmentation fault details?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Aug 11, 2008 at 2:37 PM, Wang Yi <leonidwang@xxxxxxxxx> wrote:
> Hi, all!
>  I'd like to know some details about segmentation fault.
>  What I mean is when a program accesses invalid memory area, it will
> get a SIGSEGV signal from kernel, and a message "Segmentation fault".
>  I also find that dmesg can show we some details like this:
>  ProgramName[Pid]: segfault at xxxx eip xxxx esp xxxx error x
>  It is useful and provides the first-step information for further
> debug/analysis.
>  My question is how dmesg gets the information, and if there are any
> programmable interfaces we can call to get this. (e.g. we
> can write sig handler for a program to print this message and maybe do
> some auto analysis)
>  Thank you.
> Leo

The decent ways u are looking for, is to look at how segmentation
fault is handled, ie do_page_fault() function:

(the following error_code documentation is fantastic - 2.6.20 kernel,
but the latest linus git tree for 2.6.26 is completely missing in this
aspect).

/*
 * This routine handles page faults.  It determines the address,
 * and the problem, and then passes it off to one of the appropriate
 * routines.
 *
 * error_code:
 *      bit 0 == 0 means no page found, 1 means protection fault
 *      bit 1 == 0 means read, 1 means write
 *      bit 2 == 0 means kernel, 1 means user-mode
 *      bit 3 == 1 means use of reserved bit detected
 *      bit 4 == 1 means fault was an instruction fetch
 */
fastcall void __kprobes do_page_fault(struct pt_regs *regs,
                                      unsigned long error_code)
{
        /* get the address */
        address = read_cr2();====> from the CR2 register, u get the
address where it faulted.   And then further down below the same
function:

                printk(" at virtual address %08lx\n",address);
                printk(KERN_ALERT " printing eip:\n");
                printk("%08lx\n", regs->eip);
        }
        page = read_cr3();
        page = ((unsigned long *) __va(page))[address >> 22];
        if (oops_may_print())
                printk(KERN_ALERT "*pde = %08lx\n", page);

here u can get the EIP (which is the currently to-be-executed
instruction) and page information from cr3 etc.

These information are arch-specific: register values etc.

And also looking at mm/page_alloc.c:bad_page() (which implement the
arch-independent part):

static void bad_page(struct page *page)
{
        printk(KERN_EMERG "Bad page state in process '%s'\n"
                KERN_EMERG "page:%p flags:0x%0*lx mapping:%p
mapcount:%d count:%d\n"
                KERN_EMERG "Trying to fix it up, but a reboot is needed\n"
                KERN_EMERG "Backtrace:\n",
                current->comm, page, (int)(2*sizeof(unsigned long)),
                (unsigned long)page->flags, page->mapping,
                page_mapcount(page), page_count(page));
        dump_stack();
        page->flags &= ~(1 << PG_lru    |
                        1 << PG_private |
                        1 << PG_locked  |
                        1 << PG_active  |
                        1 << PG_dirty   |
                        1 << PG_reclaim |
                        1 << PG_slab    |
                        1 << PG_swapcache |
                        1 << PG_writeback |
                        1 << PG_buddy );
        set_page_count(page, 0);
        reset_page_mapcount(page);
        page->mapping = NULL;
        add_taint(TAINT_BAD_PAGE);
}

as u can see, accessing global variable like "current" should solve
some of your queries....but there may be other global variables u can
use to get the info - just grep for LIST_HEAD in mm/*.c, or
EXPORT_SYMBOL mm/*.c.   Many ways.....


-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux