1 /* This testcase is part of GDB, the GNU debugger. 2 3 Copyright 2018-2020 Free Software Foundation, Inc. 4 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 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 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/>. */ 17 18 /* This file contains a library that can be preloaded into GDB on Linux 19 using the LD_PRELOAD technique. 20 21 The library intercepts calls to WAITPID and SIGSUSPEND in order to 22 simulate the behaviour of a heavily loaded kernel. 23 24 When GDB wants to stop all threads in an inferior each thread is sent a 25 SIGSTOP, GDB will then wait for the signal to be received by the thread 26 with a waitpid call. 27 28 If the kernel is slow in either delivering the signal, or making the 29 result available to the waitpid call then GDB will enter a sigsuspend 30 call in order to wait for the inferior threads to change state, this is 31 signalled to GDB with a SIGCHLD. 32 33 A bug in GDB meant that in some cases we would deadlock during this 34 process. This was rarely seen as the kernel is usually quick at 35 delivering signals and making the results available to waitpid, so quick 36 that GDB would gather the statuses from all inferior threads in the 37 original pass. 38 39 The idea in this library is to rate limit calls to waitpid (where pid is 40 -1 and the WNOHANG option is set) so that only 1 per second can return 41 an answer. Any additional calls will report that no threads are 42 currently ready. This should match the behaviour we see on a slow 43 kernel. 44 45 However, given that usually when using this library, the kernel does 46 have the waitpid result ready this means that the kernel will never send 47 GDB a SIGCHLD. This means that when GDB enters sigsuspend it will block 48 forever. Alternatively, if GDB enters its polling loop the lack of 49 SIGCHLD means that we will never see an event on the child threads. To 50 resolve these problems the library intercepts calls to sigsuspend and 51 forces the call to exit if there is a pending waitpid result. Also, 52 when we know that there's a waitpid result that we've ignored, we create 53 a new thread which, after a short delay, will send GDB a SIGCHLD. */ 54 55 #define _GNU_SOURCE 56 57 #include <sys/types.h> 58 #include <sys/wait.h> 59 #include <sys/time.h> 60 #include <stdlib.h> 61 #include <stdio.h> 62 #include <dlfcn.h> 63 #include <string.h> 64 #include <stdarg.h> 65 #include <signal.h> 66 #include <errno.h> 67 #include <pthread.h> 68 #include <unistd.h> 69 70 /* Logging. */ 71 72 static void 73 log_msg (const char *fmt, ...) 74 { 75 #ifdef LOGGING 76 va_list ap; 77 78 va_start (ap, fmt); 79 vfprintf (stderr, fmt, ap); 80 va_end (ap); 81 #endif /* LOGGING */ 82 } 83 84 /* Error handling, message and exit. */ 85 86 static void 87 error (const char *fmt, ...) 88 { 89 va_list ap; 90 91 va_start (ap, fmt); 92 vfprintf (stderr, fmt, ap); 93 va_end (ap); 94 95 exit (EXIT_FAILURE); 96 } 97 98 /* Cache the result of a waitpid call that has not been reported back to 99 GDB yet. We only ever cache a single result. Once we have a result 100 cached then later calls to waitpid with the WNOHANG option will return a 101 result of 0. */ 102 103 static struct 104 { 105 /* Flag to indicate when we have a result cached. */ 106 int cached_p; 107 108 /* The cached result fields from a waitpid call. */ 109 pid_t pid; 110 int wstatus; 111 } cached_wait_status; 112 113 /* Lock to hold when modifying SIGNAL_THREAD_ACTIVE_P. */ 114 115 static pthread_mutex_t thread_creation_lock_obj = PTHREAD_MUTEX_INITIALIZER; 116 #define thread_creation_lock (&thread_creation_lock_obj) 117 118 /* This flag is only modified while holding the THREAD_CREATION_LOCK mutex. 119 When this flag is true then there is a signal thread alive that will be 120 sending a SIGCHLD at some point in the future. */ 121 122 static int signal_thread_active_p; 123 124 /* When we last allowed a waitpid to complete. */ 125 126 static struct timeval last_waitpid_time = { 0, 0 }; 127 128 /* The number of seconds that must elapse between calls to waitpid where 129 the pid is -1 and the WNOHANG option is set. If calls occur faster than 130 this then we force a result of 0 to be returned from waitpid. */ 131 132 #define WAITPID_MIN_TIME (1) 133 134 /* Return true (non-zero) if we should skip this call to waitpid, or false 135 (zero) if this waitpid call should be handled with a call to the "real" 136 waitpid function. Allows 1 waitpid call per second. */ 137 138 static int 139 should_skip_waitpid (void) 140 { 141 struct timeval *tv = &last_waitpid_time; 142 if (tv->tv_sec == 0) 143 { 144 if (gettimeofday (tv, NULL) < 0) 145 error ("error: gettimeofday failed\n"); 146 return 0; /* Don't skip. */ 147 } 148 else 149 { 150 struct timeval new_tv; 151 152 if (gettimeofday (&new_tv, NULL) < 0) 153 error ("error: gettimeofday failed\n"); 154 155 if ((new_tv.tv_sec - tv->tv_sec) < WAITPID_MIN_TIME) 156 return 1; /* Skip. */ 157 158 *tv = new_tv; 159 } 160 161 /* Don't skip. */ 162 return 0; 163 } 164 165 /* Perform a real waitpid call. */ 166 167 static pid_t 168 real_waitpid (pid_t pid, int *wstatus, int options) 169 { 170 typedef pid_t (*fptr_t) (pid_t, int *, int); 171 static fptr_t real_func = NULL; 172 173 if (real_func == NULL) 174 { 175 real_func = dlsym (RTLD_NEXT, "waitpid"); 176 if (real_func == NULL) 177 error ("error: failed to find real waitpid\n"); 178 } 179 180 return (*real_func) (pid, wstatus, options); 181 } 182 183 /* Thread worker created when we cache a waitpid result. Delays for a 184 short period of time and then sends SIGCHLD to the GDB process. This 185 should trigger GDB to call waitpid again, at which point we will make 186 the cached waitpid result available. */ 187 188 static void* 189 send_sigchld_thread (void *arg) 190 { 191 /* Delay one second longer than WAITPID_MIN_TIME so that there can be no 192 chance that a call to SHOULD_SKIP_WAITPID will return true once the 193 SIGCHLD is delivered and handled. */ 194 sleep (WAITPID_MIN_TIME + 1); 195 196 pthread_mutex_lock (thread_creation_lock); 197 signal_thread_active_p = 0; 198 199 if (cached_wait_status.cached_p) 200 { 201 log_msg ("signal-thread: sending SIGCHLD\n"); 202 kill (getpid (), SIGCHLD); 203 } 204 205 pthread_mutex_unlock (thread_creation_lock); 206 return NULL; 207 } 208 209 /* The waitpid entry point function. */ 210 211 pid_t 212 waitpid (pid_t pid, int *wstatus, int options) 213 { 214 log_msg ("waitpid: waitpid (%d, %p, 0x%x)\n", pid, wstatus, options); 215 216 if ((options & WNOHANG) != 0 217 && pid == -1 218 && should_skip_waitpid ()) 219 { 220 if (!cached_wait_status.cached_p) 221 { 222 /* Do the waitpid call, but hold the result back. */ 223 pid_t tmp_pid; 224 int tmp_wstatus; 225 226 tmp_pid = real_waitpid (-1, &tmp_wstatus, options); 227 if (tmp_pid > 0) 228 { 229 log_msg ("waitpid: delaying waitpid result (pid = %d)\n", 230 tmp_pid); 231 232 /* Cache the result. */ 233 cached_wait_status.pid = tmp_pid; 234 cached_wait_status.wstatus = tmp_wstatus; 235 cached_wait_status.cached_p = 1; 236 237 /* Is there a thread around that will be sending a signal in 238 the near future? The prevents us from creating one 239 thread per call to waitpid when the calls occur in a 240 sequence. */ 241 pthread_mutex_lock (thread_creation_lock); 242 if (!signal_thread_active_p) 243 { 244 sigset_t old_ss, new_ss; 245 pthread_t thread_id; 246 pthread_attr_t attr; 247 248 /* Create the new signal sending thread in detached 249 state. This means that the thread doesn't need to be 250 pthread_join'ed. Which is fine as there's no result 251 we care about. */ 252 pthread_attr_init (&attr); 253 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); 254 255 /* Ensure the signal sending thread has all signals 256 blocked. We don't want any signals to GDB to be 257 handled in that thread. */ 258 sigfillset (&new_ss); 259 sigprocmask (SIG_BLOCK, &new_ss, &old_ss); 260 261 log_msg ("waitpid: spawn thread to signal us\n"); 262 if (pthread_create (&thread_id, &attr, 263 send_sigchld_thread, NULL) != 0) 264 error ("error: pthread_create failed\n"); 265 266 signal_thread_active_p = 1; 267 sigprocmask (SIG_SETMASK, &old_ss, NULL); 268 pthread_attr_destroy (&attr); 269 } 270 271 pthread_mutex_unlock (thread_creation_lock); 272 } 273 } 274 275 log_msg ("waitpid: skipping\n"); 276 return 0; 277 } 278 279 /* If we have a cached result that is a suitable reply for this call to 280 waitpid then send that cached result back now. */ 281 if (cached_wait_status.cached_p 282 && (pid == -1 || pid == cached_wait_status.pid)) 283 { 284 pid_t pid; 285 286 pid = cached_wait_status.pid; 287 log_msg ("waitpid: return cached result (%d)\n", pid); 288 *wstatus = cached_wait_status.wstatus; 289 cached_wait_status.cached_p = 0; 290 return pid; 291 } 292 293 log_msg ("waitpid: real waitpid call\n"); 294 return real_waitpid (pid, wstatus, options); 295 } 296 297 /* Perform a real sigsuspend call. */ 298 299 static int 300 real_sigsuspend (const sigset_t *mask) 301 { 302 typedef int (*fptr_t) (const sigset_t *); 303 static fptr_t real_func = NULL; 304 305 if (real_func == NULL) 306 { 307 real_func = dlsym (RTLD_NEXT, "sigsuspend"); 308 if (real_func == NULL) 309 error ("error: failed to find real sigsuspend\n"); 310 } 311 312 return (*real_func) (mask); 313 } 314 315 /* The sigsuspend entry point function. */ 316 317 int 318 sigsuspend (const sigset_t *mask) 319 { 320 log_msg ("sigsuspend: sigsuspend (0x%p)\n", ((void *) mask)); 321 322 /* If SIGCHLD is _not_ in MASK, and is therefore deliverable, then if we 323 have a pending wait status pretend that a signal arrived. We will 324 have a thread alive that is going to deliver a signal but doing this 325 will boost the speed as we don't have to wait for a signal. If the 326 signal ends up being delivered then it should be harmless, we'll just 327 perform an additional waitpid call. */ 328 if (!sigismember (mask, SIGCHLD)) 329 { 330 if (cached_wait_status.cached_p) 331 { 332 log_msg ("sigsuspend: interrupt for cached waitstatus\n"); 333 last_waitpid_time.tv_sec = 0; 334 last_waitpid_time.tv_usec = 0; 335 errno = EINTR; 336 return -1; 337 } 338 } 339 340 log_msg ("sigsuspend: real sigsuspend call\n"); 341 return real_sigsuspend (mask); 342 } 343