|
17 | 17 | #include <process.h> |
18 | 18 | #include <dbghelp.h> |
19 | 19 | #include <Lm.h> |
| 20 | +#include <tchar.h> |
| 21 | +#include <psapi.h> |
20 | 22 | #else |
21 | 23 | #include <sys/time.h> |
22 | 24 | #include <sys/resource.h> |
|
27 | 29 | #include <inttypes.h> |
28 | 30 | #include <cxxabi.h> |
29 | 31 | #include <dlfcn.h> |
| 32 | +#ifdef __linux__ |
| 33 | +#include <link.h> |
| 34 | +#endif |
30 | 35 | #ifndef _AIX |
31 | 36 | #include <execinfo.h> |
32 | 37 | #else |
| 38 | +#include <sys/ldr.h> |
33 | 39 | #include <sys/procfs.h> |
34 | 40 | #endif |
35 | 41 | #include <sys/utsname.h> |
|
46 | 52 | #ifdef __APPLE__ |
47 | 53 | // Include _NSGetArgv and _NSGetArgc for command line arguments. |
48 | 54 | #include <crt_externs.h> |
| 55 | +#include <mach-o/dyld.h> |
49 | 56 | #endif |
50 | 57 |
|
51 | 58 | #ifndef _WIN32 |
@@ -74,6 +81,7 @@ static void PrintResourceUsage(FILE* fp); |
74 | 81 | #endif |
75 | 82 | static void PrintGCStatistics(FILE* fp, Isolate* isolate); |
76 | 83 | static void PrintSystemInformation(FILE* fp, Isolate* isolate); |
| 84 | +static void PrintLoadedLibraries(FILE* fp, Isolate* isolate); |
77 | 85 | static void WriteInteger(FILE* fp, size_t value); |
78 | 86 |
|
79 | 87 | // Global variables |
@@ -1003,6 +1011,108 @@ const static struct { |
1003 | 1011 | } |
1004 | 1012 | } |
1005 | 1013 | #endif |
| 1014 | + |
| 1015 | + fprintf(fp, "\nLoaded libraries\n"); |
| 1016 | + PrintLoadedLibraries(fp, isolate); |
| 1017 | +} |
| 1018 | + |
| 1019 | +/******************************************************************************* |
| 1020 | + * Functions to print a list of loaded native libraries. |
| 1021 | + * |
| 1022 | + ******************************************************************************/ |
| 1023 | +#ifdef __linux__ |
| 1024 | +static int LibraryPrintCallback(struct dl_phdr_info *info, size_t size, void *data) { |
| 1025 | + FILE* fp = (FILE*)data; |
| 1026 | + if (info->dlpi_name != nullptr && *info->dlpi_name != '\0') { |
| 1027 | + fprintf(fp, " %s\n", info->dlpi_name); |
| 1028 | + } |
| 1029 | + return 0; |
| 1030 | +} |
| 1031 | +#endif |
| 1032 | + |
| 1033 | +static void PrintLoadedLibraries(FILE* fp, Isolate* isolate) { |
| 1034 | +#ifdef __linux__ |
| 1035 | + dl_iterate_phdr(LibraryPrintCallback, fp); |
| 1036 | +#elif __APPLE__ |
| 1037 | + int i = 0; |
| 1038 | + const char *name = _dyld_get_image_name(i); |
| 1039 | + while (name != nullptr) { |
| 1040 | + fprintf(fp, " %s\n", name); |
| 1041 | + i++; |
| 1042 | + name = _dyld_get_image_name(i); |
| 1043 | + } |
| 1044 | +#elif _AIX |
| 1045 | + // We can't tell in advance how large the buffer needs to be. |
| 1046 | + // Retry until we reach too large a size (1Mb). |
| 1047 | + const unsigned int buffer_inc = 4096; |
| 1048 | + unsigned int buffer_size = buffer_inc; |
| 1049 | + char* buffer = (char*) malloc(buffer_size); |
| 1050 | + int rc = -1; |
| 1051 | + while (buffer != nullptr && rc != 0 && buffer_size < 1024 * 1024) { |
| 1052 | + rc = loadquery(L_GETINFO, buffer, buffer_size); |
| 1053 | + if (rc == 0) { |
| 1054 | + break; |
| 1055 | + } |
| 1056 | + free(buffer); |
| 1057 | + buffer_size += buffer_inc; |
| 1058 | + buffer = (char*) malloc(buffer_size); |
| 1059 | + } |
| 1060 | + if (buffer == nullptr) { |
| 1061 | + return; // Don't try to free the buffer. |
| 1062 | + } |
| 1063 | + if (rc == 0) { |
| 1064 | + char* buf = buffer; |
| 1065 | + ld_info* cur_info = nullptr; |
| 1066 | + do { |
| 1067 | + cur_info = (ld_info*) buf; |
| 1068 | + char* member_name = cur_info->ldinfo_filename |
| 1069 | + + strlen(cur_info->ldinfo_filename) + 1; |
| 1070 | + if (*member_name != '\0') { |
| 1071 | + fprintf(fp, " %s(%s)\n", cur_info->ldinfo_filename, member_name); |
| 1072 | + } else { |
| 1073 | + fprintf(fp, " %s\n", cur_info->ldinfo_filename); |
| 1074 | + } |
| 1075 | + buf += cur_info->ldinfo_next; |
| 1076 | + } while (cur_info->ldinfo_next != 0); |
| 1077 | + } |
| 1078 | + free(buffer); |
| 1079 | + |
| 1080 | +#elif _WIN32 |
| 1081 | + // Windows implementation - get a handle to the process. |
| 1082 | + HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, |
| 1083 | + FALSE, GetCurrentProcessId()); |
| 1084 | + if (process_handle == NULL) { |
| 1085 | + fprintf(fp, "No library information available\n"); |
| 1086 | + return; |
| 1087 | + } |
| 1088 | + // Get a list of all the modules in this process |
| 1089 | + DWORD size_1 = 0, size_2 = 0; |
| 1090 | + // First call to get the size of module array needed |
| 1091 | + if (EnumProcessModules(process_handle, NULL, 0, &size_1)) { |
| 1092 | + HMODULE* modules = (HMODULE*) malloc(size_1); |
| 1093 | + if (modules == NULL) { |
| 1094 | + return; // bail out if malloc failed |
| 1095 | + } |
| 1096 | + // Second call to populate the module array |
| 1097 | + if (EnumProcessModules(process_handle, modules, size_1, &size_2)) { |
| 1098 | + for (int i = 0; |
| 1099 | + i < (size_1 / sizeof(HMODULE)) && i < (size_2 / sizeof(HMODULE)); |
| 1100 | + i++) { |
| 1101 | + TCHAR module_name[MAX_PATH]; |
| 1102 | + // Obtain and print the full pathname for each module |
| 1103 | + if (GetModuleFileNameEx(process_handle, modules[i], module_name, |
| 1104 | + sizeof(module_name) / sizeof(TCHAR))) { |
| 1105 | + fprintf(fp," %s\n", module_name); |
| 1106 | + } |
| 1107 | + } |
| 1108 | + } |
| 1109 | + free(modules); |
| 1110 | + } else { |
| 1111 | + fprintf(fp, "No library information available\n"); |
| 1112 | + } |
| 1113 | + // Release the handle to the process. |
| 1114 | + CloseHandle(process_handle); |
| 1115 | +#endif |
1006 | 1116 | } |
1007 | 1117 |
|
1008 | 1118 | /******************************************************************************* |
|
0 commit comments