< prev index next >

src/jdk.hotspot.agent/linux/native/libsaproc/libproc_impl.c

Print this page
@  rev 12737 : imported patch alpinefixes-sathreaddb
|


   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 #include <stdarg.h>
  25 #include <stdio.h>
  26 #include <stdlib.h>
  27 #include <string.h>
  28 #include <fcntl.h>

  29 #include <thread_db.h>

  30 #include "libproc_impl.h"
  31 
  32 #define SA_ALTROOT "SA_ALTROOT"
  33 
  34 int pathmap_open(const char* name) {
  35   static const char *alt_root = NULL;
  36   static int alt_root_initialized = 0;
  37 
  38   int fd;
  39   char alt_path[PATH_MAX + 1], *alt_path_end;
  40   const char *s;
  41   int free_space;
  42 
  43   if (!alt_root_initialized) {
  44     alt_root_initialized = -1;
  45     alt_root = getenv(SA_ALTROOT);
  46   }
  47 
  48   if (alt_root == NULL) {
  49     return open(name, O_RDONLY);


  99    }
 100 }
 101 
 102 void print_error(const char* format,...) {
 103   va_list alist;
 104   va_start(alist, format);
 105   fputs("ERROR: ", stderr);
 106   vfprintf(stderr, format, alist);
 107   va_end(alist);
 108 }
 109 
 110 bool is_debug() {
 111    return _libsaproc_debug;
 112 }
 113 
 114 // initialize libproc
 115 bool init_libproc(bool debug) {
 116    // init debug mode
 117    _libsaproc_debug = debug;
 118 

 119    // initialize the thread_db library
 120    if (td_init() != TD_OK) {
 121      print_debug("libthread_db's td_init failed\n");
 122      return false;
 123    }

 124 
 125    return true;
 126 }
 127 
 128 static void destroy_lib_info(struct ps_prochandle* ph) {
 129    lib_info* lib = ph->libs;
 130    while (lib) {
 131      lib_info *next = lib->next;
 132      if (lib->symtab) {
 133         destroy_symtab(lib->symtab);
 134      }
 135      free(lib);
 136      lib = next;
 137    }
 138 }
 139 
 140 static void destroy_thread_info(struct ps_prochandle* ph) {
 141    thread_info* thr = ph->threads;
 142    while (thr) {
 143      thread_info *next = thr->next;


 256 // add a thread to ps_prochandle
 257 thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
 258    thread_info* newthr;
 259    if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
 260       print_debug("can't allocate memory for thread_info\n");
 261       return NULL;
 262    }
 263 
 264    // initialize thread info
 265    newthr->pthread_id = pthread_id;
 266    newthr->lwp_id = lwp_id;
 267 
 268    // add new thread to the list
 269    newthr->next = ph->threads;
 270    ph->threads = newthr;
 271    ph->num_threads++;
 272    return newthr;
 273 }
 274 
 275 

 276 // struct used for client data from thread_db callback
 277 struct thread_db_client_data {
 278    struct ps_prochandle* ph;
 279    thread_info_callback callback;
 280 };
 281 
 282 // callback function for libthread_db
 283 static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
 284   struct thread_db_client_data* ptr = (struct thread_db_client_data*) data;
 285   td_thrinfo_t ti;
 286   td_err_e err;
 287 
 288   memset(&ti, 0, sizeof(ti));
 289   err = td_thr_get_info(th_p, &ti);
 290   if (err != TD_OK) {
 291     print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n");
 292     return err;
 293   }
 294 
 295   print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);


 307   if (td_ta_new(ph, &thread_agent) != TD_OK) {
 308      print_debug("can't create libthread_db agent\n");
 309      return false;
 310   }
 311 
 312   mydata.ph = ph;
 313   mydata.callback = cb;
 314 
 315   // we use libthread_db iterator to iterate thru list of threads.
 316   if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata,
 317                  TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
 318                  TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) {
 319      td_ta_delete(thread_agent);
 320      return false;
 321   }
 322 
 323   // delete thread agent
 324   td_ta_delete(thread_agent);
 325   return true;
 326 }
 327 
 328 
 329 // get number of threads
 330 int get_num_threads(struct ps_prochandle* ph) {
 331    return ph->num_threads;
 332 }
 333 
 334 // get lwp_id of n'th thread
 335 lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) {
 336    int count = 0;
 337    thread_info* thr = ph->threads;
 338    while (thr) {
 339       if (count == index) {
 340          return thr->lwp_id;
 341       }
 342       count++;
 343       thr = thr->next;
 344    }
 345    return -1;
 346 }
 347 




   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 #include <stdarg.h>
  25 #include <stdio.h>
  26 #include <stdlib.h>
  27 #include <string.h>
  28 #include <fcntl.h>
  29 #ifdef INCLUDE_SA_ATTACH
  30 #include <thread_db.h>
  31 #endif
  32 #include "libproc_impl.h"
  33 
  34 #define SA_ALTROOT "SA_ALTROOT"
  35 
  36 int pathmap_open(const char* name) {
  37   static const char *alt_root = NULL;
  38   static int alt_root_initialized = 0;
  39 
  40   int fd;
  41   char alt_path[PATH_MAX + 1], *alt_path_end;
  42   const char *s;
  43   int free_space;
  44 
  45   if (!alt_root_initialized) {
  46     alt_root_initialized = -1;
  47     alt_root = getenv(SA_ALTROOT);
  48   }
  49 
  50   if (alt_root == NULL) {
  51     return open(name, O_RDONLY);


 101    }
 102 }
 103 
 104 void print_error(const char* format,...) {
 105   va_list alist;
 106   va_start(alist, format);
 107   fputs("ERROR: ", stderr);
 108   vfprintf(stderr, format, alist);
 109   va_end(alist);
 110 }
 111 
 112 bool is_debug() {
 113    return _libsaproc_debug;
 114 }
 115 
 116 // initialize libproc
 117 bool init_libproc(bool debug) {
 118    // init debug mode
 119    _libsaproc_debug = debug;
 120 
 121 #ifdef INCLUDE_SA_ATTACH
 122    // initialize the thread_db library
 123    if (td_init() != TD_OK) {
 124      print_debug("libthread_db's td_init failed\n");
 125      return false;
 126    }
 127 #endif
 128 
 129    return true;
 130 }
 131 
 132 static void destroy_lib_info(struct ps_prochandle* ph) {
 133    lib_info* lib = ph->libs;
 134    while (lib) {
 135      lib_info *next = lib->next;
 136      if (lib->symtab) {
 137         destroy_symtab(lib->symtab);
 138      }
 139      free(lib);
 140      lib = next;
 141    }
 142 }
 143 
 144 static void destroy_thread_info(struct ps_prochandle* ph) {
 145    thread_info* thr = ph->threads;
 146    while (thr) {
 147      thread_info *next = thr->next;


 260 // add a thread to ps_prochandle
 261 thread_info* add_thread_info(struct ps_prochandle* ph, pthread_t pthread_id, lwpid_t lwp_id) {
 262    thread_info* newthr;
 263    if ( (newthr = (thread_info*) calloc(1, sizeof(thread_info))) == NULL) {
 264       print_debug("can't allocate memory for thread_info\n");
 265       return NULL;
 266    }
 267 
 268    // initialize thread info
 269    newthr->pthread_id = pthread_id;
 270    newthr->lwp_id = lwp_id;
 271 
 272    // add new thread to the list
 273    newthr->next = ph->threads;
 274    ph->threads = newthr;
 275    ph->num_threads++;
 276    return newthr;
 277 }
 278 
 279 
 280 #ifdef INCLUDE_SA_ATTACH
 281 // struct used for client data from thread_db callback
 282 struct thread_db_client_data {
 283    struct ps_prochandle* ph;
 284    thread_info_callback callback;
 285 };
 286 
 287 // callback function for libthread_db
 288 static int thread_db_callback(const td_thrhandle_t *th_p, void *data) {
 289   struct thread_db_client_data* ptr = (struct thread_db_client_data*) data;
 290   td_thrinfo_t ti;
 291   td_err_e err;
 292 
 293   memset(&ti, 0, sizeof(ti));
 294   err = td_thr_get_info(th_p, &ti);
 295   if (err != TD_OK) {
 296     print_debug("libthread_db : td_thr_get_info failed, can't get thread info\n");
 297     return err;
 298   }
 299 
 300   print_debug("thread_db : pthread %d (lwp %d)\n", ti.ti_tid, ti.ti_lid);


 312   if (td_ta_new(ph, &thread_agent) != TD_OK) {
 313      print_debug("can't create libthread_db agent\n");
 314      return false;
 315   }
 316 
 317   mydata.ph = ph;
 318   mydata.callback = cb;
 319 
 320   // we use libthread_db iterator to iterate thru list of threads.
 321   if (td_ta_thr_iter(thread_agent, thread_db_callback, &mydata,
 322                  TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
 323                  TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS) != TD_OK) {
 324      td_ta_delete(thread_agent);
 325      return false;
 326   }
 327 
 328   // delete thread agent
 329   td_ta_delete(thread_agent);
 330   return true;
 331 }
 332 #endif // INCLUDE_SA_ATTACH
 333 
 334 // get number of threads
 335 int get_num_threads(struct ps_prochandle* ph) {
 336    return ph->num_threads;
 337 }
 338 
 339 // get lwp_id of n'th thread
 340 lwpid_t get_lwp_id(struct ps_prochandle* ph, int index) {
 341    int count = 0;
 342    thread_info* thr = ph->threads;
 343    while (thr) {
 344       if (count == index) {
 345          return thr->lwp_id;
 346       }
 347       count++;
 348       thr = thr->next;
 349    }
 350    return -1;
 351 }
 352 


< prev index next >