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:
parent
e259f83e0f
commit
297ebe6b97
@ -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
|
||||
be empty if an error occured.
|
||||
|
||||
This method is currently only implemented under Win32 and is useful mostly for
|
||||
diagnostics purposes.
|
||||
This method is currently implemented only under Win32 and Linux and is useful
|
||||
mostly for diagnostics purposes.
|
||||
|
||||
|
||||
\membersection{wxDynamicLibrary::Load}\label{wxdynamiclibraryload}
|
||||
|
@ -388,7 +388,7 @@ static void TestDllLoad()
|
||||
#error "don't know how to test wxDllLoader on this platform"
|
||||
#endif
|
||||
|
||||
wxPuts(_T("*** testing wxDllLoader ***\n"));
|
||||
wxPuts(_T("*** testing basic wxDynamicLibrary functions ***\n"));
|
||||
|
||||
wxDynamicLibrary lib(LIB_NAME);
|
||||
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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -4096,6 +4124,7 @@ int main(int argc, char **argv)
|
||||
|
||||
#ifdef TEST_DLLLOADER
|
||||
TestDllLoad();
|
||||
TestDllListLoaded();
|
||||
#endif // TEST_DLLLOADER
|
||||
|
||||
#ifdef TEST_ENVIRON
|
||||
|
@ -26,6 +26,7 @@
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
|
||||
#include "wx/dynlib.h"
|
||||
#include "wx/ffile.h"
|
||||
|
||||
#if defined(HAVE_DLOPEN) || defined(__DARWIN__)
|
||||
#define USE_POSIX_DL_FUNCS
|
||||
@ -243,6 +244,10 @@ void *wxDynamicLibrary::RawGetSymbol(wxDllType handle, const wxString& name)
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// error handling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef wxHAVE_DYNLIB_ERROR
|
||||
|
||||
/* static */
|
||||
@ -260,5 +265,118 @@ void wxDynamicLibrary::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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user