I'm newbie in google protocol buffer. And now I have a issue as below:
I have created a simple message in testMessage.proto file:
option optimize_for = SPEED;
message TestMessage
{
optional string foo = 1;
optional string bar = 2;
}
Then I generated this message to testMessage.pb.h and testMessage.pb.cc files and included these files, also added libprotobuf libs to my test project.
Then I wrote a simple code to use this class:
TestMessage testMsg;
testMsg.set_foo("1234"); // set ok
testMsg.set_bar("abcd"); // set ok
string output;
try {
std::cout << testMsg.foo() << std::endl; // output foo ok
testMsg.PrintDebugString(); // throw bad allocation exception here
// testMsg.SerializeToString(&output); // also throw bad allocation exception here
} catch (std::exception ex) {
std::cout << ex.what() << std::endl;
}
This code is very simple, but I cannot understand why it cannot run correctly.
I googled for my issue but there is nowhere mention about it.
Everyone please help me with this issue.
Related
I have a Zaber linear stage for which I'm developing a C++ backend, to integrate it in my framework.
I have installed the Zaber API by following the instructions from the Zaber webpage. The installer actually generates the dll, lib, and headers necessary for my backend, and I'm confident that my CMake configuration is correct, because I can instantiate objects from the Zaber API.
So now, I am trying in my framework to go through their first code example:
// I commented out the following block:
// - enableDeviceDbStore() is supposed to allow the library to cache
// information from the online database
// - I don't need the online db
// - when I call it, it throws a "string too long" exception.
// try
// {
// zaber::motion::Library::enableDeviceDbStore(".");
// }
// catch (std::exception& e)
// {
// LogError << e.what();
// }
try
{
_connection = zaber::motion::ascii::Connection::openSerialPort("COM6");
// this also throws a "string too long" exception
}
catch (std::exception& e)
{
std::cout << e.what() << std::endl;
}
std::vector<zaber::motion::ascii::Device> deviceList;
try
{
deviceList = _connection.detectDevices(false);
// this throws a "Connection has been closed" exception
}
catch (std::exception& e)
{
std::count << e.what() << std::endl;
}
std::count << "Found " << deviceList.size() << " devices." << std::endl;
The problem is, when I use the Zaber Launcher (their UI that allows to control a connected stage), the port is "COM6", and I have made sure to close the connection on the Zaber Launcher before trying to connect with my framework.
I have also tried to launch their pre-configured C++ code example (VS17 solution), with the same problems arising (except their example doesn't catch exceptions, so it just crashes).
None of my exception matches their troubleshooting section.
I don't know how to proceed from here, or how to interpret the "string too long" error message, considering that I'm sure of my connection port.
I have code that parses a configuration file, which may send output to stdout or stderr in case of errors.
Unfortunately, when I pipe the output of my program to /dev/null, I get an exception: ios_base::clear: unspecified iostream_category error with stderror Inappropriate ioctl for device.
Here is the relevant part of my code:
try {
file.exceptions(std::ios::failbit | std::ios::badbit);
file.open(config_file);
// file.exceptions(std::ios::failbit);
}
catch (std::ios_base::failure& e) {
throw std::invalid_argument(std::string("Can't open config file ") + config_file + ": " + strerror(errno));
}
try {
errno = 0; // reset errno before I/O operation.
// ...
while (std::getline(file, line)) {
if ( [... unknown line ...] ) {
std::cerr << "Invalid line in config " << config_file << ": " << line << std::endl;
continue;
}
// debug info to STDOUT:
std::cout << config_file << ": " << line << std::endl;
}
} catch (std::ios_base::failure& err) {
std::cout << "Caught exception " << err.what() << std::endl;
if (errno != 0) {
char* theerror = strerror(errno);
file.close();
throw std::invalid_argument(std::string("Can't read config file ") + config_file + ": " + theerror);
}
}
try {
file.close();
}
catch (std::ios_base::failure& e) {
throw std::invalid_argument(std::string("Can't close config file ") + config_file + ": " + strerror(errno));
}
Here is an example of an exception:
~> ./Application test1.conf > /dev/null
test1.conf: # this is a line in the config file
Caught exception ios_base::clear: unspecified iostream_category error
When I don't pipe to /dev/null (but to stdout or a regular file), all is fine. I first suspected that the cout and cerr where causing problems, but I'm not sure.
I finally found that I could resolve this by enabling this line after opening the file, so that the badbit-type of exceptions are ignored.
file.exceptions(std::ios::failbit);
Frankly, I'm too novice in C++ to understand what is going on here.
My questions: what is causing the unspecified iostream_category exception? How can I avoid it? Is setting file.exceptions(std::ios::failbit); indeed a proper solution, or does that give other pitfalls? (A pointer to a good source detailing best practices for opening files in C++, which does included all proper exception handling, or some background explained, is highly appreciated!)
I would recommend the following approach. This is based on my own experience as well as on some of the links that have been provided above. In short I would suggest the following:
Don't turn on the exceptions when using C++ streams. They are just so hard to get right I find they make my code less readable, which sort of defeats the purpose of exceptions. (IMHO it would be better if the C++ streams used exceptions by default and in a more reasonable manner. But since it isn't built that way it is better not to force the issue and just follow the pattern that the designers seem to have had in mind.)
Rely on the fact that getline will handle the various stream bits properly. You don't need to check after each call if the bad or fail bits are set. The stream returned by getline will be implicitly cast to false when these occur.
Restructure your code to follow the RAII pattern so that you don't need to call open() or close() manually. This not only simplifies your code, but ensures that you don't forget to close it. If you are not familiar with the RAII pattern, see https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization.
Don't repeatedly put things like errno or your filename into the exceptions you generate. Keep them minimal to avoid repetition and use a catch block at the bottom to handle the errors, possibly throwing a new exception that adds the details you wish to report.
With that said, I would recommend rewriting your code to look something like the following:
using namespace std;
try {
errno = 0;
// Construct the stream here (part of RAII) then you don't need to call
// open() or close() manually.
ifstream file(config_file);
if (!file.is_open()) {
throw invalid_argument("Could not open the file");
}
while (getline(file, line)) {
// do all your processing as if no errors will occur (getline will
// be explicitly cast to a false when an error occurs). If there is
// something wrong with a line (bad format, etc.) then throw an
// exception without echoing it to cerr.
}
if (file.bad()) {
throw invalid_argument("Problem while reading file");
}
}
catch (const invalid_argument& e) {
// Whatever your error handling needs to be. config_file should still
// be valid so you can add it here, you don't need to add it to each
// individual exception. Also you can echo to cerr here, you don't need
// to do it inside the loop. If you want to use errno it should still
// be set properly at this point. If you want to pass the exception to
// the next level you can either rethrow it or generate a new one that
// adds additional details (like strerror and the filename).
}
I've improved on my earlier answer by writing a couple of functions that handle the stream checks using lambdas to actually process the file. This has the following advantages:
You don't forget where to put the stream checks.
Your code concentrates on what you want to do (the file processing) and not on the system boilerplate items.
I've created two versions. With the first your lambda is given the stream and you can process it how you like. With the second your lambda is given one line at a time. In both cases if an I/O problem occurs it will throw a system_error exception. You can also throw your own exceptions in your lambda and they will be passed on properly.
namespace {
inline void throwProcessingError(const string& filename, const string& what_arg) {
throw system_error(errno, system_category(), what_arg + " " + filename);
}
}
void process_file(const string& filename, function<void (ifstream &)> fn) {
errno = 0;
ifstream strm(filename);
if (!strm.is_open()) throwProcessingError(filename, "Failed to open");
fn(strm);
if (strm.bad()) throwProcessingError(filename, "Failed while processing");
}
void process_file_line_by_line(const string& filename, function<void (const string &)> fn)
{
errno = 0;
ifstream strm(filename);
if (!strm.is_open()) throwProcessingError(filename, "Failed to open");
string line;
while (getline(strm, line)) {
fn(line);
}
if (strm.bad()) throwProcessingError(filename, "Failed while processing");
}
To use them, you would call them as follows...
process_file("myfile.txt", [](ifstream& stream) {
... my processing on stream ...
});
or
process_file_line_by_line("myfile.txt", [](const string& line) {
... process the line ...
});
I am trying to read a XML file using ticpp::LoadFile(); It was not successfull and I did not know why because I have no idea how to catch the exceptions. Here is what I did:
try
{
// Load a document
ticpp::Document doc( pFilename );
doc.LoadFile();
// Get an element by chaining calls - no return values to check, no TiXmlHandle
ticpp::Element* pElem = doc.FirstChildElement()->NextSibling();
// do something useful here
}
catch( ticpp::Exception& ex )
{
// If any function has an error, execution will enter here.
// Report the error
std::cout << ex.what();
}
But I the ex actually shows grayed as if it is never declared. I am wondering how I can catch the exceptions in this case?
It turned out it was the file path that is messed up.
The code itself is fine.
I have been thru a few questions but did not find an answer.
I wonder how should the exception handling be implemented in a C++ software so it is centralized and it is tracking the software progress?
For example, I want to process exceptions at four stages of the program and know that exception happened at that specific stage:
1. Initialization
2. Script processing
3. Computation
4. Wrap-up.
At this point, I tried this:
int main (...)
{
...
// start logging system
try {
...
}
catch (exception &e)
{
cerr << "Error: " << e.what() << endl;
cerr << "Could not start the logging system. Application terminated!\n";
return -1;
}
catch(...)
{
cerr << "Unknown error occured.\n";
cerr << "Could not start the logging system. Application terminated!\n";
return -2;
}
// open script file and acquire data
try {
...
}
catch (exception &e)
{
cerr << "Error: " << e.what() << endl;
cerr << "Could not acquire input parameters. Application terminated!\n";
return -1;
}
catch(...)
{
cerr << "Unknown error occured.\n";
cerr << "Could not acquire input parameters. Application terminated!\n";
return -2;
}
// computation
try {
...
}
...
This is definitely not centralized and seems stupid.
Or maybe it is not a good concept at all?
You could keep a global variable containing the state of the program, and print it out in the catch block. Then you would only need two catch blocks, one for std::exception and one for everything else.
It seems to me that you're trying to use exceptions as (more or less) a replacement for logging. I think in this case, you'd be a lot better off using the two together -- in particular, I'd probably have a small exception handler that put output in the log, so your code would look something like this:
try {
// start logging system
}
catch (exception const &e) { std::cerr << e.what << "error starting logging"; }
catch (...) { std::cerr << "Unknown error starting logging"; }
try {
{ scoped_log("script processing");
start_script();
}
{ scoped_log("computation");
do_computation();
}
{ scoped_log("wrap up");
wrap_up();
}
}
catch(std::exception const &e) { log << "error: " << e.what() << "\n"; }
catch(...) { log << "Unknown exception\n"; }
where "scoped_log" is a simple class something like:
class scoped_log {
std::string caption;
public:
scoped_log(std::string const &c) : caption(c) {
log << "Starting: " << caption << "\n";
}
~scoped_log() { log << "Finished: " << caption << "\n"; }
};
This allows you to centralize most of the exception handling. The only exception (no pun intended) is for starting up the logging system itself -- you obviously can't use logging to report problems with starting up the logging system.
Once the logging system is up, however, things are a lot simpler -- you use the combination of logging and exception handling to track down when the problem occurred. Keep one minor detail in mind: since the scoped_log is an object that's destroyed when the scope is exited (for any reason), the log will have a structure that might (at least initially) seem a bit misleading -- the error message will follow the "finshed xxx" message in the log. For example, if a script file couldn't be opened, your log might look something like this:
starting script processing
finished script processing
error: could not open file: 'script.input'
At least IMO, that's unlikely to cause a problem if you're aware of the situation.
In my opinion, exceptions should be (generally) caught in 5 conditions:
You can legitimately handle the exception and continue normally (e.g. you caught a boost::bad_lexical_cast from user input, but can recover by reporting the error to the user).
You need to translate the exception from one source to another (e.g. your library uses another library as a pure implementation detail and wants to translate a 'socket_exception' into a 'service_exception' or something of the sort). In .Net, I'd do this by throwing a new exception instance w/ an inner exception. In C++, it can be useful to provide a consistent interface to your users, especially if you're, for instance, only throwing exceptions derived from std::exception, but a dependent library throws exceptions from a non-standard type (string, int, const char*, custom type, etc).
You're writing a cross language wrapper. C++/C, C++/Fortran, etc. C++ exceptions don't tend to cross these barriers well, and you're best off translating them into the target runtime's error handling facilities, if possible.
You're in main, and wish to capture some slight information from the exception & log before you crash. If you do so, there's two primary camps on what to do next: exit(1) or throw; and generate a core (on *nix). I've mixed feelings...
much like in main, around a thread entry. Can be helpful to log why a thread terminated, and then treat thread termination in a appropriate manner.
A simple way of having exception processing centralized is creating a simple function to process the exceptions and then using a generic catch that calls the function:
void processExceptions( std::string const & stage )
{
std::cout << "Exception caught at stage " << stage << std::endl;
try {
throw; // rethrow the last caught exception
}
catch ( exception1 const & ) {
// do process 1
}
catch ( exception2 const & ) {
// ...
}
}
int main()
{
try {
initialize();
}
catch ( ... ) {
processExceptions( "initialization" );
}
try {
stage2();
}
catch ( ... ) {
processExceptions( "stage2" );
}
}
I have never used that technique to identify when an exception was caught, but it is quite useful to avoid duplicating exception processing code in many places if it is the same.
Note that if you call the function when no exception has been thrown (outside of a catch) you will get undefined behavior and more often than not your application will die.
The other alternative is to have distinct, by-you-defined exceptions which you then handle in one central place instead of different return values. So when the exception occurs like "could not acquire input parameters" you would throw something like an "invalid_parameters exception" with some more context information added about the reason for the exception. Then in a central place you display the error.
If you really want to more centralize this, you could define your own error classes such as
class does_not_open {};
class cannot_write {};
or so. You'll need more work in your different parts, e.g., check if open succeeds; if not, throw does_not_open (etc.). But after you organize yourself this way, you can put the entire main part of your code into the following form:
try{
}
catch(does_not_open &e){
}
catch(cannot_write &e){
- your code here -
}
catch(...){
- your code here -
}
Not sure this accomplishes what you were hoping for...but gl. :)
Do you know how can I log the exception ?
right now the message in the catch statement is printed, but i cannot understood why insĀ“t Manage.Gere() called sussefully .
try{
Manager.Gere(&par,&Acc, coman, comando, RunComando, log, &parti, comandosS, RunComandosSuper,true);
}
catch (...)
{
log("ERROR ENTER GERE*****");
}
Perif::Gere(CString *par, CString *Acc, HANDLE coman, HANDLE comando, HANDLE RunComando, Log &log, CString *parti, HANDLE comandosS, HANDLE RunComandosSuper,bool first)
{
log->LogD("Perif :: Gere Enter****** "); //It doesnt get printed
}
A well-behaved API should only throw objects of types derived from std::exception. If that's the case, then the exception will have a member function const char *what() containing a message, which will hopefully describe the error. So you could try this, and hope that it helps:
try {
Manage.Gere(...);
} catch (const std::exception &e) {
log(e.what());
} catch (...) {
log("Manage.Gere threw unknown exception");
}
If it throws a type that isn't a std::exception, then you will need to look at the documentation and/or source for the function to see what could go wrong, and what types it does throw. If none of this is available, I would be looking for a better library.
First thing you need there is find which exceptions Manage.Gere can throw.
Then catch them specifically like catch(FirstExceptionGereThrows &exc) and when you catch all possible exceptions, you'll know what is failing in Manage.Gere.
catch(FirstException &exc){
log << "Failed because FirstException\n";
}catch(SecondException &exc){
log << "Failed because SecondException\n";
}
After, and if you are lucky enough the exceptions thrown by Manage.Gere may include some extra info about the crash which you could log as well.
catch(FirstException &exc){
log << "Failed because FirstException: " << exc.what() << "\n";
}
As others have suggested, RTFM is really the answer. However, I've found that lazy programmers often write code like:
if ( something ) {
throw "Something has happened!";
}
so it is always worthwhile trying to catch both const char * ans std::string:
try {
// stuff
}
catch( const char * s ) {
cerr << s << endl;
}
catch( const std::string & s ) {
cerr << s << endl;
}
// other catches here
You can also use my tool as an external debugger which catches C++ exceptions and automatically create minidump files for offline debugging. See http://alax.info/blog/1211 for details.
The good thing is that you don't need any code for this, or you can even debug an application which you don't have code for, or you cannot rebuild it for any reason. The dump file will get you stacks and information, and the application will be able to continue execution.