1299 else |
1299 else |
1300 return false; |
1300 return false; |
1301 } |
1301 } |
1302 #endif |
1302 #endif |
1303 |
1303 |
1304 |
|
1305 // Enumerate all modules for a given process ID |
|
1306 // |
|
1307 // Notice that Windows 95/98/Me and Windows NT/2000/XP have |
|
1308 // different API for doing this. We use PSAPI.DLL on NT based |
|
1309 // Windows and ToolHelp on 95/98/Me. |
|
1310 |
|
1311 // Callback function that is called by enumerate_modules() on |
|
1312 // every DLL module. |
|
1313 // Input parameters: |
|
1314 // int pid, |
|
1315 // char* module_file_name, |
|
1316 // address module_base_addr, |
|
1317 // unsigned module_size, |
|
1318 // void* param |
|
1319 typedef int (*EnumModulesCallbackFunc)(int, char *, address, unsigned, void *); |
|
1320 |
|
1321 // enumerate_modules for Windows NT, using PSAPI |
|
1322 static int _enumerate_modules_winnt( int pid, EnumModulesCallbackFunc func, void * param) |
|
1323 { |
|
1324 HANDLE hProcess; |
|
1325 |
|
1326 # define MAX_NUM_MODULES 128 |
|
1327 HMODULE modules[MAX_NUM_MODULES]; |
|
1328 static char filename[MAX_PATH]; |
|
1329 int result = 0; |
|
1330 |
|
1331 if (!os::PSApiDll::PSApiAvailable()) { |
|
1332 return 0; |
|
1333 } |
|
1334 |
|
1335 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, |
|
1336 FALSE, pid); |
|
1337 if (hProcess == NULL) return 0; |
|
1338 |
|
1339 DWORD size_needed; |
|
1340 if (!os::PSApiDll::EnumProcessModules(hProcess, modules, |
|
1341 sizeof(modules), &size_needed)) { |
|
1342 CloseHandle(hProcess); |
|
1343 return 0; |
|
1344 } |
|
1345 |
|
1346 // number of modules that are currently loaded |
|
1347 int num_modules = size_needed / sizeof(HMODULE); |
|
1348 |
|
1349 for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { |
|
1350 // Get Full pathname: |
|
1351 if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i], |
|
1352 filename, sizeof(filename))) { |
|
1353 filename[0] = '\0'; |
|
1354 } |
|
1355 |
|
1356 MODULEINFO modinfo; |
|
1357 if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i], |
|
1358 &modinfo, sizeof(modinfo))) { |
|
1359 modinfo.lpBaseOfDll = NULL; |
|
1360 modinfo.SizeOfImage = 0; |
|
1361 } |
|
1362 |
|
1363 // Invoke callback function |
|
1364 result = func(pid, filename, (address)modinfo.lpBaseOfDll, |
|
1365 modinfo.SizeOfImage, param); |
|
1366 if (result) break; |
|
1367 } |
|
1368 |
|
1369 CloseHandle(hProcess); |
|
1370 return result; |
|
1371 } |
|
1372 |
|
1373 |
|
1374 // enumerate_modules for Windows 95/98/ME, using TOOLHELP |
|
1375 static int _enumerate_modules_windows( int pid, EnumModulesCallbackFunc func, void *param) |
|
1376 { |
|
1377 HANDLE hSnapShot; |
|
1378 static MODULEENTRY32 modentry; |
|
1379 int result = 0; |
|
1380 |
|
1381 if (!os::Kernel32Dll::HelpToolsAvailable()) { |
|
1382 return 0; |
|
1383 } |
|
1384 |
|
1385 // Get a handle to a Toolhelp snapshot of the system |
|
1386 hSnapShot = os::Kernel32Dll::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); |
|
1387 if (hSnapShot == INVALID_HANDLE_VALUE) { |
|
1388 return FALSE; |
|
1389 } |
|
1390 |
|
1391 // iterate through all modules |
|
1392 modentry.dwSize = sizeof(MODULEENTRY32); |
|
1393 bool not_done = os::Kernel32Dll::Module32First( hSnapShot, &modentry ) != 0; |
|
1394 |
|
1395 while (not_done) { |
|
1396 // invoke the callback |
|
1397 result=func(pid, modentry.szExePath, (address)modentry.modBaseAddr, |
|
1398 modentry.modBaseSize, param); |
|
1399 if (result) break; |
|
1400 |
|
1401 modentry.dwSize = sizeof(MODULEENTRY32); |
|
1402 not_done = os::Kernel32Dll::Module32Next( hSnapShot, &modentry ) != 0; |
|
1403 } |
|
1404 |
|
1405 CloseHandle(hSnapShot); |
|
1406 return result; |
|
1407 } |
|
1408 |
|
1409 int enumerate_modules( int pid, EnumModulesCallbackFunc func, void * param ) |
|
1410 { |
|
1411 // Get current process ID if caller doesn't provide it. |
|
1412 if (!pid) pid = os::current_process_id(); |
|
1413 |
|
1414 if (os::win32::is_nt()) return _enumerate_modules_winnt (pid, func, param); |
|
1415 else return _enumerate_modules_windows(pid, func, param); |
|
1416 } |
|
1417 |
|
1418 struct _modinfo { |
1304 struct _modinfo { |
1419 address addr; |
1305 address addr; |
1420 char* full_path; // point to a char buffer |
1306 char* full_path; // point to a char buffer |
1421 int buflen; // size of the buffer |
1307 int buflen; // size of the buffer |
1422 address base_addr; |
1308 address base_addr; |
1423 }; |
1309 }; |
1424 |
1310 |
1425 static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr, |
1311 static int _locate_module_by_addr(const char * mod_fname, address base_addr, |
1426 unsigned size, void * param) { |
1312 address top_address, void * param) { |
1427 struct _modinfo *pmod = (struct _modinfo *)param; |
1313 struct _modinfo *pmod = (struct _modinfo *)param; |
1428 if (!pmod) return -1; |
1314 if (!pmod) return -1; |
1429 |
1315 |
1430 if (base_addr <= pmod->addr && |
1316 if (base_addr <= pmod->addr && |
1431 base_addr+size > pmod->addr) { |
1317 top_address > pmod->addr) { |
1432 // if a buffer is provided, copy path name to the buffer |
1318 // if a buffer is provided, copy path name to the buffer |
1433 if (pmod->full_path) { |
1319 if (pmod->full_path) { |
1434 jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname); |
1320 jio_snprintf(pmod->full_path, pmod->buflen, "%s", mod_fname); |
1435 } |
1321 } |
1436 pmod->base_addr = base_addr; |
1322 pmod->base_addr = base_addr; |
1477 buf[0] = '\0'; |
1362 buf[0] = '\0'; |
1478 return false; |
1363 return false; |
1479 } |
1364 } |
1480 |
1365 |
1481 // save the start and end address of jvm.dll into param[0] and param[1] |
1366 // save the start and end address of jvm.dll into param[0] and param[1] |
1482 static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, |
1367 static int _locate_jvm_dll(const char* mod_fname, address base_addr, |
1483 unsigned size, void * param) { |
1368 address top_address, void * param) { |
1484 if (!param) return -1; |
1369 if (!param) return -1; |
1485 |
1370 |
1486 if (base_addr <= (address)_locate_jvm_dll && |
1371 if (base_addr <= (address)_locate_jvm_dll && |
1487 base_addr+size > (address)_locate_jvm_dll) { |
1372 top_address > (address)_locate_jvm_dll) { |
1488 ((address*)param)[0] = base_addr; |
1373 ((address*)param)[0] = base_addr; |
1489 ((address*)param)[1] = base_addr + size; |
1374 ((address*)param)[1] = top_address; |
1490 return 1; |
1375 return 1; |
1491 } |
1376 } |
1492 return 0; |
1377 return 0; |
1493 } |
1378 } |
1494 |
1379 |
1495 address vm_lib_location[2]; // start and end address of jvm.dll |
1380 address vm_lib_location[2]; // start and end address of jvm.dll |
1496 |
1381 |
1497 // check if addr is inside jvm.dll |
1382 // check if addr is inside jvm.dll |
1498 bool os::address_is_in_vm(address addr) { |
1383 bool os::address_is_in_vm(address addr) { |
1499 if (!vm_lib_location[0] || !vm_lib_location[1]) { |
1384 if (!vm_lib_location[0] || !vm_lib_location[1]) { |
1500 int pid = os::current_process_id(); |
1385 if (!get_loaded_modules_info(_locate_jvm_dll, (void *)vm_lib_location)) { |
1501 if (!enumerate_modules(pid, _locate_jvm_dll, (void *)vm_lib_location)) { |
|
1502 assert(false, "Can't find jvm module."); |
1386 assert(false, "Can't find jvm module."); |
1503 return false; |
1387 return false; |
1504 } |
1388 } |
1505 } |
1389 } |
1506 |
1390 |
1507 return (vm_lib_location[0] <= addr) && (addr < vm_lib_location[1]); |
1391 return (vm_lib_location[0] <= addr) && (addr < vm_lib_location[1]); |
1508 } |
1392 } |
1509 |
1393 |
1510 // print module info; param is outputStream* |
1394 // print module info; param is outputStream* |
1511 static int _print_module(int pid, char* fname, address base, |
1395 static int _print_module(const char* fname, address base_address, |
1512 unsigned size, void* param) { |
1396 address top_address, void* param) { |
1513 if (!param) return -1; |
1397 if (!param) return -1; |
1514 |
1398 |
1515 outputStream* st = (outputStream*)param; |
1399 outputStream* st = (outputStream*)param; |
1516 |
1400 |
1517 address end_addr = base + size; |
1401 st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base_address, top_address, fname); |
1518 st->print(PTR_FORMAT " - " PTR_FORMAT " \t%s\n", base, end_addr, fname); |
|
1519 return 0; |
1402 return 0; |
1520 } |
1403 } |
1521 |
1404 |
1522 // Loads .dll/.so and |
1405 // Loads .dll/.so and |
1523 // in case of error it checks if .dll/.so was built for the |
1406 // in case of error it checks if .dll/.so was built for the |
1642 } |
1525 } |
1643 |
1526 |
1644 return NULL; |
1527 return NULL; |
1645 } |
1528 } |
1646 |
1529 |
1647 |
|
1648 void os::print_dll_info(outputStream *st) { |
1530 void os::print_dll_info(outputStream *st) { |
1649 int pid = os::current_process_id(); |
|
1650 st->print_cr("Dynamic libraries:"); |
1531 st->print_cr("Dynamic libraries:"); |
1651 enumerate_modules(pid, _print_module, (void *)st); |
1532 get_loaded_modules_info(_print_module, (void *)st); |
|
1533 } |
|
1534 |
|
1535 int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { |
|
1536 HANDLE hProcess; |
|
1537 |
|
1538 # define MAX_NUM_MODULES 128 |
|
1539 HMODULE modules[MAX_NUM_MODULES]; |
|
1540 static char filename[MAX_PATH]; |
|
1541 int result = 0; |
|
1542 |
|
1543 if (!os::PSApiDll::PSApiAvailable()) { |
|
1544 return 0; |
|
1545 } |
|
1546 |
|
1547 int pid = os::current_process_id(); |
|
1548 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, |
|
1549 FALSE, pid); |
|
1550 if (hProcess == NULL) return 0; |
|
1551 |
|
1552 DWORD size_needed; |
|
1553 if (!os::PSApiDll::EnumProcessModules(hProcess, modules, |
|
1554 sizeof(modules), &size_needed)) { |
|
1555 CloseHandle(hProcess); |
|
1556 return 0; |
|
1557 } |
|
1558 |
|
1559 // number of modules that are currently loaded |
|
1560 int num_modules = size_needed / sizeof(HMODULE); |
|
1561 |
|
1562 for (int i = 0; i < MIN2(num_modules, MAX_NUM_MODULES); i++) { |
|
1563 // Get Full pathname: |
|
1564 if (!os::PSApiDll::GetModuleFileNameEx(hProcess, modules[i], |
|
1565 filename, sizeof(filename))) { |
|
1566 filename[0] = '\0'; |
|
1567 } |
|
1568 |
|
1569 MODULEINFO modinfo; |
|
1570 if (!os::PSApiDll::GetModuleInformation(hProcess, modules[i], |
|
1571 &modinfo, sizeof(modinfo))) { |
|
1572 modinfo.lpBaseOfDll = NULL; |
|
1573 modinfo.SizeOfImage = 0; |
|
1574 } |
|
1575 |
|
1576 // Invoke callback function |
|
1577 result = callback(filename, (address)modinfo.lpBaseOfDll, |
|
1578 (address)((u8)modinfo.lpBaseOfDll + (u8)modinfo.SizeOfImage), param); |
|
1579 if (result) break; |
|
1580 } |
|
1581 |
|
1582 CloseHandle(hProcess); |
|
1583 return result; |
1652 } |
1584 } |
1653 |
1585 |
1654 void os::print_os_info_brief(outputStream* st) { |
1586 void os::print_os_info_brief(outputStream* st) { |
1655 os::print_os_info(st); |
1587 os::print_os_info(st); |
1656 } |
1588 } |