no more need for ldd in StackTrace, read from /proc/self/maps
This commit is contained in:
@@ -9,6 +9,9 @@
|
|||||||
@license LGPL, see file <a href="license.html">COPYING</a>
|
@license LGPL, see file <a href="license.html">COPYING</a>
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.7 2004/10/13 10:47:15 marc
|
||||||
|
no more need for ldd in StackTrace, read from /proc/self/maps
|
||||||
|
|
||||||
Revision 1.6 2004/10/11 15:58:51 marc
|
Revision 1.6 2004/10/11 15:58:51 marc
|
||||||
First version with working support for shared libraries!
|
First version with working support for shared libraries!
|
||||||
|
|
||||||
@@ -45,6 +48,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <fstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
#if defined(__solaris__)
|
#if defined(__solaris__)
|
||||||
@@ -237,10 +241,10 @@ bool mrw::StackTrace::createSymtable(const mrw::StackTrace::BinFiles& files)
|
|||||||
mrw::StackTrace::BinFiles mrw::StackTrace::filename()
|
mrw::StackTrace::BinFiles mrw::StackTrace::filename()
|
||||||
throw(std::bad_exception) {
|
throw(std::bad_exception) {
|
||||||
mrw::StackTrace::BinFiles res;
|
mrw::StackTrace::BinFiles res;
|
||||||
std::string s;
|
|
||||||
s<<"/proc/"<<getpid();
|
|
||||||
# if defined(__solaris__)
|
# if defined(__solaris__)
|
||||||
{
|
{
|
||||||
|
std::string s;
|
||||||
|
s<<"/proc/"<<getpid();
|
||||||
AutoFile fd(open(s.str(), O_RDONLY));
|
AutoFile fd(open(s.str(), O_RDONLY));
|
||||||
prpsinfo_t status;
|
prpsinfo_t status;
|
||||||
if (fd==-1 || ioctl(fd, PIOCPSINFO, &status)==-1) return res;
|
if (fd==-1 || ioctl(fd, PIOCPSINFO, &status)==-1) return res;
|
||||||
@@ -249,26 +253,18 @@ mrw::StackTrace::BinFiles mrw::StackTrace::filename()
|
|||||||
}
|
}
|
||||||
# elif defined(__linux__)
|
# elif defined(__linux__)
|
||||||
{
|
{
|
||||||
res<<BinFiles::value_type(s<<"/exe", 0);
|
res<<BinFiles::value_type("/proc/self/exe", 0);
|
||||||
try {
|
std::ifstream is("/proc/self/maps");
|
||||||
mrw::Exec ldd = (mrw::Cmd("/usr/bin/ldd"), s).execute();
|
std::string s;
|
||||||
for (std::string lddres(ldd.result());
|
std::string range, perm, x1, x2, size, lib;
|
||||||
lddres.size();
|
while (getline(is, s)) {
|
||||||
lddres.erase(0, min(lddres.find('\n')+1, std::string::npos))) {
|
range = perm = x1 = x2 = size = lib = "????";
|
||||||
std::string line(lddres.substr(0, lddres.find('\n')));
|
s>>range>>perm>>x1>>x2>>size>>lib;
|
||||||
std::string::size_type pos = line.find(" => ");
|
range.resize(range.find_first_not_of("0123456789abcdefABCDEF"));
|
||||||
if (pos<std::string::npos) {
|
void* addr(0);
|
||||||
pos += 4;
|
range>>addr;
|
||||||
std::string file = line.substr(pos, (pos=line.find(' ', pos)-pos));
|
if (lib.size() && addr>0) res<<BinFiles::value_type(lib, addr);
|
||||||
std::stringstream addr;
|
|
||||||
addr<<line.substr(++(pos=line.find('(', pos)),
|
|
||||||
line.find(')', pos)-pos);
|
|
||||||
void* address(0);
|
|
||||||
addr>>address;
|
|
||||||
if (file.size()) res<<BinFiles::value_type(file, address);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} catch (mrw::ExecutionFailedExc&) {}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
@@ -276,7 +272,7 @@ mrw::StackTrace::BinFiles mrw::StackTrace::filename()
|
|||||||
# warning "Don't know how to get executable file name in your system!"
|
# warning "Don't know how to get executable file name in your system!"
|
||||||
# warning "Impossible to get function names in stack trace!"
|
# warning "Impossible to get function names in stack trace!"
|
||||||
# warning "Give the path to the executable to StackTrace::createSymtable!"
|
# warning "Give the path to the executable to StackTrace::createSymtable!"
|
||||||
abort();
|
return res; // empty
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,9 @@
|
|||||||
@license LGPL, see file <a href="license.html">COPYING</a>
|
@license LGPL, see file <a href="license.html">COPYING</a>
|
||||||
|
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.9 2004/10/13 10:47:15 marc
|
||||||
|
no more need for ldd in StackTrace, read from /proc/self/maps
|
||||||
|
|
||||||
Revision 1.8 2004/10/11 16:49:32 marc
|
Revision 1.8 2004/10/11 16:49:32 marc
|
||||||
Better comment for new shared library feature
|
Better comment for new shared library feature
|
||||||
|
|
||||||
@@ -90,7 +93,6 @@ namespace mrw {
|
|||||||
- either a GNU glibc bases system (LINUX), or the GNU gcc compiler
|
- either a GNU glibc bases system (LINUX), or the GNU gcc compiler
|
||||||
- a system with ELF binaries (LINUX, Solaris, ...)
|
- a system with ELF binaries (LINUX, Solaris, ...)
|
||||||
- debug information, compile option @c -g
|
- debug information, compile option @c -g
|
||||||
- it must be linked with @c -libery and @c -lbfd
|
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
@@ -108,10 +110,8 @@ namespace mrw {
|
|||||||
once, before evaluating the first stack trace.Best place is the
|
once, before evaluating the first stack trace.Best place is the
|
||||||
first line of the @c main function.
|
first line of the @c main function.
|
||||||
|
|
||||||
@note This class requires libbfd an libiberty. Debug information
|
@note Debug information is required for compiling. You nee the
|
||||||
is required for compiling. You nee the compile option @c -g, or
|
compile option @c -g, or even better @c -ggdb3.
|
||||||
even better @c -ggdb3. To link, you need @c -lmrw, @c -lbfd and
|
|
||||||
@c -liberty.
|
|
||||||
|
|
||||||
@note The stack trace is known to work perfectly on Linux and
|
@note The stack trace is known to work perfectly on Linux and
|
||||||
Solaris both with GNU gcc compiler. But it should work with the
|
Solaris both with GNU gcc compiler. But it should work with the
|
||||||
@@ -145,17 +145,43 @@ namespace mrw {
|
|||||||
|
|
||||||
Unfortunately it is not possible to extract the source file name
|
Unfortunately it is not possible to extract the source file name
|
||||||
and line number information if the executable was not compiled
|
and line number information if the executable was not compiled
|
||||||
with debug option @c -g. But what's worse, it is not possible to
|
with debug option @c -g.
|
||||||
ger symbolic information from libraries linked to the
|
|
||||||
executable. Perhaps it could be possible, if I'd add a
|
|
||||||
possibility to read and evaluate these libraries, but that's for
|
|
||||||
a future release. (Now, 10/08/2004, I am working on it)
|
|
||||||
|
|
||||||
@todo Add support to read debugging information from libraries
|
|
||||||
that are linked to the executable. (soon)
|
|
||||||
|
|
||||||
@todo Add support for alternative symbol evaluation using @c
|
@todo Add support for alternative symbol evaluation using @c
|
||||||
backtrace_symbols.
|
backtrace_symbols.
|
||||||
|
|
||||||
|
@bug File and line is wrong where the exception is thrown. On
|
||||||
|
Address [0x4007830b] file and line is wrong, the file should be
|
||||||
|
/privat/home/marc/pro/mrw-c++/mrw/exception.cpp. File and line
|
||||||
|
are always wrong at the line where the exception is
|
||||||
|
instanciated. Why?!? (Could it be, because there is a string
|
||||||
|
created inline? The trace always shows basic_string.h.)
|
||||||
|
@code
|
||||||
|
UNEXPECTED EXCEPTION: ----------------------------
|
||||||
|
---------- Reason:
|
||||||
|
mrw::Exec: command execution failed
|
||||||
|
failed command was: "/bin/false"
|
||||||
|
error was: "execution failed"
|
||||||
|
---------- Stack:
|
||||||
|
1[0x8049b71] ../sysdeps/i386/elf/start.S:105 _start
|
||||||
|
[0x4022f92b] ????:0 __libc_start_main
|
||||||
|
[0x8049c96] /usr/include/g++/bits/basic_string.h:249 main
|
||||||
|
[0x40054668] ????:0 CppUnit::TextUi::TestRunner::run(std::string, bool, bool, bool)
|
||||||
|
[0x40054747] ????:0 CppUnit::TextUi::TestRunner::runTestByName(std::string, bool)
|
||||||
|
[0x400543ec] ????:0 CppUnit::TextUi::TestRunner::runTest(CppUnit::Test*, bool)
|
||||||
|
[0x4005525b] ????:0 CppUnit::TestSuite::run(CppUnit::TestResult*)
|
||||||
|
[0x4005525b] ????:0 CppUnit::TestSuite::run(CppUnit::TestResult*)
|
||||||
|
[0x4005525b] ????:0 CppUnit::TestSuite::run(CppUnit::TestResult*)
|
||||||
|
[0x4004aa06] ????:0 CppUnit::TestCase::run(CppUnit::TestResult*)
|
||||||
|
[0x804b164] /usr/include/cppunit/TestCaller.h:166 CppUnit::TestCaller<ExecTest, std::bad_exception>::runTest()
|
||||||
|
[0x804b299] /usr/include/g++/bits/stl_alloc.h:652 ExecTest::unexpectedExc()
|
||||||
|
[0x40078bda] /privat/home/marc/pro/mrw-c++/mrw/exec.cpp:77 mrw::Cmd::execute(bool) const
|
||||||
|
[0x4007830b] /usr/include/g++/bits/basic_string.h:249 mrw::Exec::execute(bool)
|
||||||
|
[0x40077941] /privat/home/marc/pro/mrw-c++/mrw/exec.cpp:38 mrw::ExecutionFailedExc::ExecutionFailedExc(std::string const&, std::string const&)
|
||||||
|
[0x400769d4] /privat/home/marc/pro/mrw-c++/mrw/exception.cpp:41 mrw::exception::exception()
|
||||||
|
[0x4007cbc5] /privat/home/marc/pro/mrw-c++/mrw/stacktrace.cpp:118 mrw::StackTrace::StackTrace()
|
||||||
|
-------------------------------------------------
|
||||||
|
@endcode
|
||||||
*/
|
*/
|
||||||
class StackTrace {
|
class StackTrace {
|
||||||
public:
|
public:
|
||||||
@@ -193,11 +219,10 @@ namespace mrw {
|
|||||||
/** @brief read the symbol table from the executable file or a
|
/** @brief read the symbol table from the executable file or a
|
||||||
shared library
|
shared library
|
||||||
|
|
||||||
On Solaris and Linux, the name of the executable is
|
On Solaris and Linux, the executable is automatically
|
||||||
automatically detected through the @c /dev/proc file
|
detected through the @c /proc file system. Only on Linux the
|
||||||
system. Only on Linux the shared libraries are detected
|
shared libraries are detected through @c /proc/self/maps. So
|
||||||
through a call to @c ldd. So you may leave the parameter
|
you may leave the parameter empty on these systems.
|
||||||
empty on these systems.
|
|
||||||
|
|
||||||
@param fname The file name of the executable or a shared
|
@param fname The file name of the executable or a shared
|
||||||
library. On Linux and Solaris, this can be evaluated
|
library. On Linux and Solaris, this can be evaluated
|
||||||
|
Reference in New Issue
Block a user