implemented wxDynamicLibrary::ListLoaded() for Linux; added test for it
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31408 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -130,8 +130,8 @@ of all modules loaded into the address space of the current project, the array
|
|||||||
elements are object of \texttt{wxDynamicLibraryDetails} class. The array will
|
elements are object of \texttt{wxDynamicLibraryDetails} class. The array will
|
||||||
be empty if an error occured.
|
be empty if an error occured.
|
||||||
|
|
||||||
This method is currently only implemented under Win32 and is useful mostly for
|
This method is currently implemented only under Win32 and Linux and is useful
|
||||||
diagnostics purposes.
|
mostly for diagnostics purposes.
|
||||||
|
|
||||||
|
|
||||||
\membersection{wxDynamicLibrary::Load}\label{wxdynamiclibraryload}
|
\membersection{wxDynamicLibrary::Load}\label{wxdynamiclibraryload}
|
||||||
|
@@ -388,7 +388,7 @@ static void TestDllLoad()
|
|||||||
#error "don't know how to test wxDllLoader on this platform"
|
#error "don't know how to test wxDllLoader on this platform"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxPuts(_T("*** testing wxDllLoader ***\n"));
|
wxPuts(_T("*** testing basic wxDynamicLibrary functions ***\n"));
|
||||||
|
|
||||||
wxDynamicLibrary lib(LIB_NAME);
|
wxDynamicLibrary lib(LIB_NAME);
|
||||||
if ( !lib.IsLoaded() )
|
if ( !lib.IsLoaded() )
|
||||||
@@ -421,6 +421,34 @@ static void TestDllLoad()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__WXMSW__) || defined(__UNIX__)
|
||||||
|
|
||||||
|
static void TestDllListLoaded()
|
||||||
|
{
|
||||||
|
wxPuts(_T("*** testing wxDynamicLibrary::ListLoaded() ***\n"));
|
||||||
|
|
||||||
|
puts("\nLoaded modules:");
|
||||||
|
wxDynamicLibraryDetailsArray dlls = wxDynamicLibrary::ListLoaded();
|
||||||
|
const size_t count = dlls.GetCount();
|
||||||
|
for ( size_t n = 0; n < count; ++n )
|
||||||
|
{
|
||||||
|
const wxDynamicLibraryDetails& details = dlls[n];
|
||||||
|
printf("%-45s", details.GetPath().c_str());
|
||||||
|
|
||||||
|
void *addr;
|
||||||
|
size_t len;
|
||||||
|
if ( details.GetAddress(&addr, &len) )
|
||||||
|
{
|
||||||
|
printf(" %08lx:%08lx",
|
||||||
|
(unsigned long)addr, (unsigned long)((char *)addr + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" %s\n", details.GetVersion().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // TEST_DLLLOADER
|
#endif // TEST_DLLLOADER
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -4096,6 +4124,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
#ifdef TEST_DLLLOADER
|
#ifdef TEST_DLLLOADER
|
||||||
TestDllLoad();
|
TestDllLoad();
|
||||||
|
TestDllListLoaded();
|
||||||
#endif // TEST_DLLLOADER
|
#endif // TEST_DLLLOADER
|
||||||
|
|
||||||
#ifdef TEST_ENVIRON
|
#ifdef TEST_ENVIRON
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#if wxUSE_DYNLIB_CLASS
|
#if wxUSE_DYNLIB_CLASS
|
||||||
|
|
||||||
#include "wx/dynlib.h"
|
#include "wx/dynlib.h"
|
||||||
|
#include "wx/ffile.h"
|
||||||
|
|
||||||
#if defined(HAVE_DLOPEN) || defined(__DARWIN__)
|
#if defined(HAVE_DLOPEN) || defined(__DARWIN__)
|
||||||
#define USE_POSIX_DL_FUNCS
|
#define USE_POSIX_DL_FUNCS
|
||||||
@@ -243,6 +244,10 @@ void *wxDynamicLibrary::RawGetSymbol(wxDllType handle, const wxString& name)
|
|||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// error handling
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef wxHAVE_DYNLIB_ERROR
|
#ifdef wxHAVE_DYNLIB_ERROR
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
@@ -260,5 +265,118 @@ void wxDynamicLibrary::Error()
|
|||||||
|
|
||||||
#endif // wxHAVE_DYNLIB_ERROR
|
#endif // wxHAVE_DYNLIB_ERROR
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// listing loaded modules
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// wxDynamicLibraryDetails declares this class as its friend, so put the code
|
||||||
|
// initializing new details objects here
|
||||||
|
class wxDynamicLibraryDetailsCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// create a new wxDynamicLibraryDetails from the given data
|
||||||
|
static wxDynamicLibraryDetails *
|
||||||
|
New(unsigned long start, unsigned long end, const wxString& path)
|
||||||
|
{
|
||||||
|
wxDynamicLibraryDetails *details = new wxDynamicLibraryDetails;
|
||||||
|
details->m_path = path;
|
||||||
|
details->m_name = path.AfterLast(_T('/'));
|
||||||
|
details->m_address = wx_reinterpret_cast(void *, start);
|
||||||
|
details->m_length = end - start;
|
||||||
|
|
||||||
|
// try to extract the library version from its name
|
||||||
|
const size_t posExt = path.rfind(_T(".so"));
|
||||||
|
if ( posExt != wxString::npos )
|
||||||
|
{
|
||||||
|
if ( path.c_str()[posExt + 3] == _T('.') )
|
||||||
|
{
|
||||||
|
// assume "libfoo.so.x.y.z" case
|
||||||
|
details->m_version.assign(path, posExt + 4, wxString::npos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t posDash = path.find_last_of(_T('-'), posExt);
|
||||||
|
if ( posDash != wxString::npos )
|
||||||
|
{
|
||||||
|
// assume "libbar-x.y.z.so" case
|
||||||
|
posDash++;
|
||||||
|
details->m_version.assign(path, posDash, posExt - posDash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
|
||||||
|
{
|
||||||
|
wxDynamicLibraryDetailsArray dlls;
|
||||||
|
|
||||||
|
#ifdef __LINUX__
|
||||||
|
// examine /proc/self/maps to find out what is loaded in our address space
|
||||||
|
wxFFile file("/proc/self/maps");
|
||||||
|
if ( file.IsOpened() )
|
||||||
|
{
|
||||||
|
// details of the module currently being parsed
|
||||||
|
wxString pathCur;
|
||||||
|
unsigned long startCur,
|
||||||
|
endCur;
|
||||||
|
|
||||||
|
char path[1024];
|
||||||
|
char buf[1024];
|
||||||
|
while ( fgets(buf, WXSIZEOF(buf), file.fp()) )
|
||||||
|
{
|
||||||
|
// format is: start-end perm something? maj:min inode path
|
||||||
|
unsigned long start, end;
|
||||||
|
switch ( sscanf(buf, "%08lx-%08lx %*4s %*08x %*02d:%*02d %*d %1024s\n",
|
||||||
|
&start, &end, path) )
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
// there may be no path column
|
||||||
|
path[0] = '\0';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
// nothing to do, read everything we wanted
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// chop '\n'
|
||||||
|
buf[strlen(buf) - 1] = '\0';
|
||||||
|
wxLogDebug(_T("Failed to parse line \"%s\" in /proc/self/maps."),
|
||||||
|
buf);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString pathNew = wxString::FromAscii(path);
|
||||||
|
if ( pathCur.empty() )
|
||||||
|
{
|
||||||
|
// new module start
|
||||||
|
pathCur = pathNew;
|
||||||
|
startCur = start;
|
||||||
|
endCur = end;
|
||||||
|
}
|
||||||
|
else if ( pathCur == pathNew )
|
||||||
|
{
|
||||||
|
// continuation of the same module
|
||||||
|
wxASSERT_MSG( start == endCur, _T("hole in /proc/self/maps?") );
|
||||||
|
endCur = end;
|
||||||
|
}
|
||||||
|
else // end of the current module
|
||||||
|
{
|
||||||
|
dlls.Add(wxDynamicLibraryDetailsCreator::New(startCur,
|
||||||
|
endCur,
|
||||||
|
pathCur));
|
||||||
|
pathCur.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // __LINUX__
|
||||||
|
|
||||||
|
return dlls;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // wxUSE_DYNLIB_CLASS
|
#endif // wxUSE_DYNLIB_CLASS
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user