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; |
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 |
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: |