T32: Parsing cli options for T32 fail-client
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@2108 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
21
debuggers/t32/include/T32Connector.hpp
Normal file
21
debuggers/t32/include/T32Connector.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef __T32CONNECTOR_HPP__
|
||||||
|
#define __T32CONNECTOR_HPP__
|
||||||
|
|
||||||
|
namespace fail {
|
||||||
|
|
||||||
|
class T32Connector {
|
||||||
|
char* m_hostname;
|
||||||
|
unsigned m_port;
|
||||||
|
unsigned m_packetlength;
|
||||||
|
|
||||||
|
public:
|
||||||
|
T32Connector() { };
|
||||||
|
T32Connector(char* hostname, unsigned port, unsigned packlen);
|
||||||
|
~T32Connector();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end-of-namespace fail
|
||||||
|
#endif // __T32CONNECTOR_HPP__
|
||||||
|
|
||||||
2815
debuggers/t32/include/optionparser.h
Normal file
2815
debuggers/t32/include/optionparser.h
Normal file
File diff suppressed because it is too large
Load Diff
53
debuggers/t32/include/optionparser_ext.hpp
Normal file
53
debuggers/t32/include/optionparser_ext.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef __OPTIONSPARSER_EXT_HPP__
|
||||||
|
#define __OPTIONSPARSER_EXT_HPP__
|
||||||
|
|
||||||
|
|
||||||
|
struct Arg: public option::Arg
|
||||||
|
{
|
||||||
|
static void printError(const char* msg1, const option::Option& opt, const char* msg2)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", msg1);
|
||||||
|
fwrite(opt.name, opt.namelen, 1, stderr);
|
||||||
|
fprintf(stderr, "%s", msg2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static option::ArgStatus Unknown(const option::Option& option, bool msg)
|
||||||
|
{
|
||||||
|
if (msg) printError("Unknown option '", option, "'\n");
|
||||||
|
return option::ARG_ILLEGAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static option::ArgStatus Required(const option::Option& option, bool msg)
|
||||||
|
{
|
||||||
|
if (option.arg != 0)
|
||||||
|
return option::ARG_OK;
|
||||||
|
|
||||||
|
if (msg) printError("Option '", option, "' requires an argument\n");
|
||||||
|
return option::ARG_ILLEGAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static option::ArgStatus NonEmpty(const option::Option& option, bool msg)
|
||||||
|
{
|
||||||
|
if (option.arg != 0 && option.arg[0] != 0)
|
||||||
|
return option::ARG_OK;
|
||||||
|
|
||||||
|
if (msg) printError("Option '", option, "' requires a non-empty argument\n");
|
||||||
|
return option::ARG_ILLEGAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static option::ArgStatus Numeric(const option::Option& option, bool msg)
|
||||||
|
{
|
||||||
|
char* endptr = 0;
|
||||||
|
if (option.arg != 0 && strtol(option.arg, &endptr, 10)){};
|
||||||
|
if (endptr != option.arg && *endptr == 0)
|
||||||
|
return option::ARG_OK;
|
||||||
|
|
||||||
|
if (msg) printError("Option '", option, "' requires a numeric argument\n");
|
||||||
|
return option::ARG_ILLEGAL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __OPTIONSPARSER_EXT_HPP__
|
||||||
@ -1,5 +1,6 @@
|
|||||||
set(SRCS
|
set(SRCS
|
||||||
T32Connector.cc
|
main.cc
|
||||||
|
T32Connector.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(fail-client ${SRCS})
|
add_executable(fail-client ${SRCS})
|
||||||
|
|||||||
@ -1,82 +1,17 @@
|
|||||||
/**
|
#include "T32Connector.hpp"
|
||||||
* FailT32 -- Fault Injection on the Lauterbach Trace32 System
|
|
||||||
*
|
|
||||||
* 1. Invoke t32 executable with appropriate Lauterbach Skript
|
|
||||||
* - Script has to load binary
|
|
||||||
* - and let system run until entry point
|
|
||||||
* -> Then we have a readily configured system
|
|
||||||
*
|
|
||||||
* @author Martin Hoffmann <hoffmann@cs.fau.de>
|
|
||||||
* @date 15.02.2013
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <t32.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string.h>
|
namespace fail {
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "config/VariantConfig.hpp"
|
T32Connector::T32Connector(char *hostname, unsigned port, unsigned packlen) : m_hostname(hostname), m_port(port), m_packetlength(packlen) {
|
||||||
#include "sal/SALInst.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
/* Default T32 error handler */
|
|
||||||
void err(int ernum){
|
|
||||||
if(err != 0){
|
|
||||||
cerr << "Error: " << err << endl;
|
|
||||||
//exit(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Here we go... */
|
T32Connector::~T32Connector() {
|
||||||
int main(int argc, char** argv){
|
// Close Connection to T32 on object deletion. Also works, on simulator.terminate -> global object.
|
||||||
|
std::cout << "[T32] Closing connection." << std::endl;
|
||||||
// Evaluate arguments
|
|
||||||
|
|
||||||
// Setup connection to Lauterbach
|
|
||||||
cout << "Lauterbach remote connection" << endl;
|
|
||||||
int error;
|
|
||||||
char hostname[] = "localhost";
|
|
||||||
char packlen[] = "1024";
|
|
||||||
char port[] = "20010";
|
|
||||||
|
|
||||||
cout << "[T32] Connecting to " << hostname << ":" << port << " Packlen: " << packlen << endl;
|
|
||||||
T32_Config("NODE=", hostname);
|
|
||||||
T32_Config("PACKLEN=", packlen);
|
|
||||||
T32_Config("PORT=", port);
|
|
||||||
|
|
||||||
cout << "[T32] Init." << endl;
|
|
||||||
err(T32_Init());
|
|
||||||
|
|
||||||
cout << "[T32] Attach." << endl;
|
|
||||||
err(T32_Attach(T32_DEV_ICD));
|
|
||||||
|
|
||||||
|
|
||||||
// Let the SimulatorController do the dirty work.
|
|
||||||
fail::simulator.startup();
|
|
||||||
|
|
||||||
// Here, we come back after any experiment called a resume
|
|
||||||
// Start execution of the SUT.
|
|
||||||
// The experiments/traces hopefully set some Breakpoints, we can react on.
|
|
||||||
// We may also provide a timeout, if a TimerListener was set wanted.
|
|
||||||
|
|
||||||
/*
|
|
||||||
while(1) {
|
|
||||||
// Start execution (with next timeout, in any)
|
|
||||||
|
|
||||||
// Wait for debugger to stop.
|
|
||||||
|
|
||||||
// Evaluate state.
|
|
||||||
|
|
||||||
// Call appropriate callback of the SimulatorController.
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
cout << "[T32 Backend] After startup" << endl;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
133
debuggers/t32/src/main.cc
Normal file
133
debuggers/t32/src/main.cc
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/**
|
||||||
|
* FailT32 -- Fault Injection on the Lauterbach Trace32 System
|
||||||
|
*
|
||||||
|
* 1. Invoke t32 executable with appropriate Lauterbach Skript
|
||||||
|
* - Script has to load binary
|
||||||
|
* - and let system run until entry point
|
||||||
|
* -> Then we have a readily configured system
|
||||||
|
*
|
||||||
|
* @author Martin Hoffmann <hoffmann@cs.fau.de>
|
||||||
|
* @date 15.02.2013
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <t32.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "config/VariantConfig.hpp"
|
||||||
|
#include "sal/SALInst.hpp"
|
||||||
|
#include "optionparser.h"
|
||||||
|
#include "optionparser_ext.hpp"
|
||||||
|
|
||||||
|
#include "T32Connector.hpp"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
/* Default T32 error handler */
|
||||||
|
void err(int ernum){
|
||||||
|
if(err != 0){
|
||||||
|
cerr << "Error: " << err << endl;
|
||||||
|
//exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static fail::T32Connector t32;
|
||||||
|
|
||||||
|
//!< Program options
|
||||||
|
enum optionIndex { UNKNOWN, HELP, RUN, T32HOST, PORT, PACKLEN };
|
||||||
|
const option::Descriptor usage[] =
|
||||||
|
{
|
||||||
|
{UNKNOWN, 0,"" , "" ,Arg::None, "USAGE: fail-client [options]\n\n"
|
||||||
|
"Options:" },
|
||||||
|
{HELP, 0,"" , "help",Arg::None, " --help \tPrint usage and exit." },
|
||||||
|
{RUN, 0,"r", "run",Arg::Required, " --run, -r \tLauterbach script to startup system." },
|
||||||
|
{T32HOST, 0,"t", "trace32-host",Arg::Required, " --trace32-host, -t <hostname> \tHostname/IP Address of the Trace32 instance. (default: localhost)" },
|
||||||
|
{PORT, 0,"p", "port",Arg::Required, " --port <NUM>, -p <NUM> \tTCP Port. (default: 20010)" },
|
||||||
|
{PACKLEN, 0,"l", "packet-length",Arg::Required, " --packet-length, -l <NUM> \tPacket length. (default: 1024)" },
|
||||||
|
{0,0,0,0,0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Here we go... */
|
||||||
|
int main(int argc, char** argv){
|
||||||
|
|
||||||
|
// Evaluate arguments
|
||||||
|
argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
|
||||||
|
option::Stats stats(usage, argc, argv);
|
||||||
|
option::Option options[stats.options_max], buffer[stats.buffer_max];
|
||||||
|
option::Parser parse(usage, argc, argv, options, buffer);
|
||||||
|
|
||||||
|
if (parse.error()){
|
||||||
|
cerr << "Error parsing arguments." << endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( options[HELP] ) // || argc == 0 || options[RUN].count() == 0) // to enforce -s
|
||||||
|
{
|
||||||
|
int columns = getenv("COLUMNS")? atoi(getenv("COLUMNS")) : 80;
|
||||||
|
option::printUsage(fwrite, stdout, usage, columns);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(options[RUN].count()){
|
||||||
|
cout << "Script: " << options[RUN].first()->arg << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
char hostname[] = "localhost";
|
||||||
|
if(options[T32HOST].count()){
|
||||||
|
cout << "T32 Hostname: " << options[T32HOST].first()->arg << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
char port[] = "20010";
|
||||||
|
if(options[PORT].count()){
|
||||||
|
cout << "T32 Port: " << options[PORT].first()->arg << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
char packlen[] = "1024";
|
||||||
|
if(options[PACKLEN].count()){
|
||||||
|
cout << "T32 Packet Length: " << options[PACKLEN].first()->arg << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Setup connection to Lauterbach
|
||||||
|
cout << "Lauterbach remote connection" << endl;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
cout << "[T32] Connecting to " << hostname << ":" << port << " Packlen: " << packlen << endl;
|
||||||
|
T32_Config("NODE=", hostname);
|
||||||
|
T32_Config("PACKLEN=", packlen);
|
||||||
|
T32_Config("PORT=", port);
|
||||||
|
|
||||||
|
cout << "[T32] Init." << endl;
|
||||||
|
err(T32_Init());
|
||||||
|
|
||||||
|
cout << "[T32] Attach." << endl;
|
||||||
|
err(T32_Attach(T32_DEV_ICD));
|
||||||
|
|
||||||
|
|
||||||
|
// Let the SimulatorController do the dirty work.
|
||||||
|
fail::simulator.startup();
|
||||||
|
|
||||||
|
// Here, we come back after any experiment called a resume
|
||||||
|
// Start execution of the SUT.
|
||||||
|
// The experiments/traces hopefully set some Breakpoints, we can react on.
|
||||||
|
// We may also provide a timeout, if a TimerListener was set wanted.
|
||||||
|
|
||||||
|
/*
|
||||||
|
while(1) {
|
||||||
|
// Start execution (with next timeout, in any)
|
||||||
|
|
||||||
|
// Wait for debugger to stop.
|
||||||
|
|
||||||
|
// Evaluate state.
|
||||||
|
|
||||||
|
// Call appropriate callback of the SimulatorController.
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
cout << "[T32 Backend] After startup" << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ bool VEZSExperiment::run()
|
|||||||
simulator.clearListeners();
|
simulator.clearListeners();
|
||||||
|
|
||||||
// resume backend.
|
// resume backend.
|
||||||
simulator.resume();
|
// simulator.resume();
|
||||||
|
|
||||||
// Explicitly terminate, or the simulator will continue to run.
|
// Explicitly terminate, or the simulator will continue to run.
|
||||||
simulator.terminate();
|
simulator.terminate();
|
||||||
|
|||||||
Reference in New Issue
Block a user