summaryrefslogtreecommitdiffstats
path: root/tester/covoar/covoar.cc
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2018-05-11 14:24:11 +1200
committerChris Johns <chrisj@rtems.org>2018-06-18 12:26:16 +1000
commit881824f766937a47fb494f97f4ebcd44c99135cc (patch)
tree0af3d9422ba8e0eae6df8458cc08d4aafacff301 /tester/covoar/covoar.cc
parentlinkers/exe-info: Add DWARF support to gather and check producer details. (diff)
downloadrtems-tools-881824f766937a47fb494f97f4ebcd44c99135cc.tar.bz2
tester/covoar: Remove all exit() calls and throw an rld::error exception.
Add a suitable catch to covoar's main.
Diffstat (limited to 'tester/covoar/covoar.cc')
-rw-r--r--tester/covoar/covoar.cc232
1 files changed, 136 insertions, 96 deletions
diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc
index eadf0ec..26abf34 100644
--- a/tester/covoar/covoar.cc
+++ b/tester/covoar/covoar.cc
@@ -1,3 +1,7 @@
+#include <iostream>
+#include <iomanip>
+
+#include <cxxabi.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -12,6 +16,9 @@
#include <list>
+#include <rld.h>
+#include <rld-process.h>
+
#include "app_common.h"
#include "CoverageFactory.h"
#include "CoverageMap.h"
@@ -23,14 +30,13 @@
#include "TargetFactory.h"
#include "GcovData.h"
-#include "rld-process.h"
-
#ifdef _WIN32
#define kill(p,s) raise(s)
#endif
typedef std::list<std::string> CoverageNames;
typedef std::list<Coverage::ExecutableInfo*> Executables;
+typedef std::string option_error;
/*
* Create a build path from the executable paths. Also extract the build prefix
@@ -105,8 +111,7 @@ static void createBuildPath(Executables& executablesToAnalyze,
}
}
if (!fail.empty()) {
- std::cerr << "ERROR: " << fail << std::endl;
- exit(EXIT_FAILURE);
+ throw rld::error( fail, "createBuildPath" );
}
}
}
@@ -138,44 +143,7 @@ void usage(const std::string& progname)
<< std::endl;
}
-#define PrintableString(_s) \
-((!(_s)) ? "NOT SET" : (_s))
-
-static void
-fatal_signal( int signum )
-{
- signal( signum, SIG_DFL );
-
- rld::process::temporaries_clean_up();
-
- /*
- * Get the same signal again, this time not handled, so its normal effect
- * occurs.
- */
- kill( getpid(), signum );
-}
-
-static void
-setup_signals( void )
-{
- if ( signal( SIGINT, SIG_IGN ) != SIG_IGN )
- signal( SIGINT, fatal_signal );
-#ifdef SIGHUP
- if ( signal( SIGHUP, SIG_IGN ) != SIG_IGN )
- signal( SIGHUP, fatal_signal );
-#endif
- if ( signal( SIGTERM, SIG_IGN ) != SIG_IGN )
- signal( SIGTERM, fatal_signal );
-#ifdef SIGPIPE
- if ( signal( SIGPIPE, SIG_IGN ) != SIG_IGN )
- signal( SIGPIPE, fatal_signal );
-#endif
-#ifdef SIGCHLD
- signal( SIGCHLD, SIG_DFL );
-#endif
-}
-
-int main(
+int covoar(
int argc,
char** argv
)
@@ -204,16 +172,12 @@ int main(
rld::process::tempfile syms( ".syms" );
bool debug = false;
std::string symbolSet;
- std::string progname;
std::string option;
int opt;
- setup_signals();
-
//
// Process command line options.
//
- progname = rld::path::basename(argv[0]);
while ((opt = getopt(argc, argv, "1:L:e:c:g:E:f:s:S:T:O:p:vd")) != -1) {
switch (opt) {
@@ -232,46 +196,31 @@ int main(
case 'p': projectName = optarg; break;
case 'd': debug = true; break;
default: /* '?' */
- usage(progname);
- exit(EXIT_FAILURE);
+ throw option_error( "unknown option" );
}
}
- try
- {
- /*
- * Validate inputs.
- */
- /*
- * Validate that we have a symbols of interest file.
- */
- if ( symbolSet.empty() ) {
- option = "symbol set file -S";
- throw option;
- }
+ /*
+ * Validate inputs.
+ */
- /*
- * Has path to explanations.txt been specified.
- */
- if ( !explanations ) {
- option = "explanations -E";
- throw option;
- }
+ /*
+ * Validate that we have a symbols of interest file.
+ */
+ if ( symbolSet.empty() )
+ throw option_error( "symbol set file -S" );
- /*
- * Check for project name.
- */
- if ( !projectName ) {
- option = "project name -p";
- throw option;
- }
- }
- catch( std::string option )
- {
- std::cerr << "error missing option: " + option << std::endl;
- usage(progname);
- exit(EXIT_FAILURE);
- }
+ /*
+ * Has path to explanations.txt been specified.
+ */
+ if ( !explanations )
+ throw option_error( "explanations -E" );
+
+ /*
+ * Check for project name.
+ */
+ if ( !projectName )
+ throw option_error( "project name -p" );
// If a single executable was specified, process the remaining
// arguments as coverage file names.
@@ -332,18 +281,14 @@ int main(
}
// Ensure that there is at least one executable to process.
- if (executablesToAnalyze.empty()) {
- std::cerr << "error: No information to analyze" << std::endl;
- exit(EXIT_FAILURE);
- }
+ if (executablesToAnalyze.empty())
+ throw rld::error( "No information to analyze", "covoar" );
// The executablesToAnalyze and coverageFileNames containers need
// to be the name size of some of the code below breaks. Lets
// check and make sure.
- if (executablesToAnalyze.size() != coverageFileNames.size()) {
- std::cerr << "ERROR: executables and coverage name size mismatch" << std::endl;
- exit(EXIT_FAILURE);
- }
+ if (executablesToAnalyze.size() != coverageFileNames.size())
+ throw rld::error( "executables and coverage name size mismatch", "covoar" );
//
// Find the top of the BSP's build tree and if we have found the top
@@ -398,9 +343,7 @@ int main(
//
// Read symbol configuration file and load needed symbols.
//
- if (!SymbolsToAnalyze->load( symbolSet, buildTarget, buildBSP, Verbose )) {
- exit(EXIT_FAILURE);
- }
+ SymbolsToAnalyze->load( symbolSet, buildTarget, buildBSP, Verbose );
if ( Verbose )
std::cerr << "Analyzing " << SymbolsToAnalyze->set.size()
@@ -413,10 +356,8 @@ int main(
// Create coverage map reader.
coverageReader = Coverage::CreateCoverageReader(coverageFormat);
- if (!coverageReader) {
- std::cerr << "error: Unable to create coverage file reader" << std::endl;
- exit(EXIT_FAILURE);
- }
+ if (!coverageReader)
+ throw rld::error( "Unable to create coverage file reader", "covoar" );
// Create the objdump processor.
objdumpProcessor = new Coverage::ObjdumpProcessor();
@@ -555,3 +496,102 @@ int main(
return 0;
}
+
+#define PrintableString(_s) \
+((!(_s)) ? "NOT SET" : (_s))
+
+static void
+fatal_signal( int signum )
+{
+ signal( signum, SIG_DFL );
+
+ rld::process::temporaries_clean_up();
+
+ /*
+ * Get the same signal again, this time not handled, so its normal effect
+ * occurs.
+ */
+ kill( getpid(), signum );
+}
+
+static void
+setup_signals( void )
+{
+ if ( signal( SIGINT, SIG_IGN ) != SIG_IGN )
+ signal( SIGINT, fatal_signal );
+#ifdef SIGHUP
+ if ( signal( SIGHUP, SIG_IGN ) != SIG_IGN )
+ signal( SIGHUP, fatal_signal );
+#endif
+ if ( signal( SIGTERM, SIG_IGN ) != SIG_IGN )
+ signal( SIGTERM, fatal_signal );
+#ifdef SIGPIPE
+ if ( signal( SIGPIPE, SIG_IGN ) != SIG_IGN )
+ signal( SIGPIPE, fatal_signal );
+#endif
+#ifdef SIGCHLD
+ signal( SIGCHLD, SIG_DFL );
+#endif
+}
+
+void
+unhandled_exception (void)
+{
+ std::cerr << "error: exception handling error, please report" << std::endl;
+ exit (1);
+}
+
+int main(
+ int argc,
+ char** argv
+)
+{
+ std::string progname( argv[0] );
+ int ec = 0;
+
+ setup_signals();
+
+ std::set_terminate(unhandled_exception);
+
+ try
+ {
+ progname = rld::path::basename(argv[0]);
+ covoar( argc, argv );
+ }
+ catch ( option_error oe )
+ {
+ std::cerr << "error: missing option: " + oe << std::endl;
+ usage(progname);
+ ec = EXIT_FAILURE;
+ }
+ catch (rld::error re)
+ {
+ std::cerr << "error: "
+ << re.where << ": " << re.what
+ << std::endl;
+ ec = 10;
+ }
+ catch (std::exception e)
+ {
+ int status;
+ char* realname;
+ realname = abi::__cxa_demangle (e.what(), 0, 0, &status);
+ std::cerr << "error: exception: " << realname << " [";
+ ::free (realname);
+ const std::type_info &ti = typeid (e);
+ realname = abi::__cxa_demangle (ti.name(), 0, 0, &status);
+ std::cerr << realname << "] " << e.what () << std::endl << std::flush;
+ ::free (realname);
+ ec = 11;
+ }
+ catch (...)
+ {
+ /*
+ * Helps to know if this happens.
+ */
+ std::cerr << "error: unhandled exception" << std::endl;
+ ec = 12;
+ }
+
+ return ec;
+}