1 /* Test dwfl_linux_proc_attach works without any modules. 2 Copyright (C) 2015 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file 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 elfutils is distributed in the hope that it will be useful, but 11 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 #include <config.h> 19 #include <inttypes.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <errno.h> 23 #include <error.h> 24 #include <unistd.h> 25 #ifdef __linux__ 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #include <sys/user.h> 29 #include <fcntl.h> 30 #include <string.h> 31 #include ELFUTILS_HEADER(dwfl) 32 #include <pthread.h> 33 #endif 34 35 #ifndef __linux__ 36 int 37 main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused))) 38 { 39 printf ("dwfl_linux_proc_attach unsupported.\n"); 40 return 77; 41 } 42 #else /* __linux__ */ 43 44 static pthread_t thread1; 45 static pthread_t thread2; 46 47 static void * 48 sleeper (void* d __attribute__ ((unused))) 49 { 50 sleep (60); 51 return NULL; 52 } 53 54 static char *debuginfo_path = NULL; 55 56 static const Dwfl_Callbacks proc_callbacks = 57 { 58 .find_elf = dwfl_linux_proc_find_elf, 59 .find_debuginfo = dwfl_standard_find_debuginfo, 60 .debuginfo_path = &debuginfo_path, 61 }; 62 63 static int 64 thread_callback (Dwfl_Thread *thread, void *thread_arg) 65 { 66 int *threads = (int *) thread_arg; 67 pid_t tid = dwfl_thread_tid (thread); 68 printf ("thread tid: %d\n", tid); 69 (*threads)++; 70 71 return DWARF_CB_OK; 72 } 73 74 int 75 main (int argc __attribute__ ((unused)), 76 char **argv __attribute__ ((unused))) 77 { 78 /* Create two extra threads to iterate through. */ 79 int err; 80 if ((err = pthread_create (&thread1, NULL, sleeper, NULL)) != 0) 81 error (-1, err, "Couldn't create thread1"); 82 if ((err = pthread_create (&thread2, NULL, sleeper, NULL)) != 0) 83 error (-1, err, "Couldn't create thread2"); 84 85 Dwfl *dwfl = dwfl_begin (&proc_callbacks); 86 if (dwfl == NULL) 87 error (-1, 0, "dwfl_begin: %s", dwfl_errmsg (-1)); 88 89 pid_t pid = getpid (); 90 /* This used to fail, since we don't have any modules yet. */ 91 if (dwfl_linux_proc_attach (dwfl, pid, false) < 0) 92 error (-1, 0, "dwfl_linux_proc_attach pid %d: %s", pid, 93 dwfl_errmsg (-1)); 94 95 /* Did we see all 3 threads? */ 96 int threads = 0; 97 if (dwfl_getthreads (dwfl, thread_callback, &threads) != DWARF_CB_OK) 98 error (-1, 0, "dwfl_getthreads failed: %s", dwfl_errmsg (-1)); 99 100 return (threads == 3) ? 0 : -1; 101 } 102 103 #endif /* __linux__ */ 104