OLD | NEW |
1 /* This testcase is part of GDB, the GNU debugger. | 1 /* This testcase is part of GDB, the GNU debugger. |
2 | 2 |
3 Copyright 2009-2012 Free Software Foundation, Inc. | 3 Copyright 2009-2012 Free Software Foundation, Inc. |
4 | 4 |
5 This program is free software; you can redistribute it and/or modify | 5 This program is free software; you can redistribute it and/or modify |
6 it under the terms of the GNU General Public License as published by | 6 it under the terms of the GNU General Public License as published by |
7 the Free Software Foundation; either version 3 of the License, or | 7 the Free Software Foundation; either version 3 of the License, or |
8 (at your option) any later version. | 8 (at your option) any later version. |
9 | 9 |
10 This program is distributed in the hope that it will be useful, | 10 This program is distributed in the hope that it will be useful, |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 GNU General Public License for more details. | 13 GNU General Public License for more details. |
14 | 14 |
15 You should have received a copy of the GNU General Public License | 15 You should have received a copy of the GNU General Public License |
16 along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 |
18 Do not use threads as we need to exploit a bug in LWP code masked by the | 18 Test that GDB doesn't lose an event for a thread it didn't know |
19 threads code otherwise. | 19 about, until an event is reported for it. */ |
20 | |
21 INFERIOR_PTID must point to exited LWP. Here we use the initial LWP as it | |
22 is automatically INFERIOR_PTID for GDB. | |
23 | |
24 Finally we need to call target_resume (RESUME_ALL, ...) which we invoke by | |
25 NEW_THREAD_EVENT (called from the new LWP as initial LWP is exited now). */ | |
26 | 20 |
27 #define _GNU_SOURCE | 21 #define _GNU_SOURCE |
28 #include <sched.h> | 22 #include <sched.h> |
29 #include <assert.h> | 23 #include <assert.h> |
| 24 #include <stdlib.h> |
| 25 #include <signal.h> |
| 26 #include <sys/types.h> |
30 #include <unistd.h> | 27 #include <unistd.h> |
31 #include <stdlib.h> | 28 #include <sys/syscall.h> |
32 | 29 |
33 #include <features.h> | 30 #include <features.h> |
34 #ifdef __UCLIBC__ | 31 #ifdef __UCLIBC__ |
35 #if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__)) | 32 #if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__)) |
36 #define HAS_NOMMU | 33 #define HAS_NOMMU |
37 #endif | 34 #endif |
38 #endif | 35 #endif |
39 | 36 |
40 #define STACK_SIZE 0x1000 | 37 #define STACK_SIZE 0x1000 |
41 | 38 |
42 static int | 39 static int |
43 fn_return (void *unused) | 40 tkill (int lwpid, int signo) |
44 { | 41 { |
45 return 0;» /* at-fn_return */ | 42 return syscall (__NR_tkill, lwpid, signo); |
| 43 } |
| 44 |
| 45 static pid_t |
| 46 gettid (void) |
| 47 { |
| 48 return syscall (__NR_gettid); |
46 } | 49 } |
47 | 50 |
48 static int | 51 static int |
49 fn (void *unused) | 52 fn (void *unused) |
50 { | 53 { |
51 int i; | 54 tkill (gettid (), SIGUSR1); |
52 unsigned char *stack; | |
53 int new_pid; | |
54 | |
55 i = sleep (1); | |
56 assert (i == 0); | |
57 | |
58 stack = malloc (STACK_SIZE); | |
59 assert (stack != NULL); | |
60 | |
61 new_pid = clone (fn_return, stack + STACK_SIZE, CLONE_FILES | |
62 #if defined(__UCLIBC__) && defined(HAS_NOMMU) | |
63 » » | CLONE_VM | |
64 #endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */ | |
65 » » , NULL, NULL, NULL, NULL); | |
66 assert (new_pid > 0); | |
67 | |
68 return 0; | 55 return 0; |
69 } | 56 } |
70 | 57 |
71 int | 58 int |
72 main (int argc, char **argv) | 59 main (int argc, char **argv) |
73 { | 60 { |
74 unsigned char *stack; | 61 unsigned char *stack; |
75 int new_pid; | 62 int new_pid; |
76 | 63 |
77 stack = malloc (STACK_SIZE); | 64 stack = malloc (STACK_SIZE); |
78 assert (stack != NULL); | 65 assert (stack != NULL); |
79 | 66 |
80 new_pid = clone (fn, stack + STACK_SIZE, CLONE_FILES | 67 new_pid = clone (fn, stack + STACK_SIZE, CLONE_FILES |
81 #if defined(__UCLIBC__) && defined(HAS_NOMMU) | 68 #if defined(__UCLIBC__) && defined(HAS_NOMMU) |
82 | CLONE_VM | 69 | CLONE_VM |
83 #endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */ | 70 #endif /* defined(__UCLIBC__) && defined(HAS_NOMMU) */ |
84 , NULL, NULL, NULL, NULL); | 71 , NULL, NULL, NULL, NULL); |
85 assert (new_pid > 0); | 72 assert (new_pid > 0); |
86 | 73 |
87 return 0; | 74 return 0; |
88 } | 75 } |
OLD | NEW |