bug-gdb
[Top][All Lists]
Advanced

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

Problem of GDB interaction with interrupted system calls


From: Alexandre Rusev
Subject: Problem of GDB interaction with interrupted system calls
Date: Fri, 30 Oct 2009 19:10:58 +0300
User-agent: Thunderbird 1.5.0.8 (X11/20060911)

Hi.


When the program at ht end of message debugged under GDB is stopped with
Ctrl+C
it's usually found in interrupted system call. (The same result is
observed for x86 and PPC with kernels 2.6.18 and 2.6.28)

(gdb) where
#0  0xb7fe2424 in __kernel_vsyscall ()
#1  0xb7f36ad0 in nanosleep () from /lib/libc.so.6
#2  0xb7f3690e in sleep () from /lib/libc.so.6
#3  0x08048600 in qqq () at testBT2.c:45
#4  0x080487a5 in eee () at testBT2.c:73
#5  0x0804846a in main () at testBT2.c:17

The PC is pointing at the next instruction, accordingly to GDB.
But the kernel tries to restart syscall by means of changing PC to PC-4
(in case of PowerPC and to some other value for x86)
and it does it's change to PC after the user continues execution of
program in GDB with "cont" or "si" command.

The issue is that if user changed PC at this point or uses "call
<func_name>" GDB command, the both changes to PC
are added (as kernel uses PC relative change i.e. PC - 4), and the
program continues execution at absolutely wrong place.

The issue may be gracefully observed if breakpoint is set just before
<func_name> and then PC is changed to the <func_name> address.
In such case the breakpoint is hit while it must not be.



#include <stdio.h>
#include <stdlib.h>

void qqq();
void www();
void eee();

void * xrealloc(void*, int);

int main(void)
{
        eee();
    return EXIT_SUCCESS;
}

void qqq() {
    void *a[256];
    size_t i, n;

    for (i = 0; i < 256; i++)
    {
        n = (size_t) ((rand() * 256.0) / (RAND_MAX + 1.0)) + 1;
        a[i] = malloc(n);
    }
    for (i = 256; i > 0; i--)
    {
        n = (size_t) ((rand() * 256.0) / (RAND_MAX + 1.0)) + 1;
        a[i - 1] = xrealloc(a[i - 1], n);
    }
    sleep(1);
    for (i = 0; i < 256; i += 2)
        free(a[i]);
    for (i = 256; i > 0; i -= 2)
        free(a[i - 1]);
    sleep(1);
}

void www() {
    void *a[256];
    size_t i, n;

    for (i = 0; i < 256; i++)
    {
        n = (size_t) ((rand() * 256.0) / (RAND_MAX + 1.0)) + 1;
        a[i] = malloc(n);
    }
    for (i = 256; i > 0; i--)
    {
        n = (size_t) ((rand() * 256.0) / (RAND_MAX + 1.0)) + 1;
        a[i - 1] = realloc(a[i - 1], n);
    }
    sleep(1);
    for (i = 0; i < 256; i += 2)
        free(a[i]);
    for (i = 256; i > 0; i -= 2)
        free(a[i - 1]);
    sleep(1);
}

void eee() {

        while (1) {
                qqq();

                www();

        }
}

void * xrealloc(void* addr, int n) {
        return realloc(addr, n);
}







reply via email to

[Prev in Thread] Current Thread [Next in Thread]