Repository navigation
src: GetLoadedLibraries routine under NativeSymbolDebuggingContext #24825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,27 @@ | |
|
|
||
| #endif // __POSIX__ | ||
|
|
||
| #if defined(__linux__) || defined(__sun) | ||
| #include <link.h> | ||
| #endif // (__linux__) || defined(__sun) | ||
|
|
||
| #ifdef __APPLE__ | ||
| #include <mach-o/dyld.h> // _dyld_get_image_name() | ||
| #endif // __APPLE__ | ||
|
|
||
| #ifdef _AIX | ||
| #include <sys/ldr.h> // ld_info structure | ||
| #endif // _AIX | ||
|
|
||
| #ifdef _WIN32 | ||
| #include <Lm.h> | ||
| #include <Windows.h> | ||
| #include <dbghelp.h> | ||
| #include <process.h> | ||
| #include <psapi.h> | ||
| #include <tchar.h> | ||
| #endif // _WIN32 | ||
|
|
||
| namespace node { | ||
|
|
||
| #ifdef __POSIX__ | ||
|
|
@@ -299,6 +320,103 @@ void CheckedUvLoopClose(uv_loop_t* loop) { | |
| CHECK(0 && "uv_loop_close() while having open handles"); | ||
| } | ||
|
|
||
| std::vector<std::string> NativeSymbolDebuggingContext::GetLoadedLibraries() { | ||
| std::vector<std::string> list; | ||
| #ifdef __linux__ | ||
| dl_iterate_phdr( | ||
| [](struct dl_phdr_info* info, size_t size, void* data) { | ||
| auto list = static_cast<std::vector<std::string>*>(data); | ||
| if (*info->dlpi_name != '\0') { | ||
| list->push_back(info->dlpi_name); | ||
| } | ||
| return 0; | ||
| }, | ||
| &list); | ||
| #elif __APPLE__ | ||
| uint32_t i = 0; | ||
| for (const char* name = _dyld_get_image_name(i); name != nullptr; | ||
| name = _dyld_get_image_name(++i)) { | ||
| list.push_back(name); | ||
| } | ||
|
|
||
| #elif _AIX | ||
| // We can't tell in advance how large the buffer needs to be. | ||
| // Retry until we reach too large a size (1Mb). | ||
| const unsigned int kBufferGrowStep = 4096; | ||
| MallocedBuffer<char> buffer(kBufferGrowStep); | ||
| int rc = -1; | ||
| do { | ||
| rc = loadquery(L_GETINFO, buffer.data, buffer.size); | ||
| if (rc == 0) break; | ||
| buffer = MallocedBuffer<char>(buffer.size + kBufferGrowStep); | ||
| } while (buffer.size < 1024 * 1024); | ||
|
|
||
| if (rc == 0) { | ||
| char* buf = buffer.data; | ||
| ld_info* cur_info = nullptr; | ||
| do { | ||
| std::ostringstream str; | ||
| cur_info = reinterpret_cast<ld_info*>(buf); | ||
| char* member_name = cur_info->ldinfo_filename + | ||
| strlen(cur_info->ldinfo_filename) + 1; | ||
| if (*member_name != '\0') { | ||
| str << cur_info->ldinfo_filename << "(" << member_name << ")"; | ||
| list.push_back(str.str()); | ||
| str.str(""); | ||
|
gireeshpunathil marked this conversation as resolved.
Outdated
|
||
| } else { | ||
| list.push_back(cur_info->ldinfo_filename); | ||
| } | ||
| buf += cur_info->ldinfo_next; | ||
| } while (cur_info->ldinfo_next != 0); | ||
| } | ||
| #elif __sun | ||
| Link_map* p; | ||
|
|
||
| if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &p) != -1) { | ||
| for (Link_map* l = p; l != nullptr; l = l->l_next) { | ||
| list.push_back(l->l_name); | ||
| } | ||
| } | ||
|
|
||
| #elif _WIN32 | ||
| // Windows implementation - get a handle to the process. | ||
| HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, | ||
| FALSE, GetCurrentProcessId()); | ||
| if (process_handle == nullptr) { | ||
| // Cannot proceed, return an empty list. | ||
| return list; | ||
| } | ||
| // Get a list of all the modules in this process | ||
| DWORD size_1 = 0; | ||
| DWORD size_2 = 0; | ||
| // First call to get the size of module array needed | ||
| if (EnumProcessModules(process_handle, nullptr, 0, &size_1)) { | ||
| MallocedBuffer<HMODULE> modules(size_1); | ||
|
|
||
| // Second call to populate the module array | ||
| if (EnumProcessModules(process_handle, modules.data, size_1, &size_2)) { | ||
| for (DWORD i = 0; | ||
| i < (size_1 / sizeof(HMODULE)) && i < (size_2 / sizeof(HMODULE)); | ||
|
gireeshpunathil marked this conversation as resolved.
Outdated
|
||
| i++) { | ||
| WCHAR module_name[MAX_PATH]; | ||
| // Obtain and report the full pathname for each module | ||
| if (GetModuleFileNameEx(process_handle, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks @bzoz . I have 2 options;
On an assumption that the module names wont be made with wide characters, do you think the second option is an overkill, and we can just go with TCHAR instead? pls let me know.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I’d definitely prefer not to make such an assumption…
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, thanks @addaleax for the assertion. Pushed a fix that makes no assumptions on the module name format. |
||
| modules.data[i], | ||
| module_name, | ||
| arraysize(module_name) / sizeof(WCHAR))) { | ||
| list.push_back(module_name); | ||
|
addaleax marked this conversation as resolved.
Outdated
|
||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Release the handle to the process. | ||
| CloseHandle(process_handle); | ||
| #endif | ||
| return list; | ||
| } | ||
|
|
||
|
|
||
| } // namespace node | ||
|
|
||
| extern "C" void __DumpBacktrace(FILE* fp) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.