Version 0.90
This commit is contained in:
18
COPYING
18
COPYING
@@ -57,7 +57,7 @@ modified by someone else and passed on, the recipients should know
|
|||||||
that what they have is not the original version, so that the original
|
that what they have is not the original version, so that the original
|
||||||
author's reputation will not be affected by problems that might be
|
author's reputation will not be affected by problems that might be
|
||||||
introduced by others.
|
introduced by others.
|
||||||
^L
|
|
||||||
Finally, software patents pose a constant threat to the existence of
|
Finally, software patents pose a constant threat to the existence of
|
||||||
any free program. We wish to make sure that a company cannot
|
any free program. We wish to make sure that a company cannot
|
||||||
effectively restrict the users of a free program by obtaining a
|
effectively restrict the users of a free program by obtaining a
|
||||||
@@ -113,7 +113,7 @@ modification follow. Pay close attention to the difference between a
|
|||||||
"work based on the library" and a "work that uses the library". The
|
"work based on the library" and a "work that uses the library". The
|
||||||
former contains code derived from the library, whereas the latter must
|
former contains code derived from the library, whereas the latter must
|
||||||
be combined with the library in order to run.
|
be combined with the library in order to run.
|
||||||
^L
|
|
||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ Library.
|
|||||||
You may charge a fee for the physical act of transferring a copy,
|
You may charge a fee for the physical act of transferring a copy,
|
||||||
and you may at your option offer warranty protection in exchange for a
|
and you may at your option offer warranty protection in exchange for a
|
||||||
fee.
|
fee.
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Library or any portion
|
2. You may modify your copy or copies of the Library or any portion
|
||||||
of it, thus forming a work based on the Library, and copy and
|
of it, thus forming a work based on the Library, and copy and
|
||||||
distribute such modifications or work under the terms of Section 1
|
distribute such modifications or work under the terms of Section 1
|
||||||
@@ -218,7 +218,7 @@ instead of to this License. (If a newer version than version 2 of the
|
|||||||
ordinary GNU General Public License has appeared, then you can specify
|
ordinary GNU General Public License has appeared, then you can specify
|
||||||
that version instead if you wish.) Do not make any other change in
|
that version instead if you wish.) Do not make any other change in
|
||||||
these notices.
|
these notices.
|
||||||
^L
|
|
||||||
Once this change is made in a given copy, it is irreversible for
|
Once this change is made in a given copy, it is irreversible for
|
||||||
that copy, so the ordinary GNU General Public License applies to all
|
that copy, so the ordinary GNU General Public License applies to all
|
||||||
subsequent copies and derivative works made from that copy.
|
subsequent copies and derivative works made from that copy.
|
||||||
@@ -269,7 +269,7 @@ Library will still fall under Section 6.)
|
|||||||
distribute the object code for the work under the terms of Section 6.
|
distribute the object code for the work under the terms of Section 6.
|
||||||
Any executables containing that work also fall under Section 6,
|
Any executables containing that work also fall under Section 6,
|
||||||
whether or not they are linked directly with the Library itself.
|
whether or not they are linked directly with the Library itself.
|
||||||
^L
|
|
||||||
6. As an exception to the Sections above, you may also combine or
|
6. As an exception to the Sections above, you may also combine or
|
||||||
link a "work that uses the Library" with the Library to produce a
|
link a "work that uses the Library" with the Library to produce a
|
||||||
work containing portions of the Library, and distribute that work
|
work containing portions of the Library, and distribute that work
|
||||||
@@ -331,7 +331,7 @@ restrictions of other proprietary libraries that do not normally
|
|||||||
accompany the operating system. Such a contradiction means you cannot
|
accompany the operating system. Such a contradiction means you cannot
|
||||||
use both them and the Library together in an executable that you
|
use both them and the Library together in an executable that you
|
||||||
distribute.
|
distribute.
|
||||||
^L
|
|
||||||
7. You may place library facilities that are a work based on the
|
7. You may place library facilities that are a work based on the
|
||||||
Library side-by-side in a single library together with other library
|
Library side-by-side in a single library together with other library
|
||||||
facilities not covered by this License, and distribute such a combined
|
facilities not covered by this License, and distribute such a combined
|
||||||
@@ -372,7 +372,7 @@ subject to these terms and conditions. You may not impose any further
|
|||||||
restrictions on the recipients' exercise of the rights granted herein.
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
You are not responsible for enforcing compliance by third parties with
|
You are not responsible for enforcing compliance by third parties with
|
||||||
this License.
|
this License.
|
||||||
^L
|
|
||||||
11. If, as a consequence of a court judgment or allegation of patent
|
11. If, as a consequence of a court judgment or allegation of patent
|
||||||
infringement or for any other reason (not limited to patent issues),
|
infringement or for any other reason (not limited to patent issues),
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
@@ -425,7 +425,7 @@ conditions either of that version or of any later version published by
|
|||||||
the Free Software Foundation. If the Library does not specify a
|
the Free Software Foundation. If the Library does not specify a
|
||||||
license version number, you may choose any version ever published by
|
license version number, you may choose any version ever published by
|
||||||
the Free Software Foundation.
|
the Free Software Foundation.
|
||||||
^L
|
|
||||||
14. If you wish to incorporate parts of the Library into other free
|
14. If you wish to incorporate parts of the Library into other free
|
||||||
programs whose distribution conditions are incompatible with these,
|
programs whose distribution conditions are incompatible with these,
|
||||||
write to the author to ask for permission. For software which is
|
write to the author to ask for permission. For software which is
|
||||||
@@ -459,7 +459,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
|||||||
DAMAGES.
|
DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
^L
|
|
||||||
How to Apply These Terms to Your New Libraries
|
How to Apply These Terms to Your New Libraries
|
||||||
|
|
||||||
If you develop a new library, and you want it to be of the greatest
|
If you develop a new library, and you want it to be of the greatest
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
* Fri Apr 24 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.90 (mrw)
|
||||||
|
- initial rpm with two spec files
|
||||||
|
- test cases for libmrwexcstderr and libmrwexclog4cxx
|
||||||
|
* Thu Apr 23 2004 Marc Wäckerlin <marc@waeckerlin.org> - mrw-c++-0.11 (mrw)
|
||||||
|
- better support for solaris, but not yet tested
|
||||||
|
- more and better documentation and a pdf file
|
||||||
|
- new submodule "Automated Unexpected Handler with Stack Trace"
|
||||||
|
5
NEWS
5
NEWS
@@ -0,0 +1,5 @@
|
|||||||
|
This is a preliminary release. Especially tests, configure
|
||||||
|
environment, packages and documentation are not yet finished. It
|
||||||
|
should already work, even though it may be not yet perfect.
|
||||||
|
|
||||||
|
It is know not to link on Solaris.
|
15
README
15
README
@@ -1,9 +1,6 @@
|
|||||||
Please read:
|
C++ Library for automated C-Library resource management, UNIX
|
||||||
- from the .tar.gz package:
|
Pipes, simple and secure UNIX system command execution, runtime
|
||||||
mrw/doc/html/index.html
|
stack trace and automated unexpected exception handling.
|
||||||
- from the .tar.gz installation:
|
|
||||||
/usr/local/share/mrw-c++/doc/html/index.html
|
HTML and PDF documentation is include in the installation (built with
|
||||||
- from the rpm installation:
|
Doxygen).
|
||||||
/usr/share/doc/packages/mrw-c++/doc/html/index.html
|
|
||||||
- the webpage at:
|
|
||||||
http://marc.waeckerlin.org/mrw-c++/index.html
|
|
||||||
|
4
bootstrap.sh
Executable file
4
bootstrap.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
make distclean
|
||||||
|
aclocal && libtoolize --force && automake && autoconf
|
31
configure.in
31
configure.in
@@ -1,9 +1,16 @@
|
|||||||
AC_INIT([mrw/stacktrace.hpp])
|
# init
|
||||||
|
AC_INIT([mrw/mrw.hpp.in])
|
||||||
PACKAGENAME=mrw-c++
|
PACKAGENAME=mrw-c++
|
||||||
MAJOR=0
|
MAJOR=0
|
||||||
MINOR=10
|
MINOR=90
|
||||||
SUPPORT=alfa
|
SUPPORT=beta
|
||||||
AM_INIT_AUTOMAKE(@PACKAGENAME@, @MAJOR@.@MINOR@)
|
AM_INIT_AUTOMAKE(@PACKAGENAME@, @MAJOR@.@MINOR@, [marc@waeckerlin.org])
|
||||||
|
|
||||||
|
# macros
|
||||||
|
README=README
|
||||||
|
AC_SUBST_FILE(README)
|
||||||
|
CHANGE_LOG=ChangeLog
|
||||||
|
AC_SUBST_FILE(CHANGE_LOG)
|
||||||
|
|
||||||
# languages
|
# languages
|
||||||
AC_LANG(C++)
|
AC_LANG(C++)
|
||||||
@@ -18,9 +25,18 @@ AC_PROG_LIBTOOL
|
|||||||
AC_CHECK_PROG(have_doxygen, doxygen, yes, no)
|
AC_CHECK_PROG(have_doxygen, doxygen, yes, no)
|
||||||
AC_CHECK_PROG(have_dot, dot, yes, no)
|
AC_CHECK_PROG(have_dot, dot, yes, no)
|
||||||
|
|
||||||
|
# solaris?
|
||||||
|
AC_CHECK_HEADER(sys/old_procfs.h, [AM_CPPFLAGS=-D__solaris__])
|
||||||
|
|
||||||
# libraries
|
# libraries
|
||||||
AC_SEARCH_LIBS(cplus_demangle, iberty)
|
AC_SEARCH_LIBS(cplus_demangle, iberty, [AC_MSG_RESULT([OK])],
|
||||||
AC_SEARCH_LIBS(bfd_get_symbol_leading_char, bfd)
|
[AC_MSG_ERROR([Library iberty is required!])])
|
||||||
|
AC_SEARCH_LIBS(bfd_arch_list, bfd, [AC_MSG_RESULT([OK])],
|
||||||
|
[
|
||||||
|
AC_SEARCH_LIBS(bfd_arch_list, bfd, [AC_MSG_RESULT([OK])],
|
||||||
|
[AC_MSG_ERROR([BFD library libbfd is required])],
|
||||||
|
[-lintl])
|
||||||
|
])
|
||||||
|
|
||||||
# Arguments
|
# Arguments
|
||||||
AM_MAINTAINER_MODE
|
AM_MAINTAINER_MODE
|
||||||
@@ -37,7 +53,8 @@ AC_SUBST(SUPPORT)
|
|||||||
AC_SUBST(PACKAGENAME)
|
AC_SUBST(PACKAGENAME)
|
||||||
|
|
||||||
# create output
|
# create output
|
||||||
AC_CONFIG_FILES([makefile mrw/makefile mrw/doxyfile mrw/mrw.hpp])
|
AC_CONFIG_FILES([makefile mrw-c++.spec mrw-c++-devel.spec
|
||||||
|
mrw/makefile mrw/doxyfile mrw/mrw.hpp])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
||||||
# infos and warnings
|
# infos and warnings
|
||||||
|
23
makefile.am
23
makefile.am
@@ -1,11 +1,24 @@
|
|||||||
SUBDIRS = mrw
|
SUBDIRS = mrw
|
||||||
|
|
||||||
include_HEADERS = mrw/auto.hpp mrw/unistd.hpp \
|
nobase_include_HEADERS = mrw/auto.hpp mrw/unistd.hpp \
|
||||||
mrw/stacktrace.hpp mrw/exception.hpp \
|
mrw/stacktrace.hpp mrw/exception.hpp \
|
||||||
mrw/exec.hpp
|
mrw/exec.hpp
|
||||||
data_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog
|
infosdir = ${pkgdatadir}
|
||||||
|
infos_DATA = AUTHORS NEWS README COPYING INSTALL ChangeLog \
|
||||||
|
@PACKAGENAME@.spec @PACKAGENAME@-devel.spec
|
||||||
|
|
||||||
webserver: all check doc dist
|
RPMS = /usr/src/packages/RPMS/i586/@PACKAGENAME@-@MAJOR@.@MINOR@-1.i586.rpm \
|
||||||
|
/usr/src/packages/RPMS/i586/@PACKAGENAME@-devel-@MAJOR@.@MINOR@-1.i586.rpm
|
||||||
|
|
||||||
|
rpm: dist
|
||||||
|
cp @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz /usr/src/packages/SOURCES/
|
||||||
|
rpmbuild -bb --clean @PACKAGENAME@.spec
|
||||||
|
rpmbuild -bb --clean @PACKAGENAME@-devel.spec
|
||||||
|
|
||||||
|
webserver: all check dist ${RPMS}
|
||||||
ssh root@waeckerlin.org mkdir -p /home/marc/mrw-c++
|
ssh root@waeckerlin.org mkdir -p /home/marc/mrw-c++
|
||||||
scp mrw/doc/html/* root@waeckerlin.org:/home/marc/mrw-c++/
|
scp mrw/doc/html/* \
|
||||||
scp @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz root@waeckerlin.org:/home/marc/mrw-c++/
|
mrw/doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf \
|
||||||
|
@PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz \
|
||||||
|
${RPMS} \
|
||||||
|
root@waeckerlin.org:/home/marc/mrw-c++/
|
||||||
|
42
mrw-c++-devel.spec.in
Normal file
42
mrw-c++-devel.spec.in
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# rpmbuild -bb --clean @PACKAGENAME@.spec
|
||||||
|
Summary: MRW's C++ Class Library, facilities for ease and quality
|
||||||
|
Name: @PACKAGENAME@-devel
|
||||||
|
Version: @MAJOR@.@MINOR@
|
||||||
|
Release: 1
|
||||||
|
License: LGPL
|
||||||
|
Group: Development/Libraries/C++
|
||||||
|
URL: http://marc.waeckerlin.org/mrw-c++/index.html
|
||||||
|
Source0: @PACKAGENAME@-@MAJOR@.@MINOR@.tar.gz
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
|
||||||
|
|
||||||
|
Prefix: /usr
|
||||||
|
|
||||||
|
Requires: gcc-c++ >= 3.0
|
||||||
|
Requires: binutils
|
||||||
|
Requires: @PACKAGENAME@ = @MAJOR@.@MINOR@
|
||||||
|
|
||||||
|
%description
|
||||||
|
@README@
|
||||||
|
|
||||||
|
This Package contains all files required for developement.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q -n @PACKAGENAME@-@MAJOR@.@MINOR@
|
||||||
|
./configure --prefix=$RPM_BUILD_ROOT/usr
|
||||||
|
|
||||||
|
%build
|
||||||
|
make check
|
||||||
|
|
||||||
|
%install
|
||||||
|
make install
|
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/lib/libmrw*.so*
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
/usr
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
@CHANGE_LOG@
|
46
mrw-c++.spec.in
Normal file
46
mrw-c++.spec.in
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# rpmbuild -bb --clean @PACKAGENAME@.spec
|
||||||
|
Summary: MRW's C++ Class Library, facilities for ease and quality
|
||||||
|
Name: @PACKAGENAME@
|
||||||
|
Version: @MAJOR@.@MINOR@
|
||||||
|
Release: 1
|
||||||
|
License: LGPL
|
||||||
|
Group: Development/Libraries/C++
|
||||||
|
URL: http://marc.waeckerlin.org/mrw-c++/index.html
|
||||||
|
Source0: %{name}-%{version}.tar.gz
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
|
||||||
|
|
||||||
|
Prefix: /usr
|
||||||
|
|
||||||
|
Requires: gcc-c++ >= 3.0
|
||||||
|
Requires: binutils
|
||||||
|
|
||||||
|
%description
|
||||||
|
@README@
|
||||||
|
|
||||||
|
This package contains only the shared libraries required at runtime.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q
|
||||||
|
./configure --prefix=$RPM_BUILD_ROOT/usr
|
||||||
|
|
||||||
|
%build
|
||||||
|
make check
|
||||||
|
|
||||||
|
%install
|
||||||
|
make install
|
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/share/mrw-c++
|
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/include/mrw
|
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/lib/libmrw*.la
|
||||||
|
rm -rf $RPM_BUILD_ROOT/usr/lib/libmrw*.a
|
||||||
|
rmdir $RPM_BUILD_ROOT/usr/include
|
||||||
|
rmdir $RPM_BUILD_ROOT/usr/share
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
/usr
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
@CHANGE_LOG@
|
@@ -19,6 +19,7 @@ namespace mrw {
|
|||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @brief Automatically closes a file when destructed.
|
/** @brief Automatically closes a file when destructed.
|
||||||
|
@pre #include <mrw/auto.hpp>
|
||||||
|
|
||||||
AutoFile works exactly like std::auto_ptr, but not for files
|
AutoFile works exactly like std::auto_ptr, but not for files
|
||||||
instead of pointers. Whenever the context of AutoFile is left,
|
instead of pointers. Whenever the context of AutoFile is left,
|
||||||
@@ -59,6 +60,7 @@ namespace mrw {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @brief Automatically call @c munmap for mmaped files on destruction.
|
/** @brief Automatically call @c munmap for mmaped files on destruction.
|
||||||
|
@pre #include <mrw/auto.hpp>
|
||||||
|
|
||||||
It's the same as std::auto_ptr, but for @c mmap instead of @c
|
It's the same as std::auto_ptr, but for @c mmap instead of @c
|
||||||
new. When the context of @c AutoMapper is left, @c munmap is
|
new. When the context of @c AutoMapper is left, @c munmap is
|
||||||
@@ -89,6 +91,7 @@ namespace mrw {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @brief Automatically call @c bfd_close for @c bfd*.
|
/** @brief Automatically call @c bfd_close for @c bfd*.
|
||||||
|
@pre #include <mrw/auto.hpp>
|
||||||
|
|
||||||
It acts like a @c std::auto_ptr, but for @c bfd*, that means it
|
It acts like a @c std::auto_ptr, but for @c bfd*, that means it
|
||||||
calls @c bfd_close whenever the context is left.
|
calls @c bfd_close whenever the context is left.
|
||||||
@@ -111,6 +114,7 @@ namespace mrw {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @brief Automatically calls @c free for @c malloc allocated memory.
|
/** @brief Automatically calls @c free for @c malloc allocated memory.
|
||||||
|
@pre #include <mrw/auto.hpp>
|
||||||
|
|
||||||
It works like a @c std::auto_ptr, but for memory that was
|
It works like a @c std::auto_ptr, but for memory that was
|
||||||
allocated with @c malloc, not @c new. Memory is freed, whenever
|
allocated with @c malloc, not @c new. Memory is freed, whenever
|
||||||
|
91
mrw/autostacktracelog4cxx.cpp
Normal file
91
mrw/autostacktracelog4cxx.cpp
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#include <mrw/stacktrace.hpp>
|
||||||
|
#include <mrw/exception.hpp>
|
||||||
|
#include <exception>
|
||||||
|
#include <log4cxx/logger.h>
|
||||||
|
|
||||||
|
namespace mrw {
|
||||||
|
|
||||||
|
/** @addtogroup StackTrace */
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/** @addtogroup AutoTrace
|
||||||
|
|
||||||
|
@section trclog4cxx Trace using the log4cxx Library
|
||||||
|
|
||||||
|
If you link to the library @c libmrwexclog4cxx using a linker
|
||||||
|
option such as: @c -lmrwexclog4cxx, then an unexpected handler
|
||||||
|
is registered, that traces a fatal error using the log4cxx
|
||||||
|
library. You don't need to change a single line in your code!
|
||||||
|
|
||||||
|
The log4cxx library is located at:
|
||||||
|
- http://logging.apache.org/log4cxx
|
||||||
|
|
||||||
|
@note The configurator is not installed automatically. If you
|
||||||
|
want to trace e.g. on the console, you have to call @c
|
||||||
|
log4cxx::BasicConfigurator::configure(); as first statement in
|
||||||
|
your @c main().
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/// The log4cxx logger where the trace is written to.
|
||||||
|
static log4cxx::LoggerPtr logger = log4cxx::Logger::getLogger(_T("libmrw"));
|
||||||
|
|
||||||
|
/** @brief unexpected handler, that traces using log4cxx
|
||||||
|
|
||||||
|
The unexpected handler is installed automatically when you link
|
||||||
|
to @c -lmrwexclog4cxx. The implementation of this unexpected
|
||||||
|
handler is as follows:
|
||||||
|
|
||||||
|
@code
|
||||||
|
void unexpected_log4cxx() {
|
||||||
|
logger->fatal("Unexpected Exception", __FILE__, __LINE__);
|
||||||
|
try {
|
||||||
|
throw;
|
||||||
|
} catch (const mrw::exception& x) {
|
||||||
|
StackTrace::createSymtable();
|
||||||
|
logger->fatal(std::string("Reason:\n")+x.what()
|
||||||
|
+"\nStack:+\n"+x.stacktrace());
|
||||||
|
} catch (const std::exception& x) {
|
||||||
|
logger->fatal(std::string("Reason:\n")+x.what()
|
||||||
|
+"\nStack: **** not available ****");
|
||||||
|
} catch (...) {
|
||||||
|
logger->fatal(std::string("Reason: **** not available ****\n")
|
||||||
|
+"\nStack: **** not available ****");
|
||||||
|
}
|
||||||
|
throw std::bad_exception();
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
|
void unexpected_log4cxx() {
|
||||||
|
logger->fatal("Unexpected Exception", __FILE__, __LINE__);
|
||||||
|
try {
|
||||||
|
throw;
|
||||||
|
} catch (const mrw::exception& x) {
|
||||||
|
StackTrace::createSymtable();
|
||||||
|
logger->fatal(std::string("Reason:\n")+x.what()
|
||||||
|
+"\nStack:+\n"+x.stacktrace());
|
||||||
|
} catch (const std::exception& x) {
|
||||||
|
logger->fatal(std::string("Reason:\n")+x.what()
|
||||||
|
+"\nStack: **** not available ****");
|
||||||
|
} catch (...) {
|
||||||
|
logger->fatal(std::string("Reason: **** not available ****\n")
|
||||||
|
+"\nStack: **** not available ****");
|
||||||
|
}
|
||||||
|
throw std::bad_exception();
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
//@}
|
||||||
|
|
||||||
|
class AutoStackTrace {
|
||||||
|
public:
|
||||||
|
AutoStackTrace() {
|
||||||
|
std::set_unexpected(&mrw::unexpected_log4cxx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// initialize stack traces (load symbols)
|
||||||
|
static AutoStackTrace _autoStackTrace;
|
||||||
|
|
||||||
|
}
|
@@ -5,8 +5,69 @@
|
|||||||
|
|
||||||
namespace mrw {
|
namespace mrw {
|
||||||
|
|
||||||
/// @todo integrate it into the distribution and document it
|
/** @addtogroup StackTrace */
|
||||||
void unexpected() {
|
//@{
|
||||||
|
|
||||||
|
/** @defgroup AutoTrace Automated Unexpected Handler with Stack Trace
|
||||||
|
|
||||||
|
@brief Don't care about the unexpected handler, let the library
|
||||||
|
do all the repetitive work for you.
|
||||||
|
|
||||||
|
For all your programs it is recommended to implement an identical
|
||||||
|
unexpected handler, that rethrows, catches the @c
|
||||||
|
mrw::exception, @c std::exception and all unknown exceptions,
|
||||||
|
traces them and finally quits with a throw of a @c
|
||||||
|
atd::bad_exception. The only thing that may be different from
|
||||||
|
project to project is, how tracing is done. The MRW C++ Class
|
||||||
|
Library provides you with additional libraries you can link
|
||||||
|
to. By linking to the library, you get an unexpected handler for
|
||||||
|
free: You don't need to add a single line of code, just link to
|
||||||
|
one more library! The libraries differ in how tracing is done.
|
||||||
|
|
||||||
|
The Implementation is done with a static instance of a class that
|
||||||
|
sets the unexpected handler in the constructor.
|
||||||
|
|
||||||
|
@section trcstderr Trace using std::cerr
|
||||||
|
|
||||||
|
If you link to the library @c libmrwexcstderr using a linker
|
||||||
|
option such as: @c -lmrwexcstderr, then an unexpected handler is
|
||||||
|
registered, that traces to the standard error stream @c
|
||||||
|
std::cerr. You don't need to change a single line in your code!
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
/** @brief unexpected handler, that traces to @c std::cerr
|
||||||
|
|
||||||
|
The unexpected handler is installed automatically when you link
|
||||||
|
to @c -lmrwexcstderr. The implementation of this unexpected
|
||||||
|
handler is as follows:
|
||||||
|
|
||||||
|
@code
|
||||||
|
void unexpected_stderr() {
|
||||||
|
std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<<std::endl;
|
||||||
|
try {
|
||||||
|
throw;
|
||||||
|
} catch (const mrw::exception& x) {
|
||||||
|
StackTrace::createSymtable();
|
||||||
|
std::cerr<<"---------- Reason:"<<std::endl
|
||||||
|
<<x.what()<<std::endl
|
||||||
|
<<"---------- Stack:"<<std::endl
|
||||||
|
<<x.stacktrace()<<std::endl;
|
||||||
|
} catch (const std::exception& x) {
|
||||||
|
std::cerr<<"---------- Reason:"<<std::endl
|
||||||
|
<<x.what()<<std::endl
|
||||||
|
<<"---------- Stack: **** not available ****"<<std::endl;
|
||||||
|
} catch (...) {
|
||||||
|
std::cerr<<"---------- Reason: **** not available ****"<<std::endl
|
||||||
|
<<"---------- Stack: **** not available ****"<<std::endl;
|
||||||
|
}
|
||||||
|
std::cerr<<"-------------------------------------------------"<<std::endl;
|
||||||
|
throw std::bad_exception();
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
*/
|
||||||
|
void unexpected_stderr() {
|
||||||
std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<<std::endl;
|
std::cerr<<"UNEXPECTED EXCEPTION: ----------------------------"<<std::endl;
|
||||||
try {
|
try {
|
||||||
throw;
|
throw;
|
||||||
@@ -28,10 +89,13 @@ namespace mrw {
|
|||||||
throw std::bad_exception();
|
throw std::bad_exception();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
//@}
|
||||||
|
|
||||||
class AutoStackTrace {
|
class AutoStackTrace {
|
||||||
public:
|
public:
|
||||||
AutoStackTrace() {
|
AutoStackTrace() {
|
||||||
std::set_unexpected(&mrw::unexpected);
|
std::set_unexpected(&mrw::unexpected_stderr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -117,7 +117,7 @@ BRIEF_MEMBER_DESC = YES
|
|||||||
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
|
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
|
||||||
# brief descriptions will be completely suppressed.
|
# brief descriptions will be completely suppressed.
|
||||||
|
|
||||||
REPEAT_BRIEF = YES
|
REPEAT_BRIEF = NO
|
||||||
|
|
||||||
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
||||||
# Doxygen will generate a detailed section even if there is only a brief
|
# Doxygen will generate a detailed section even if there is only a brief
|
||||||
@@ -143,7 +143,7 @@ FULL_PATH_NAMES = YES
|
|||||||
# only done if one of the specified strings matches the left-hand part of
|
# only done if one of the specified strings matches the left-hand part of
|
||||||
# the path. It is allowed to use relative paths in the argument list.
|
# the path. It is allowed to use relative paths in the argument list.
|
||||||
|
|
||||||
STRIP_FROM_PATH = ../
|
STRIP_FROM_PATH = ..
|
||||||
|
|
||||||
# The INTERNAL_DOCS tag determines if documentation
|
# The INTERNAL_DOCS tag determines if documentation
|
||||||
# that is typed after a \internal command is included. If the tag is set
|
# that is typed after a \internal command is included. If the tag is set
|
||||||
@@ -176,7 +176,7 @@ HIDE_SCOPE_NAMES = NO
|
|||||||
# will put a list of the files that are included by a file in the documentation
|
# will put a list of the files that are included by a file in the documentation
|
||||||
# of that file.
|
# of that file.
|
||||||
|
|
||||||
SHOW_INCLUDE_FILES = YES
|
SHOW_INCLUDE_FILES = NO
|
||||||
|
|
||||||
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
|
||||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
# will interpret the first line (until the first dot) of a JavaDoc-style
|
||||||
@@ -297,7 +297,7 @@ OPTIMIZE_OUTPUT_JAVA = NO
|
|||||||
# at the bottom of the documentation of classes and structs. If set to YES the
|
# at the bottom of the documentation of classes and structs. If set to YES the
|
||||||
# list will mention the files that were used to generate the documentation.
|
# list will mention the files that were used to generate the documentation.
|
||||||
|
|
||||||
SHOW_USED_FILES = YES
|
SHOW_USED_FILES = NO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to warning and progress messages
|
# configuration options related to warning and progress messages
|
||||||
@@ -381,13 +381,13 @@ EXCLUDE_SYMLINKS = NO
|
|||||||
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
||||||
# certain files from those directories.
|
# certain files from those directories.
|
||||||
|
|
||||||
EXCLUDE_PATTERNS =
|
EXCLUDE_PATTERNS = *_test.cpp
|
||||||
|
|
||||||
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
||||||
# directories that contain example code fragments that are included (see
|
# directories that contain example code fragments that are included (see
|
||||||
# the \include command).
|
# the \include command).
|
||||||
|
|
||||||
EXAMPLE_PATH = examples ..
|
EXAMPLE_PATH = .. examples
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||||
@@ -602,7 +602,7 @@ TREEVIEW_WIDTH = 250
|
|||||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
||||||
# generate Latex output.
|
# generate Latex output.
|
||||||
|
|
||||||
GENERATE_LATEX = NO
|
GENERATE_LATEX = YES
|
||||||
|
|
||||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
||||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||||
@@ -625,7 +625,7 @@ MAKEINDEX_CMD_NAME = makeindex
|
|||||||
# LaTeX documents. This may be useful for small projects and may help to
|
# LaTeX documents. This may be useful for small projects and may help to
|
||||||
# save some trees in general.
|
# save some trees in general.
|
||||||
|
|
||||||
COMPACT_LATEX = NO
|
COMPACT_LATEX = YES
|
||||||
|
|
||||||
# The PAPER_TYPE tag can be used to set the paper type that is used
|
# The PAPER_TYPE tag can be used to set the paper type that is used
|
||||||
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
||||||
@@ -650,26 +650,26 @@ LATEX_HEADER =
|
|||||||
# contain links (just like the HTML output) instead of page references
|
# contain links (just like the HTML output) instead of page references
|
||||||
# This makes the output suitable for online browsing using a pdf viewer.
|
# This makes the output suitable for online browsing using a pdf viewer.
|
||||||
|
|
||||||
PDF_HYPERLINKS = NO
|
PDF_HYPERLINKS = YES
|
||||||
|
|
||||||
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
|
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
|
||||||
# plain latex in the generated Makefile. Set this option to YES to get a
|
# plain latex in the generated Makefile. Set this option to YES to get a
|
||||||
# higher quality PDF documentation.
|
# higher quality PDF documentation.
|
||||||
|
|
||||||
USE_PDFLATEX = NO
|
USE_PDFLATEX = YES
|
||||||
|
|
||||||
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
|
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
|
||||||
# command to the generated LaTeX files. This will instruct LaTeX to keep
|
# command to the generated LaTeX files. This will instruct LaTeX to keep
|
||||||
# running if errors occur, instead of asking the user for help.
|
# running if errors occur, instead of asking the user for help.
|
||||||
# This option is also used when generating formulas in HTML.
|
# This option is also used when generating formulas in HTML.
|
||||||
|
|
||||||
LATEX_BATCHMODE = NO
|
LATEX_BATCHMODE = YES
|
||||||
|
|
||||||
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
|
# If LATEX_HIDE_INDICES is set to YES then doxygen will not
|
||||||
# include the index chapters (such as File Index, Compound Index, etc.)
|
# include the index chapters (such as File Index, Compound Index, etc.)
|
||||||
# in the output.
|
# in the output.
|
||||||
|
|
||||||
LATEX_HIDE_INDICES = NO
|
LATEX_HIDE_INDICES = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the RTF output
|
# configuration options related to the RTF output
|
||||||
@@ -691,7 +691,7 @@ RTF_OUTPUT = rtf
|
|||||||
# RTF documents. This may be useful for small projects and may help to
|
# RTF documents. This may be useful for small projects and may help to
|
||||||
# save some trees in general.
|
# save some trees in general.
|
||||||
|
|
||||||
COMPACT_RTF = NO
|
COMPACT_RTF = YES
|
||||||
|
|
||||||
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
|
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
|
||||||
# will contain hyperlink fields. The RTF file will
|
# will contain hyperlink fields. The RTF file will
|
||||||
@@ -700,7 +700,7 @@ COMPACT_RTF = NO
|
|||||||
# programs which support those fields.
|
# programs which support those fields.
|
||||||
# Note: wordpad (write) and others do not support links.
|
# Note: wordpad (write) and others do not support links.
|
||||||
|
|
||||||
RTF_HYPERLINKS = NO
|
RTF_HYPERLINKS = YES
|
||||||
|
|
||||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
||||||
# config file, i.e. a series of assigments. You only have to provide
|
# config file, i.e. a series of assigments. You only have to provide
|
||||||
@@ -739,7 +739,7 @@ MAN_EXTENSION = .3
|
|||||||
# only source the real man page, but without them the man command
|
# only source the real man page, but without them the man command
|
||||||
# would be unable to find the correct page. The default is NO.
|
# would be unable to find the correct page. The default is NO.
|
||||||
|
|
||||||
MAN_LINKS = NO
|
MAN_LINKS = YES
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the XML output
|
# configuration options related to the XML output
|
||||||
|
55
mrw/examples/exceptionhandling.cpp
Normal file
55
mrw/examples/exceptionhandling.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include <mrw/exception.hpp>
|
||||||
|
#include <mrw/stacktrace.hpp>
|
||||||
|
#include <exception>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void unexpectedHandler() {
|
||||||
|
try {
|
||||||
|
throw;
|
||||||
|
} catch (mrw::exception& x) {
|
||||||
|
mrw::StackTrace::createSymtable();
|
||||||
|
std::cerr<<"UNEXPECTED:"<<x.what()<<std::endl
|
||||||
|
<<"---------------------------Stack:"<<std::endl
|
||||||
|
<<x.stacktrace()
|
||||||
|
<<"---------------------------------"<<std::endl;
|
||||||
|
} catch (std::exception& x) {
|
||||||
|
std::cerr<<"UNEXPECTED:"<<x.what()<<std::endl;
|
||||||
|
} catch (...) {
|
||||||
|
std::cerr<<"UNKNOWN UNEXPECTED"<<std::endl;
|
||||||
|
}
|
||||||
|
throw std::bad_exception(); // try to recover
|
||||||
|
}
|
||||||
|
|
||||||
|
void fn2() throw(std::bad_exception) {
|
||||||
|
std::cout<<"enter fn2"<<std::endl;
|
||||||
|
throw mrw::exception(); // that's wrong, no exception excpected
|
||||||
|
std::cout<<"leave fn2"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fn1() throw(std::bad_exception) {
|
||||||
|
std::cout<<"enter fn1"<<std::endl;
|
||||||
|
fn2();
|
||||||
|
std::cout<<"leave fn1"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fn0() throw(std::bad_exception) {
|
||||||
|
std::cout<<"enter fn0"<<std::endl;
|
||||||
|
try {
|
||||||
|
fn1();
|
||||||
|
} catch (std::exception& x) {
|
||||||
|
std::cerr<<"EXCEPTION caught in fn0:"<<x.what()<<std::endl;
|
||||||
|
}
|
||||||
|
std::cout<<"leave fn0"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::set_unexpected(&unexpectedHandler);
|
||||||
|
try {
|
||||||
|
std::cout<<"call fn0"<<std::endl;
|
||||||
|
fn0();
|
||||||
|
std::cout<<"call of fn0 successful"<<std::endl;
|
||||||
|
} catch (...) {
|
||||||
|
std::cerr<<"OOOPS!!!"<<std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
@@ -53,7 +53,8 @@ namespace mrw {
|
|||||||
- if any exception is thrown, specify @c throw(mrw::exception)
|
- if any exception is thrown, specify @c throw(mrw::exception)
|
||||||
- if no exception is thrown, specify @c throw(std::bad_exception)
|
- if no exception is thrown, specify @c throw(std::bad_exception)
|
||||||
-# document the exact exception thrown with Doxygen's \@throw tag
|
-# document the exact exception thrown with Doxygen's \@throw tag
|
||||||
-# write an unexpected handler as follows:
|
-# write an unexpected handler as follows
|
||||||
|
(or link to a @ref AutoTrace "library"):
|
||||||
|
|
||||||
@code
|
@code
|
||||||
void unexpectedHandler() {
|
void unexpectedHandler() {
|
||||||
@@ -83,6 +84,9 @@ namespace mrw {
|
|||||||
|
|
||||||
For a proof of concept refer to
|
For a proof of concept refer to
|
||||||
@ref exceptionhandling.cpp "the example exceptionhandling.cpp".
|
@ref exceptionhandling.cpp "the example exceptionhandling.cpp".
|
||||||
|
|
||||||
|
The unexpected handler is implemented ready to use in @ref
|
||||||
|
AutoTrace "a separate library".
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
@@ -114,12 +118,16 @@ leave fn0
|
|||||||
call of fn0 successful
|
call of fn0 successful
|
||||||
@endverbatim
|
@endverbatim
|
||||||
|
|
||||||
Please note, that without the exception concept and without the
|
The unexpected handler is implemented ready to use in @ref
|
||||||
|
AutoTrace "a separate library".
|
||||||
|
|
||||||
|
Please note, that without the exception concept and without the
|
||||||
unexpected handler, the program would abort in function fn2 on
|
unexpected handler, the program would abort in function fn2 on
|
||||||
line 25. The output was produced by the following code:
|
line 25. The output was produced by the following code:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @brief replacement for @c std::exception, that collects a stack trace
|
/** @brief replacement for @c std::exception, that collects a stack trace
|
||||||
|
@pre #include <mrw/exception.hpp>
|
||||||
|
|
||||||
This exception class behaves exactely like @c std::exception,
|
This exception class behaves exactely like @c std::exception,
|
||||||
but it collects a stack trace in the constructor and offers a
|
but it collects a stack trace in the constructor and offers a
|
||||||
|
24
mrw/exec.cpp
24
mrw/exec.cpp
@@ -85,26 +85,26 @@ mrw::Exec& mrw::Exec::operator=(const mrw::Exec& e) throw(std::bad_exception) {
|
|||||||
|
|
||||||
mrw::Exec& mrw::Exec::execute(bool throwExc) throw(mrw::exception) {
|
mrw::Exec& mrw::Exec::execute(bool throwExc) throw(mrw::exception) {
|
||||||
/** This method calls @c fork, sets up a pipe connection to pass @c
|
/** This method calls @c fork, sets up a pipe connection to pass @c
|
||||||
stdot and @c stderr from the child process to the parent process
|
stdout and @c stderr from the child process to the parent process
|
||||||
using mrw::pipe and calls @c execvp to execute the program. */
|
using mrw::pipe and calls @c execvp to execute the program. */
|
||||||
_success = false;
|
_success = false;
|
||||||
_res = _err = "";
|
_res = _err = "";
|
||||||
mrw::pipe stdout, stderr;
|
mrw::pipe stdOut, stdErr;
|
||||||
if (!stdout || !stderr)
|
if (!stdOut || !stdErr)
|
||||||
throw mrw::ExecutionFailedExc("cannot create pipe", *_cmd);
|
throw mrw::ExecutionFailedExc("cannot create pipe", *_cmd);
|
||||||
pid_t pid(fork());
|
pid_t pid(fork());
|
||||||
if (pid<0)
|
if (pid<0)
|
||||||
throw ExecutionFailedExc("cannot fork", *_cmd);
|
throw ExecutionFailedExc("cannot fork", *_cmd);
|
||||||
if (pid) { // parent
|
if (pid) { // parent
|
||||||
stdout.close_out();
|
stdOut.close_out();
|
||||||
stderr.close_out();
|
stdErr.close_out();
|
||||||
if (!stdout || !stderr)
|
if (!stdOut || !stdErr)
|
||||||
throw ExecutionFailedExc("cannot close pipe", *_cmd);
|
throw ExecutionFailedExc("cannot close pipe", *_cmd);
|
||||||
int num1(0), num2(0);
|
int num1(0), num2(0);
|
||||||
for (char buf1[4096], buf2[4096];
|
for (char buf1[4096], buf2[4096];
|
||||||
(num1=read(stdout.istream(), buf1, sizeof(buf1)))>0 ||
|
(num1=read(stdOut.istream(), buf1, sizeof(buf1)))>0 ||
|
||||||
num1==-1 && errno==EINTR ||
|
num1==-1 && errno==EINTR ||
|
||||||
(num2=read(stderr.istream(), buf2, sizeof(buf2)))>0 ||
|
(num2=read(stdErr.istream(), buf2, sizeof(buf2)))>0 ||
|
||||||
num2==-1 && errno==EINTR;
|
num2==-1 && errno==EINTR;
|
||||||
_res += std::string(buf1, num1), _err += std::string(buf2, num2));
|
_res += std::string(buf1, num1), _err += std::string(buf2, num2));
|
||||||
if (num1==-1 || num2==-1)
|
if (num1==-1 || num2==-1)
|
||||||
@@ -120,10 +120,10 @@ mrw::Exec& mrw::Exec::execute(bool throwExc) throw(mrw::exception) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // child
|
} else { // child
|
||||||
stdout.close_in();
|
stdOut.close_in();
|
||||||
stderr.close_in();
|
stdErr.close_in();
|
||||||
stdout.connect_cout();
|
stdOut.connect_cout();
|
||||||
stderr.connect_cerr();
|
stdErr.connect_cerr();
|
||||||
execvp(_cmd->path(), _cmd->args());
|
execvp(_cmd->path(), _cmd->args());
|
||||||
exit(1); // execute failed
|
exit(1); // execute failed
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,7 @@ namespace mrw {
|
|||||||
class Cmd;
|
class Cmd;
|
||||||
|
|
||||||
/** @brief Exception: Execution of command failed.
|
/** @brief Exception: Execution of command failed.
|
||||||
|
@pre #include <mrw/exec.hpp>
|
||||||
|
|
||||||
This exception is thrown, if the exection of a command in
|
This exception is thrown, if the exection of a command in
|
||||||
mrw::Exec is failed. That means, it was not possible to fork or
|
mrw::Exec is failed. That means, it was not possible to fork or
|
||||||
@@ -64,10 +65,11 @@ namespace mrw {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @brief Execute a command in a new process.
|
/** @brief Execute a command in a new process.
|
||||||
|
@pre #include <mrw/exec.hpp>
|
||||||
|
|
||||||
This class handles the execution of a command in a new process
|
This class handles the execution of a command in a new process
|
||||||
and returns the two streams @c cout and @cerr, also known as @c
|
and returns the two streams @c cout and @c cerr, also known as @c
|
||||||
stderr and @stdout.
|
stderr and @c stdout.
|
||||||
|
|
||||||
There are different ways of usage for this class. A simple way,
|
There are different ways of usage for this class. A simple way,
|
||||||
one line of code, to get only the resulting stream (no error)
|
one line of code, to get only the resulting stream (no error)
|
||||||
@@ -188,6 +190,7 @@ namespace mrw {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @brief A system command to be executed
|
/** @brief A system command to be executed
|
||||||
|
@pre #include <mrw/exec.hpp>
|
||||||
|
|
||||||
This class is used in conjunction with mrw::Exec. It mus be
|
This class is used in conjunction with mrw::Exec. It mus be
|
||||||
initialized with the command name, then the command parameters
|
initialized with the command name, then the command parameters
|
||||||
|
@@ -1,26 +1,31 @@
|
|||||||
CLEANFILES = doxygen.error
|
|
||||||
AM_CPPFLAGS = -I..
|
AM_CPPFLAGS = -I..
|
||||||
|
|
||||||
|
CLEANFILES = doxygen.error
|
||||||
examplesdir = ${pkgdatadir}/examples
|
examplesdir = ${pkgdatadir}/examples
|
||||||
examples_DATA = examples/*
|
examples_DATA = examples/*
|
||||||
htmldir = ${pkgdatadir}/doc/html
|
htmldir = ${pkgdatadir}/doc/html
|
||||||
html_DATA = doc/html/*
|
html_DATA = doc/html/*
|
||||||
EXTRA_DIST = test.dat ${examples_DATA} ${html_DATA}
|
pdfdir = ${pkgdatadir}/doc/pdf
|
||||||
|
pdf_DATA = doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf
|
||||||
|
EXTRA_DIST = test.dat ${examples_DATA} ${html_DATA} ${pdf_DATA}
|
||||||
|
|
||||||
lib_LTLIBRARIES = libmrw.la libmrwexcstderr.la
|
lib_LTLIBRARIES = libmrw.la libmrwexcstderr.la libmrwexclog4cxx.la
|
||||||
|
|
||||||
libmrw_la_SOURCES = mrw.hpp \
|
libmrw_la_SOURCES = mrw.hpp \
|
||||||
auto.hpp auto.cpp unistd.hpp \
|
auto.hpp auto.cpp unistd.hpp \
|
||||||
stacktrace.hpp stacktrace.cpp exception.hpp exception.cpp \
|
stacktrace.hpp stacktrace.cpp exception.hpp exception.cpp \
|
||||||
exec.hpp exec.cpp
|
exec.hpp exec.cpp
|
||||||
libmrw_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
|
libmrw_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
|
||||||
libmrw_la_LIBADD = -liberty -lbfd
|
|
||||||
|
|
||||||
libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp
|
libmrwexcstderr_la_SOURCES = autostacktracestderr.cpp
|
||||||
libmrwexcstderr_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
|
libmrwexcstderr_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
|
||||||
libmrwexcstderr_la_LIBADD = -lmrw
|
libmrwexcstderr_la_LIBADD = -lmrw
|
||||||
|
|
||||||
check_PROGRAMS = auto_test exec_test stacktrace_test
|
libmrwexclog4cxx_la_SOURCES = autostacktracelog4cxx.cpp
|
||||||
|
libmrwexclog4cxx_la_LDFLAGS = -version-info @MAJOR@:@MINOR@
|
||||||
|
libmrwexclog4cxx_la_LIBADD = -lmrw
|
||||||
|
|
||||||
|
check_PROGRAMS = auto_test exec_test stacktrace_test mrwexcstderr_test mrwexclog4cxx_test
|
||||||
auto_test_SOURCES = auto_test.cpp
|
auto_test_SOURCES = auto_test.cpp
|
||||||
auto_test_CPPFLAGS = -I.. -g3
|
auto_test_CPPFLAGS = -I.. -g3
|
||||||
auto_test_LDADD = -lmrw -lcppunit
|
auto_test_LDADD = -lmrw -lcppunit
|
||||||
@@ -30,8 +35,18 @@ exec_test_LDADD = -lmrw -lcppunit
|
|||||||
stacktrace_test_SOURCES = stacktrace_test.cpp
|
stacktrace_test_SOURCES = stacktrace_test.cpp
|
||||||
stacktrace_test_CPPFLAGS = -I.. -g3
|
stacktrace_test_CPPFLAGS = -I.. -g3
|
||||||
stacktrace_test_LDADD = -lmrw -lcppunit
|
stacktrace_test_LDADD = -lmrw -lcppunit
|
||||||
|
mrwexcstderr_test_SOURCES = mrwexcstderr_test.cpp
|
||||||
|
mrwexcstderr_test_CPPFLAGS = -I.. -g3
|
||||||
|
mrwexcstderr_test_LDADD = -lmrwexcstderr -lcppunit
|
||||||
|
mrwexclog4cxx_test_SOURCES = mrwexclog4cxx_test.cpp
|
||||||
|
mrwexclog4cxx_test_CPPFLAGS = -I.. -g3
|
||||||
|
mrwexclog4cxx_test_LDADD = -lmrwexclog4cxx -lcppunit -llog4cxx
|
||||||
TESTS = ${check_PROGRAMS}
|
TESTS = ${check_PROGRAMS}
|
||||||
|
|
||||||
doc: doc/html/index.html
|
deps = ../COPYING ../README ../INSTALL ../NEWS ../ChangeLog
|
||||||
doc/html/index.html: doxyfile *.[ch]pp
|
doc: doc/html/index.html doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf
|
||||||
|
doc/html/index.html: doxyfile *.[ch]pp ${deps}
|
||||||
doxygen doxyfile
|
doxygen doxyfile
|
||||||
|
doc/latex/@PACKAGENAME@-@MAJOR@.@MINOR@.pdf: doxyfile *.[ch]pp ${deps}
|
||||||
|
cd doc/latex && make && \
|
||||||
|
mv refman.pdf @PACKAGENAME@-@MAJOR@.@MINOR@.pdf
|
||||||
|
@@ -1,50 +1,52 @@
|
|||||||
/** @mainpage
|
/** @mainpage
|
||||||
|
|
||||||
@section license License and Copyright
|
|
||||||
|
|
||||||
- All files are under GNU LGPL license.
|
|
||||||
- All files are copyrighted by Marc Wäckerlin.
|
|
||||||
- There is no warranty.
|
|
||||||
- For details, read the file LICENSE in your distribution.
|
|
||||||
|
|
||||||
@section intro Introduction
|
@section intro Introduction
|
||||||
|
|
||||||
This library cares a about:
|
@verbinclude README
|
||||||
- resource management
|
|
||||||
- execution of UNIX sub processes
|
For details, see the <a href="modules.html">"Modules"</a> page.
|
||||||
- stack trace
|
|
||||||
- exception handling
|
|
||||||
|
|
||||||
For details, see the modules page.
|
@section download Download
|
||||||
|
|
||||||
@section link Compile and Link Options
|
|
||||||
|
|
||||||
To be able to get the source file name / line number
|
|
||||||
information in stack trace, you need the debug information compile
|
|
||||||
option @c -g. For compilation on Solaris, you may need the option
|
|
||||||
@c -D__solaris__. You must link to the MRW C++ Library. For this
|
|
||||||
you need the link option @c -lmrw.
|
|
||||||
|
|
||||||
@section download Download and Installation
|
|
||||||
|
|
||||||
Download this version from here:
|
Download this version from here:
|
||||||
- http://marc.waeckerlin.org/mrw-c++/mrw-c++-@MAJOR@.@MINOR@.tar.gz
|
- Source TAR-Ball (<code>./configure && make all install</code>):
|
||||||
|
- http://marc.waeckerlin.org/mrw-c++/mrw-c++-@MAJOR@.@MINOR@.tar.gz
|
||||||
Not yet available:
|
- RPM Packages (built on i586/SuSE):
|
||||||
- http://marc.waeckerlin.org/mrw-c++/mrw-c++-@MAJOR@.@MINOR@.rpm
|
- http://marc.waeckerlin.org/mrw-c++/mrw-c++-@MAJOR@.@MINOR@-1.i586.rpm
|
||||||
- http://marc.waeckerlin.org/mrw-c++/mrw-c++-devel-@MAJOR@.@MINOR@.rpm
|
- http://marc.waeckerlin.org/mrw-c++/mrw-c++-devel-@MAJOR@.@MINOR@-1.i586.rpm
|
||||||
|
|
||||||
|
Download this documentation in PDF:
|
||||||
|
- http://marc.waeckerlin.org/mrw-c++/mrw-c++-@MAJOR@.@MINOR@.pdf
|
||||||
|
|
||||||
The homepage is on:
|
The homepage is on:
|
||||||
- http://marc.waeckerlin.org/mrw-c++/index.html
|
- http://marc.waeckerlin.org/mrw-c++/index.html
|
||||||
|
|
||||||
Install it with:
|
@section usage Usage of the Library
|
||||||
|
|
||||||
|
Include the headers you need with prefix @c mrw, e.g.:
|
||||||
|
|
||||||
@verbatim
|
@verbatim
|
||||||
tar xzvf mrw-c++-@MAJOR@.@MINOR@.tar.gz
|
#include <mrw/stacktrace.hpp>
|
||||||
cd mrw-c++-@MAJOR@.@MINOR@
|
|
||||||
./configure
|
|
||||||
make all check install
|
|
||||||
@endverbatim
|
@endverbatim
|
||||||
|
|
||||||
|
Compile with debug information enabled, thats option @c -g and
|
||||||
|
link to the library with option @c -lmrw, e.g.;
|
||||||
|
|
||||||
|
@verbatim
|
||||||
|
g++ -g -o myprogram myprogram.cpp -lmrw
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
For the @ref AutoTools "unexpected handler" you need to link with
|
||||||
|
@c -lmrwexcstderr or @c -lmrwexclog4cxx.
|
||||||
|
|
||||||
|
@section moreinfo Additional Information
|
||||||
|
|
||||||
|
See the <a href="pages.html">"Related Pages"</a>.
|
||||||
|
|
||||||
|
- @ref license "License Information (LGPL)"
|
||||||
|
- @ref install "Compilation and Installation Information"
|
||||||
|
- @ref news "Breaking News"
|
||||||
|
- @ref changes "Change Log"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @page license License
|
/** @page license License
|
||||||
@@ -53,6 +55,9 @@
|
|||||||
/** @page readme Readme
|
/** @page readme Readme
|
||||||
@verbinclude README */
|
@verbinclude README */
|
||||||
|
|
||||||
|
/** @page install Installation
|
||||||
|
@verbinclude INSTALL */
|
||||||
|
|
||||||
/** @page news News
|
/** @page news News
|
||||||
@verbinclude NEWS */
|
@verbinclude NEWS */
|
||||||
|
|
||||||
|
68
mrw/mrwexclog4cxx_test.cpp
Normal file
68
mrw/mrwexclog4cxx_test.cpp
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include <mrw/exception.hpp>
|
||||||
|
#include <log4cxx/basicconfigurator.h>
|
||||||
|
#include <cppunit/TestFixture.h>
|
||||||
|
#include <cppunit/ui/text/TestRunner.h>
|
||||||
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
#include <cppunit/extensions/TestFactoryRegistry.h>
|
||||||
|
|
||||||
|
namespace mrw {
|
||||||
|
class AutoExcLog4CxxTest: public CppUnit::TestFixture {
|
||||||
|
private:
|
||||||
|
bool enter_unexpectedThrow;
|
||||||
|
bool exit_unexpectedThrow;
|
||||||
|
bool enter_passUnexpected;
|
||||||
|
bool exit_passUnexpected;
|
||||||
|
bool enter_catchUnexpected;
|
||||||
|
bool exit_catchUnexpected;
|
||||||
|
public:
|
||||||
|
void setUp() {
|
||||||
|
enter_unexpectedThrow = false;
|
||||||
|
exit_unexpectedThrow = false;
|
||||||
|
enter_passUnexpected = false;
|
||||||
|
exit_passUnexpected = false;
|
||||||
|
enter_catchUnexpected = false;
|
||||||
|
exit_catchUnexpected = false;
|
||||||
|
}
|
||||||
|
void unexpectedThrow() throw(std::bad_exception) {
|
||||||
|
enter_unexpectedThrow = true;
|
||||||
|
throw mrw::exception();
|
||||||
|
exit_unexpectedThrow = true;
|
||||||
|
}
|
||||||
|
void passUnexpected() throw(std::bad_exception) {
|
||||||
|
enter_passUnexpected = true;
|
||||||
|
unexpectedThrow();
|
||||||
|
exit_passUnexpected = true;
|
||||||
|
}
|
||||||
|
void catchUnexpected() throw() {
|
||||||
|
enter_catchUnexpected = true;
|
||||||
|
bool caught(false);
|
||||||
|
try {
|
||||||
|
passUnexpected();
|
||||||
|
} catch (std::bad_exception&) {
|
||||||
|
caught = true;
|
||||||
|
}
|
||||||
|
CPPUNIT_ASSERT(caught);
|
||||||
|
exit_catchUnexpected = true;
|
||||||
|
}
|
||||||
|
void testcase() {
|
||||||
|
catchUnexpected();
|
||||||
|
CPPUNIT_ASSERT(enter_catchUnexpected &&
|
||||||
|
enter_passUnexpected &&
|
||||||
|
enter_unexpectedThrow &&
|
||||||
|
exit_catchUnexpected &&
|
||||||
|
!exit_passUnexpected &&
|
||||||
|
!exit_unexpectedThrow);
|
||||||
|
}
|
||||||
|
CPPUNIT_TEST_SUITE(AutoExcLog4CxxTest);
|
||||||
|
CPPUNIT_TEST(testcase);
|
||||||
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
};
|
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(AutoExcLog4CxxTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
log4cxx::BasicConfigurator::configure();
|
||||||
|
CppUnit::TextUi::TestRunner runner;
|
||||||
|
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
|
||||||
|
return runner.run() ? 0 : 1;
|
||||||
|
}
|
66
mrw/mrwexcstderr_test.cpp
Normal file
66
mrw/mrwexcstderr_test.cpp
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#include <mrw/exception.hpp>
|
||||||
|
#include <cppunit/TestFixture.h>
|
||||||
|
#include <cppunit/ui/text/TestRunner.h>
|
||||||
|
#include <cppunit/extensions/HelperMacros.h>
|
||||||
|
#include <cppunit/extensions/TestFactoryRegistry.h>
|
||||||
|
|
||||||
|
namespace mrw {
|
||||||
|
class AutoExcStderrTest: public CppUnit::TestFixture {
|
||||||
|
private:
|
||||||
|
bool enter_unexpectedThrow;
|
||||||
|
bool exit_unexpectedThrow;
|
||||||
|
bool enter_passUnexpected;
|
||||||
|
bool exit_passUnexpected;
|
||||||
|
bool enter_catchUnexpected;
|
||||||
|
bool exit_catchUnexpected;
|
||||||
|
public:
|
||||||
|
void setUp() {
|
||||||
|
enter_unexpectedThrow = false;
|
||||||
|
exit_unexpectedThrow = false;
|
||||||
|
enter_passUnexpected = false;
|
||||||
|
exit_passUnexpected = false;
|
||||||
|
enter_catchUnexpected = false;
|
||||||
|
exit_catchUnexpected = false;
|
||||||
|
}
|
||||||
|
void unexpectedThrow() throw(std::bad_exception) {
|
||||||
|
enter_unexpectedThrow = true;
|
||||||
|
throw mrw::exception();
|
||||||
|
exit_unexpectedThrow = true;
|
||||||
|
}
|
||||||
|
void passUnexpected() throw(std::bad_exception) {
|
||||||
|
enter_passUnexpected = true;
|
||||||
|
unexpectedThrow();
|
||||||
|
exit_passUnexpected = true;
|
||||||
|
}
|
||||||
|
void catchUnexpected() throw() {
|
||||||
|
enter_catchUnexpected = true;
|
||||||
|
bool caught(false);
|
||||||
|
try {
|
||||||
|
passUnexpected();
|
||||||
|
} catch (std::bad_exception&) {
|
||||||
|
caught = true;
|
||||||
|
}
|
||||||
|
CPPUNIT_ASSERT(caught);
|
||||||
|
exit_catchUnexpected = true;
|
||||||
|
}
|
||||||
|
void testcase() {
|
||||||
|
catchUnexpected();
|
||||||
|
CPPUNIT_ASSERT(enter_catchUnexpected &&
|
||||||
|
enter_passUnexpected &&
|
||||||
|
enter_unexpectedThrow &&
|
||||||
|
exit_catchUnexpected &&
|
||||||
|
!exit_passUnexpected &&
|
||||||
|
!exit_unexpectedThrow);
|
||||||
|
}
|
||||||
|
CPPUNIT_TEST_SUITE(AutoExcStderrTest);
|
||||||
|
CPPUNIT_TEST(testcase);
|
||||||
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
};
|
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(AutoExcStderrTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
CppUnit::TextUi::TestRunner runner;
|
||||||
|
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
|
||||||
|
return runner.run() ? 0 : 1;
|
||||||
|
}
|
@@ -53,10 +53,48 @@ namespace mrw {
|
|||||||
- 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
|
- it must be linked with @c -libery and @c -lbfd
|
||||||
|
|
||||||
|
@subsection sttech Technology
|
||||||
|
|
||||||
|
On GNU glibc based systems (Linux), the stack trace is collected
|
||||||
|
with GNU glibc's function @c backtrace(). On other systems
|
||||||
|
(Solaris) it is collected using the GNU gcc's internal function @c
|
||||||
|
__builtin_return_address(). With both functions, at most 50 steps
|
||||||
|
back are collected.
|
||||||
|
|
||||||
|
The evaluation is not done with the glibc library function @c
|
||||||
|
backtrace_symbols(), because this function is unable to print
|
||||||
|
the source file name and line number information. Instead of
|
||||||
|
this, the executable binary is loaded into the memory and
|
||||||
|
evaluated using the bdf library functions. For this the stack
|
||||||
|
tracer needs to know how to find out which executable is
|
||||||
|
running. It is possible to get this information automatically on
|
||||||
|
Linux and Solaris. On other systems, I don't have this
|
||||||
|
information, but you can either tell me, and I integrate support
|
||||||
|
for your system (when I have time to do it), or provide the
|
||||||
|
executable file name as an argument to @c
|
||||||
|
mrw::StackTrace::createSymtable().
|
||||||
|
|
||||||
|
@subsection stdrawbacks Draw Backs
|
||||||
|
|
||||||
|
Unfortunately it is not possible to extract the source file name
|
||||||
|
and line number information if the executable was not compiled
|
||||||
|
with debug option @c -g. But what's worse, it is not possible to
|
||||||
|
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.
|
||||||
|
|
||||||
|
@todo Add support to read debugging information from libraries
|
||||||
|
that are linked to the executable.
|
||||||
|
|
||||||
|
@todo Add support for alternative symbol evaluation using @c
|
||||||
|
backtrace_symbols.
|
||||||
*/
|
*/
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/** @brief store and print a stack trace of the actual position in code
|
/** @brief store and print a stack trace of the actual position in code
|
||||||
|
@pre #include <mrw/stacktrace.hpp>
|
||||||
|
|
||||||
In the constructor, a stack trace is stored, but not yet
|
In the constructor, a stack trace is stored, but not yet
|
||||||
evaluated. Therefore storing a stack trace is relatively
|
evaluated. Therefore storing a stack trace is relatively
|
||||||
|
@@ -8,8 +8,10 @@ namespace mrw {
|
|||||||
/** @addtogroup AutoTools */
|
/** @addtogroup AutoTools */
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
/// class that implements an unnamed UNIX pipe
|
/** @brief class that implements an unnamed UNIX pipe
|
||||||
/** Implements a UNIX pipe that is automatically closed in
|
@pre #include <mrw/unistd.hpp>
|
||||||
|
|
||||||
|
Implements a UNIX pipe that is automatically closed in
|
||||||
destructor and offers some facilities. */
|
destructor and offers some facilities. */
|
||||||
class pipe {
|
class pipe {
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user