hotspot/agent/src/os/bsd/ps_core.c
changeset 20375 9e82f2c36626
parent 17310 b4118c427cc0
equal deleted inserted replaced
20369:ea40fc329ca0 20375:9e82f2c36626
    42 // ps_prochandle cleanup helper functions
    42 // ps_prochandle cleanup helper functions
    43 
    43 
    44 // close all file descriptors
    44 // close all file descriptors
    45 static void close_files(struct ps_prochandle* ph) {
    45 static void close_files(struct ps_prochandle* ph) {
    46   lib_info* lib = NULL;
    46   lib_info* lib = NULL;
       
    47 
    47   // close core file descriptor
    48   // close core file descriptor
    48   if (ph->core->core_fd >= 0)
    49   if (ph->core->core_fd >= 0)
    49     close(ph->core->core_fd);
    50     close(ph->core->core_fd);
    50 
    51 
    51   // close exec file descriptor
    52   // close exec file descriptor
   147   return map;
   148   return map;
   148 }
   149 }
   149 
   150 
   150 // Return the map_info for the given virtual address.  We keep a sorted
   151 // Return the map_info for the given virtual address.  We keep a sorted
   151 // array of pointers in ph->map_array, so we can binary search.
   152 // array of pointers in ph->map_array, so we can binary search.
   152 static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr)
   153 static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
   153 {
       
   154   int mid, lo = 0, hi = ph->core->num_maps - 1;
   154   int mid, lo = 0, hi = ph->core->num_maps - 1;
   155   map_info *mp;
   155   map_info *mp;
   156 
   156 
   157   while (hi - lo > 1) {
   157   while (hi - lo > 1) {
   158     mid = (lo + hi) / 2;
   158     mid = (lo + hi) / 2;
   228     char*  _base;            // copy-on-write base address
   228     char*  _base;            // copy-on-write base address
   229     size_t _capacity;        // for validity checking
   229     size_t _capacity;        // for validity checking
   230     size_t _used;            // for setting space top on read
   230     size_t _used;            // for setting space top on read
   231 
   231 
   232     // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
   232     // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
   233     // the C type matching the C++ bool type on any given platform. For
   233     // the C type matching the C++ bool type on any given platform.
   234     // Hotspot on BSD we assume the corresponding C type is char but
   234     // We assume the corresponding C type is char but licensees
   235     // licensees on BSD versions may need to adjust the type of these fields.
   235     // may need to adjust the type of these fields.
   236     char   _read_only;       // read only space?
   236     char   _read_only;       // read only space?
   237     char   _allow_exec;      // executable code in space?
   237     char   _allow_exec;      // executable code in space?
   238 
   238 
   239   } _space[NUM_SHARED_MAPS];
   239   } _space[NUM_SHARED_MAPS];
   240 
   240 
   284 
   284 
   285 #ifdef __APPLE__
   285 #ifdef __APPLE__
   286 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
   286 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
   287 // mangled name of Arguments::SharedArchivePath
   287 // mangled name of Arguments::SharedArchivePath
   288 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
   288 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
       
   289 #define LIBJVM_NAME "/libjvm.dylib"
   289 #else
   290 #else
   290 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
   291 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
   291 // mangled name of Arguments::SharedArchivePath
   292 // mangled name of Arguments::SharedArchivePath
   292 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
   293 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
       
   294 #define LIBJVM_NAME "/libjvm.so"
   293 #endif // __APPLE_
   295 #endif // __APPLE_
   294 
   296 
   295 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
   297 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
   296   int m;
   298   int m;
   297   size_t n;
   299   size_t n;
   298   lib_info* lib = ph->libs;
   300   lib_info* lib = ph->libs;
   299   while (lib != NULL) {
   301   while (lib != NULL) {
   300     // we are iterating over shared objects from the core dump. look for
   302     // we are iterating over shared objects from the core dump. look for
   301     // libjvm.so.
   303     // libjvm.so.
   302     const char *jvm_name = 0;
   304     const char *jvm_name = 0;
   303 #ifdef __APPLE__
   305     if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
   304     if ((jvm_name = strstr(lib->name, "/libjvm.dylib")) != 0)
       
   305 #else
       
   306     if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0)
       
   307 #endif // __APPLE__
       
   308     {
       
   309       char classes_jsa[PATH_MAX];
   306       char classes_jsa[PATH_MAX];
   310       struct FileMapHeader header;
   307       struct FileMapHeader header;
   311       int fd = -1;
   308       int fd = -1;
   312       uintptr_t base = 0, useSharedSpacesAddr = 0;
   309       uintptr_t base = 0, useSharedSpacesAddr = 0;
   313       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
   310       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
   397                                    base, (size_t) header._space[m]._used);
   394                                    base, (size_t) header._space[m]._used);
   398           print_debug("added a share archive map at 0x%lx\n", base);
   395           print_debug("added a share archive map at 0x%lx\n", base);
   399         }
   396         }
   400       }
   397       }
   401       return true;
   398       return true;
   402     }
   399    }
   403     lib = lib->next;
   400    lib = lib->next;
   404   }
   401   }
   405   return true;
   402   return true;
   406 }
   403 }
   407 
   404 
   408 //---------------------------------------------------------------------------
   405 //---------------------------------------------------------------------------
   430   int i = 0;
   427   int i = 0;
   431 
   428 
   432   // allocate map_array
   429   // allocate map_array
   433   map_info** array;
   430   map_info** array;
   434   if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
   431   if ( (array = (map_info**) malloc(sizeof(map_info*) * num_maps)) == NULL) {
   435      print_debug("can't allocate memory for map array\n");
   432     print_debug("can't allocate memory for map array\n");
   436      return false;
   433     return false;
   437   }
   434   }
   438 
   435 
   439   // add maps to array
   436   // add maps to array
   440   while (map) {
   437   while (map) {
   441     array[i] = map;
   438     array[i] = map;
   448     free(ph->core->map_array);
   445     free(ph->core->map_array);
   449   }
   446   }
   450   ph->core->map_array = array;
   447   ph->core->map_array = array;
   451   // sort the map_info array by base virtual address.
   448   // sort the map_info array by base virtual address.
   452   qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
   449   qsort(ph->core->map_array, ph->core->num_maps, sizeof (map_info*),
   453            core_cmp_mapping);
   450         core_cmp_mapping);
   454 
   451 
   455   // print map
   452   // print map
   456   if (is_debug()) {
   453   if (is_debug()) {
   457     int j = 0;
   454     int j = 0;
   458     print_debug("---- sorted virtual address map ----\n");
   455     print_debug("---- sorted virtual address map ----\n");
   459     for (j = 0; j < ph->core->num_maps; j++) {
   456     for (j = 0; j < ph->core->num_maps; j++) {
   460       print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
   457       print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
   461                                        ph->core->map_array[j]->memsz);
   458                   ph->core->map_array[j]->memsz);
   462     }
   459     }
   463   }
   460   }
   464 
   461 
   465   return true;
   462   return true;
   466 }
   463 }
  1089       char* descdata  = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
  1086       char* descdata  = p + sizeof(ELF_NHDR) + ROUNDUP(notep->n_namesz, 4);
  1090       print_debug("Note header with n_type = %d and n_descsz = %u\n",
  1087       print_debug("Note header with n_type = %d and n_descsz = %u\n",
  1091                                    notep->n_type, notep->n_descsz);
  1088                                    notep->n_type, notep->n_descsz);
  1092 
  1089 
  1093       if (notep->n_type == NT_PRSTATUS) {
  1090       if (notep->n_type == NT_PRSTATUS) {
  1094          if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
  1091         if (core_handle_prstatus(ph, descdata, notep->n_descsz) != true) {
  1095             return false;
  1092           return false;
  1096          }
  1093         }
  1097       }
  1094       }
  1098       p = descdata + ROUNDUP(notep->n_descsz, 4);
  1095       p = descdata + ROUNDUP(notep->n_descsz, 4);
  1099    }
  1096    }
  1100 
  1097 
  1101    free(buf);
  1098    free(buf);
  1119     * Now iterate through the program headers in the core file.
  1116     * Now iterate through the program headers in the core file.
  1120     * We're interested in two types of Phdrs: PT_NOTE (which
  1117     * We're interested in two types of Phdrs: PT_NOTE (which
  1121     * contains a set of saved /proc structures), and PT_LOAD (which
  1118     * contains a set of saved /proc structures), and PT_LOAD (which
  1122     * represents a memory mapping from the process's address space).
  1119     * represents a memory mapping from the process's address space).
  1123     *
  1120     *
  1124     * Difference b/w Solaris PT_NOTE and BSD PT_NOTE:
  1121     * Difference b/w Solaris PT_NOTE and Linux/BSD PT_NOTE:
  1125     *
  1122     *
  1126     *     In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
  1123     *     In Solaris there are two PT_NOTE segments the first PT_NOTE (if present)
  1127     *     contains /proc structs in the pre-2.6 unstructured /proc format. the last
  1124     *     contains /proc structs in the pre-2.6 unstructured /proc format. the last
  1128     *     PT_NOTE has data in new /proc format.
  1125     *     PT_NOTE has data in new /proc format.
  1129     *
  1126     *
  1165    return false;
  1162    return false;
  1166 }
  1163 }
  1167 
  1164 
  1168 // read segments of a shared object
  1165 // read segments of a shared object
  1169 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
  1166 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
  1170    int i = 0;
  1167   int i = 0;
  1171    ELF_PHDR* phbuf;
  1168   ELF_PHDR* phbuf;
  1172    ELF_PHDR* lib_php = NULL;
  1169   ELF_PHDR* lib_php = NULL;
  1173 
  1170 
  1174    if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL)
  1171   int page_size=sysconf(_SC_PAGE_SIZE);
  1175       return false;
  1172 
  1176 
  1173   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
  1177    // we want to process only PT_LOAD segments that are not writable.
  1174     return false;
  1178    // i.e., text segments. The read/write/exec (data) segments would
  1175   }
  1179    // have been already added from core file segments.
  1176 
  1180    for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
  1177   // we want to process only PT_LOAD segments that are not writable.
  1181       if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
  1178   // i.e., text segments. The read/write/exec (data) segments would
  1182          if (add_map_info(ph, lib_fd, lib_php->p_offset, lib_php->p_vaddr + lib_base, lib_php->p_filesz) == NULL)
  1179   // have been already added from core file segments.
  1183             goto err;
  1180   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
  1184       }
  1181     if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
  1185       lib_php++;
  1182 
  1186    }
  1183       uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
  1187 
  1184       map_info *existing_map = core_lookup(ph, target_vaddr);
  1188    free(phbuf);
  1185 
  1189    return true;
  1186       if (existing_map == NULL){
       
  1187         if (add_map_info(ph, lib_fd, lib_php->p_offset,
       
  1188                           target_vaddr, lib_php->p_filesz) == NULL) {
       
  1189           goto err;
       
  1190         }
       
  1191       } else {
       
  1192         if ((existing_map->memsz != page_size) &&
       
  1193             (existing_map->fd != lib_fd) &&
       
  1194             (existing_map->memsz != lib_php->p_filesz)){
       
  1195 
       
  1196           print_debug("address conflict @ 0x%lx (size = %ld, flags = %d\n)",
       
  1197                         target_vaddr, lib_php->p_filesz, lib_php->p_flags);
       
  1198           goto err;
       
  1199         }
       
  1200 
       
  1201         /* replace PT_LOAD segment with library segment */
       
  1202         print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
       
  1203                      existing_map->memsz, lib_php->p_filesz);
       
  1204 
       
  1205         existing_map->fd = lib_fd;
       
  1206         existing_map->offset = lib_php->p_offset;
       
  1207         existing_map->memsz = lib_php->p_filesz;
       
  1208       }
       
  1209     }
       
  1210 
       
  1211     lib_php++;
       
  1212   }
       
  1213 
       
  1214   free(phbuf);
       
  1215   return true;
  1190 err:
  1216 err:
  1191    free(phbuf);
  1217   free(phbuf);
  1192    return false;
  1218   return false;
  1193 }
  1219 }
  1194 
  1220 
  1195 // process segments from interpreter (ld-elf.so.1)
  1221 // process segments from interpreter (ld.so or ld-linux.so or ld-elf.so)
  1196 static bool read_interp_segments(struct ps_prochandle* ph) {
  1222 static bool read_interp_segments(struct ps_prochandle* ph) {
  1197    ELF_EHDR interp_ehdr;
  1223    ELF_EHDR interp_ehdr;
  1198 
  1224 
  1199    if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
  1225    if (read_elf_header(ph->core->interp_fd, &interp_ehdr) != true) {
  1200        print_debug("interpreter is not a valid ELF file\n");
  1226        print_debug("interpreter is not a valid ELF file\n");
  1301 
  1327 
  1302   // we have got Dyn entry with DT_DEBUG
  1328   // we have got Dyn entry with DT_DEBUG
  1303   debug_base = dyn.d_un.d_ptr;
  1329   debug_base = dyn.d_un.d_ptr;
  1304   // at debug_base we have struct r_debug. This has first link map in r_map field
  1330   // at debug_base we have struct r_debug. This has first link map in r_map field
  1305   if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
  1331   if (ps_pread(ph, (psaddr_t) debug_base + FIRST_LINK_MAP_OFFSET,
  1306                   &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
  1332                  &first_link_map_addr, sizeof(uintptr_t)) != PS_OK) {
  1307     print_debug("can't read first link map address\n");
  1333     print_debug("can't read first link map address\n");
  1308     return false;
  1334     return false;
  1309   }
  1335   }
  1310 
  1336 
  1311   // read ld_base address from struct r_debug
  1337   // read ld_base address from struct r_debug
  1312   // XXX: There is no r_ldbase member on BSD
  1338 #if 0  // There is no r_ldbase member on BSD
  1313   /*
       
  1314   if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
  1339   if (ps_pread(ph, (psaddr_t) debug_base + LD_BASE_OFFSET, &ld_base_addr,
  1315                   sizeof(uintptr_t)) != PS_OK) {
  1340                   sizeof(uintptr_t)) != PS_OK) {
  1316     print_debug("can't read ld base address\n");
  1341     print_debug("can't read ld base address\n");
  1317     return false;
  1342     return false;
  1318   }
  1343   }
  1319   ph->core->ld_base_addr = ld_base_addr;
  1344   ph->core->ld_base_addr = ld_base_addr;
  1320   */
  1345 #else
  1321   ph->core->ld_base_addr = 0;
  1346   ph->core->ld_base_addr = 0;
       
  1347 #endif
  1322 
  1348 
  1323   print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
  1349   print_debug("interpreter base address is 0x%lx\n", ld_base_addr);
  1324 
  1350 
  1325   // now read segments from interp (i.e ld-elf.so.1)
  1351   // now read segments from interp (i.e ld.so or ld-linux.so or ld-elf.so)
  1326   if (read_interp_segments(ph) != true)
  1352   if (read_interp_segments(ph) != true) {
  1327     return false;
  1353     return false;
       
  1354   }
  1328 
  1355 
  1329   // after adding interpreter (ld.so) mappings sort again
  1356   // after adding interpreter (ld.so) mappings sort again
  1330   if (sort_map_array(ph) != true)
  1357   if (sort_map_array(ph) != true) {
  1331     return false;
  1358     return false;
       
  1359   }
  1332 
  1360 
  1333   print_debug("first link map is at 0x%lx\n", first_link_map_addr);
  1361   print_debug("first link map is at 0x%lx\n", first_link_map_addr);
  1334 
  1362 
  1335   link_map_addr = first_link_map_addr;
  1363   link_map_addr = first_link_map_addr;
  1336   while (link_map_addr != 0) {
  1364   while (link_map_addr != 0) {
  1378             return false;
  1406             return false;
  1379           }
  1407           }
  1380           add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
  1408           add_lib_info_fd(ph, lib_name, lib_fd, lib_base);
  1381           // Map info is added for the library (lib_name) so
  1409           // Map info is added for the library (lib_name) so
  1382           // we need to re-sort it before calling the p_pdread.
  1410           // we need to re-sort it before calling the p_pdread.
  1383           if (sort_map_array(ph) != true)
  1411           if (sort_map_array(ph) != true) {
  1384             return false;
  1412             return false;
       
  1413           }
  1385         } else {
  1414         } else {
  1386           print_debug("can't read ELF header for shared object %s\n", lib_name);
  1415           print_debug("can't read ELF header for shared object %s\n", lib_name);
  1387           close(lib_fd);
  1416           close(lib_fd);
  1388           // continue with other libraries...
  1417           // continue with other libraries...
  1389         }
  1418         }
  1390       }
  1419       }
  1391     }
  1420     }
  1392 
  1421 
  1393     // read next link_map address
  1422     // read next link_map address
  1394     if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
  1423     if (ps_pread(ph, (psaddr_t) link_map_addr + LINK_MAP_NEXT_OFFSET,
  1395                  &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
  1424                   &link_map_addr, sizeof(uintptr_t)) != PS_OK) {
  1396       print_debug("can't read next link in link_map\n");
  1425       print_debug("can't read next link in link_map\n");
  1397       return false;
  1426       return false;
  1398     }
  1427     }
  1399   }
  1428   }
  1400 
  1429 
  1406   ELF_EHDR core_ehdr;
  1435   ELF_EHDR core_ehdr;
  1407   ELF_EHDR exec_ehdr;
  1436   ELF_EHDR exec_ehdr;
  1408 
  1437 
  1409   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
  1438   struct ps_prochandle* ph = (struct ps_prochandle*) calloc(1, sizeof(struct ps_prochandle));
  1410   if (ph == NULL) {
  1439   if (ph == NULL) {
  1411     print_debug("cant allocate ps_prochandle\n");
  1440     print_debug("can't allocate ps_prochandle\n");
  1412     return NULL;
  1441     return NULL;
  1413   }
  1442   }
  1414 
  1443 
  1415   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
  1444   if ((ph->core = (struct core_data*) calloc(1, sizeof(struct core_data))) == NULL) {
  1416     free(ph);
  1445     free(ph);
  1442     print_debug("can't open executable file\n");
  1471     print_debug("can't open executable file\n");
  1443     goto err;
  1472     goto err;
  1444   }
  1473   }
  1445 
  1474 
  1446   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
  1475   if (read_elf_header(ph->core->exec_fd, &exec_ehdr) != true || exec_ehdr.e_type != ET_EXEC) {
  1447      print_debug("executable file is not a valid ELF ET_EXEC file\n");
  1476     print_debug("executable file is not a valid ELF ET_EXEC file\n");
  1448      goto err;
  1477     goto err;
  1449   }
  1478   }
  1450 
  1479 
  1451   // process core file segments
  1480   // process core file segments
  1452   if (read_core_segments(ph, &core_ehdr) != true)
  1481   if (read_core_segments(ph, &core_ehdr) != true) {
  1453      goto err;
  1482     goto err;
       
  1483   }
  1454 
  1484 
  1455   // process exec file segments
  1485   // process exec file segments
  1456   if (read_exec_segments(ph, &exec_ehdr) != true)
  1486   if (read_exec_segments(ph, &exec_ehdr) != true) {
  1457      goto err;
  1487     goto err;
       
  1488   }
  1458 
  1489 
  1459   // exec file is also treated like a shared object for symbol search
  1490   // exec file is also treated like a shared object for symbol search
  1460   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
  1491   if (add_lib_info_fd(ph, exec_file, ph->core->exec_fd,
  1461                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL)
  1492                       (uintptr_t)0 + find_base_address(ph->core->exec_fd, &exec_ehdr)) == NULL) {
  1462      goto err;
  1493     goto err;
       
  1494   }
  1463 
  1495 
  1464   // allocate and sort maps into map_array, we need to do this
  1496   // allocate and sort maps into map_array, we need to do this
  1465   // here because read_shared_lib_info needs to read from debuggee
  1497   // here because read_shared_lib_info needs to read from debuggee
  1466   // address space
  1498   // address space
  1467   if (sort_map_array(ph) != true)
  1499   if (sort_map_array(ph) != true) {
  1468     goto err;
  1500     goto err;
  1469 
  1501   }
  1470   if (read_shared_lib_info(ph) != true)
  1502 
  1471     goto err;
  1503   if (read_shared_lib_info(ph) != true) {
       
  1504     goto err;
       
  1505   }
  1472 
  1506 
  1473   // sort again because we have added more mappings from shared objects
  1507   // sort again because we have added more mappings from shared objects
  1474   if (sort_map_array(ph) != true)
  1508   if (sort_map_array(ph) != true) {
  1475     goto err;
  1509     goto err;
  1476 
  1510   }
  1477   if (init_classsharing_workaround(ph) != true)
  1511 
  1478     goto err;
  1512   if (init_classsharing_workaround(ph) != true) {
       
  1513     goto err;
       
  1514   }
  1479 
  1515 
  1480   print_debug("Leave Pgrab_core\n");
  1516   print_debug("Leave Pgrab_core\n");
  1481   return ph;
  1517   return ph;
  1482 
  1518 
  1483 err:
  1519 err: