When debugging a C++ Boost.Test application inside VS2010 (VS2008), how to make the debugger stop at Boost.Test assertion failure points?
I haven't tried this myself, but in theory you'd want to set a breakpoint somewhere in the check_impl function (in the boost_unit_test_library source), probably in the non-PASS cases of its final case statement.
In practice I always just find myself just running the tests again (or the specific problem test, selected with --run_test=...) with a breakpoint on the offending check.
Note that a failing BOOST_REQUIRE results in a throw, so if you enable VS' break-on-C++-exceptions in the debugging options that'll break on those nicely (but not BOOST_CHECKs, which just return and carry on).
I put breakpoints in check_impl(), as suggested by #timday.
Here is an extract from Boost 1.57.0, file boost/test/impl/test_tool.ipp, lines 355 to 373:
switch( tl ) {
case PASS:
framework::assertion_result( true );
return true;
case WARN:
return false; // ADD BREAKPOINT HERE
case CHECK:
framework::assertion_result( false );
return false; // ADD BREAKPOINT HERE
case REQUIRE:
framework::assertion_result( false );
framework::test_unit_aborted( framework::current_test_case() );
throw execution_aborted(); // ADD BREAKPOINT HERE
}
assertion.hpp
template class binary_expr:
assertion_result evaluate( bool no_message = false ) const
{
assertion_result const expr_res( value() );
if( no_message || expr_res )
return expr_res; <<<<<<<< SUCCESS
BRK wrap_stringstream buff;
report( buff.stream() );
return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );
}
Related
So the mongo c++ documentation says
On a failover situation, expect at least one operation to return an
error (throw an exception) before the failover is complete. Operations
are not retried
Kind of annoying, but that leaves it up to me to handle a failed operation. Ideally I would just like the application to sleep for a few seconds (app is single threaded). And retry with the hopes that a new primary mongod is established. In the case of a second failure, well I take it the connection is truly messed up and I just want to thrown an exception.
Within my MongodbManager class this means all operations have this kind of double try/catch block set up. I was wondering if there is a more elegant solution?
Example method:
template <typename T>
std::string
MongoManager::insert(std::string ns, T object)
{
mongo::BSONObj = convertToBson(object);
std::string result;
try {
connection_->insert(ns, oo); //connection_ = shared_ptr<DBClientReplicaSet>
result = connection_->getLastError();
lastOpSucceeded_ = true;
}
catch (mongo::SocketException& ex)
{
lastOpSucceeded_ = false;
boost::this_thread::sleep( boost::posix_time::seconds(5) );
}
// try again?
if (!lastOpSucceeded_) {
try {
connection_->insert(ns, oo);
result = connection_->getLastError();
lastOpSucceeded_ = true;
}
catch (mongo::SocketException& ex)
{
//do some clean up, throw exception
}
}
return result;
}
That's indeed sort of how you need to handle it. Perhaps instead of having two try/catch blocks I would use the following strategy:
keep a count of how many times you have tried
create a while loop with as terminator (count < 5 && lastOpSucceeded)
and then sleep with pow(2,count) to sleep more in every iteration.
And then when all else fails, bail out.
Is it normal to have to update assertions after upgrading the compiler from VC++ 6 to MSVC 2005? I have the following function which works without triggering the assertion in Visual Studio 6 but anything newer it fails.
void CMainFrame::OnUpdateGraphValue (CCmdUI* pCmdUI) {
BOOL bMax;
CMDIChildWnd *child = MDIGetActive (&bMax);
if (child)
{
if (child->IsKindOf (RUNTIME_CLASS (CGaugeChildFrame)))
{
CGaugeView *pView = (CGaugeView *) child->GetActiveView ();
if (pView->wndActive)
{
ASSERT (pView->IsKindOf (RUNTIME_CLASS (CGaugeView)));
pCmdUI->Enable (TRUE);
return;
}
}
if (child->IsKindOf (RUNTIME_CLASS (CGarterChildFrame)))
{
CGarterView *pView = (CGarterView *) child->GetActiveView ();
if (pView->wndGraphics)
{
ASSERT (pView->IsKindOf (RUNTIME_CLASS (CGarterView)));
pCmdUI->Enable (TRUE);
return;
}
}
}
pCmdUI->Enable (FALSE); }
The failure occurs on line ASSERT (pView->IsKindOf (RUNTIME_CLASS (CGaugeView))); When I click print preview the type is not CGaugeView but CPreviewView.
Can someone please shed some light on this for me? Thanks
It's not valid to cast to a type before you have checked the type is compatible.
So you need to do:
if(child->GetActiveView ()->IsKindOf(RUNTIME_CLASS(CGaugeView)))
{
CGaugeView *pView = (CGaugeView *) child->GetActiveView ();
As to why has this behaviour changed, I don't know. Maybe before you were ignoring the asserts? Maybe you didn't try a debug built?
Or maybe the print preview architecture has changed in version 7? Maybe there was no pView->wndGraphics in print preview mode in the previous version, so the code path never got triggered.
However since you aren't using the code path for anything maybe just dump it.
We have a Groovy Script that exits with a status of 0 when everything worked and a non-0 status for different types of failure conditions. For example if the script took a user and an email address as arguments it would exit with a status of 1 for an invalid user, and a status of 2 for an invalid email address format. We use System.exit(statusCode) for this. This works fine, but makes the the script difficult to write test cases for.
In a test we create our GroovyShell, create our Binding and call shell.run(script,args). For tests that assert failure conditions, the System.exit() causes the JVM (and the test) to exit.
Are there alternatives to using System.exit() to exit a Groovy Script? I experimented with throwing uncaught exceptions, but that clutters the output and always makes the status code 1.
In our test cases I have also experimented with using System.metaClass.static.invokeMethod to change the behavior of System.exit() to not exit the JVM, but that seems like an ugly hack.
imho System.metaClass.static.invokeMethod looks fine. It's test, and hacking is fine here.
Also you can create your own wrapper around it, like:
class ExitUtils {
static boolean enabled = true
static exit(int code) {
if (!ExitUtils.enabled) {
return //TODO set some flag?
}
System.exit(code)
}
}
and disable it for tests.
Here is the technique we eventually used.
We can't just ignore a call to System.exit() since the script would continue to run. Instead we want to throw an exception with the desired status code. We throw a (custom) ProgramExitException when System.exit() is called in our tests
class ProgramExitException extends RuntimeException {
int statusCode
public ProgramExitException(int statusCode) {
super("Exited with " + statusCode)
this.statusCode = statusCode
}
}
then we intercept System.exit() to throw this exception
/**
* Make System.exit throw ProgramExitException to fake exiting the VM
*/
System.metaClass.static.invokeMethod = { String name, args ->
if (name == 'exit')
throw new ProgramExitException(args[0])
def validMethod = System.metaClass.getStaticMetaMethod(name, args)
if (validMethod != null) {
validMethod.invoke(delegate, args)
}
else {
return System.metaClass.invokeMissingMethod(delegate, name, args)
}
}
and lastly we have GroovyShell catch any ProgramExitException and return the status code from the run method.
/**
* Catch ProgramExitException exceptions to mimic exit status codes
* without exiting the VM
*/
GroovyShell.metaClass.invokeMethod = { String name, args ->
def validMethod = GroovyShell.metaClass.getMetaMethod(name, args)
if (validMethod != null) {
try {
validMethod.invoke(delegate, args)
} catch (ProgramExitException e) {
return e.statusCode
}
}
else {
return GroovyShell.metaClass.invokeMissingMethod(delegate, name, args)
}
}
Our tests can stay looking simple, we don't need to change anything in the scripts and we get the behavior we expect from running on the command line.
assertEquals 'Unexpected status code', 0, shell.run(script,[arg1, arg2])
assertEquals 'Unexpected status code', 10, shell.run(script,[badarg1, badarg2])
I have a do-while loop that needs to log a message once (so it doesn't clutter the log) each time its status (e.g. pass/fail) changes, but still has to do other things each time it goes through the loop. Using a simple boolean variable can basically tell you if you've already logged that message, which works once you're in a known condition. However, if you want the message to be printed the first time in either case (pass/fail), you have to account for that. For example, if you default your condition to true, and it is, in fact, true the first time, it won't log the 'True' message b/c it thinks it was already true (and vice-versa for i.c. false).
This seems like it would be a good place for a nullable boolean with i.c.=Null, but in languages where those aren't present, what's one to do?
The simplest solution I could think of would be to use an extra boolean variable like 'firstTime = True', but using that always bothers me as an elementary workaround when I feel like there should be a more delicate way to handle it. Another option is to use the breakout condition of the do-while as your initial condition for whatever variable you're using as your conditional, but that can be confusing when someone reads int status = STATUS_QUIT, and it certainly requires more explanatory comments than bool firstTime = true. A third option would be to use an enum instead of a bool and have {firstTime, true, false} or something.
Are there other reasons for using one over the other, or are there better ways of doing this?
Code example with two options I came up with:
Using bool firsttime:
bool firstTime = true, infoFound = false;
do
{
if (getInfo())
{
if (!infoFound)
{
// log it (ONCE)(important)
infoFound = true;
}
// use info (every time)
}
else if (infoFound || firstTime)
{
// log it (ONCE)(important)
infoFound = false;
firstTime = false;
}
// FYI, WaitForStatusUpdate is a blocking call...
} while (STATUS_QUIT != WaitForStatusUpdate());
Use the while loop 'break-out condition' as the initial condition for a check variable:
(status is updated at the end of the do-while, so the do section will not be executed ever again if status == breakOutCondition; we can use this to our advantage here and set status = breakOutContition initially - the first time through it will be breakOutCondition but any subsequent loop will be something else... Still not sure I like this as it's kind of a hack...
bool infoFound = false;
int status = STATUS_QUIT;
do
{
if (getInfo())
{
if (!infoFound)
{
// log it (ONCE)(important)
infoFound = true;
}
// use info (every time)
}
else if (infoFound || firstTime)
{
// log it (ONCE)(important)
infoFound = false;
}
status = WaitForStatusUpdate();
} while (STATUS_QUIT != status);
(I'm tagging this as c++ since that's what I'm using, but this really could apply to any language with similar constructs)
Wouldn't an enum be clearer?
enum State { Unknown, Pass, Fail };
State state = Unknown;
...
State newState = getInfo() ? Pass : Fail;
if (newState != state) { log(); state = newState; }
C++ almost has nullable booleans, boost::optional<bool> would do the trick I believe.
One common way to do this in C++ is a stream wrapper that you create in the proper context, and it remembers for example how many times it's flushed and prevents further logging from happening. You just do your logging as normal and let the stream decide whether to send it on to the wrapped stream.
My application crashes on reading / writing data from the database. I have one database on c: and I copy-pasted and rename with different name. The following process is what I have used for copy...Please guide me if you have any suggestion or solution.
RFs fs;
fs.Connect();
CFileMan* fileMan=CFileMan::NewL(fs);
CleanupStack::PushL(fileMan);
TInt err=fileMan->Copy(anOld,aNew);
CleanupStack::PopAndDestroy(fileMan);
fs.Close();
if(err==KErrNone)
return ETrue;
else
return EFalse;
It crashes on following line when I am trying to insert or get any data from the database.
User::LeaveIfError( iDatabase.Execute( strSQL ) );
db creation:
TBool Open = OpenL();
if (!Open)
{
User::LeaveIfError(iDbSession.Connect());
CleanupClosePushL(iDbSession);
CleanupClosePushL(iDatabase);
User::LeaveIfError(iDatabase.Replace(iDbSession, iDBPath ));
// create table
_LIT(KSQLtest,"CREATE TABLE testtable(id INTEGER,test1 VARCHAR(50),test2 VARCHAR(50))"); User::LeaveIfError(iDatabase.Execute(KSQLtest));
iDatabase.Compact();
iDatabase.Close();
iDbSession.Close();
CleanupStack::PopAndDestroy();
CleanupStack::PopAndDestroy();
Open database:
User::LeaveIfError( iDbSession.Connect() );
CleanupClosePushL( iDbSession );
if ( KErrNone != iDatabase.Open(iDbSession, iDBPath))
{
iDbSession.Close();
CleanupStack::PopAndDestroy();
return EFalse;
}
else
{
CleanupClosePushL( iDatabase );
iIsDatabaseOpened = ETrue;
return ETrue;
}
User:: LeaveIfError() throws an exception when iDatabase.Execute() returns an error code.
You can find the most common Symbian error codes at NewLC
If the crash happens before RDbDatabase::Execute() is actually run, we'll need to see more code to figure out why iDatabase is in a bad state.
You need to explain what "crashes" means - an exception/leave? a panic? If so, what leave code, or what panic category and number?
If it "crashes" here
User::LeaveIfError( iDatabase.Execute( strSQL ) );
you might want to check the return value, i.e.
TInt error = iDatabase.Execute( strSQL );
//Now log/display the error
User::LeaveIfError(error);
A few other points of note:
If you use CleanupClosePushL() on an object, you don't need to call both Close() and CleanupStack::PopAndDestroy(). The latter will call Close() for you.
Your OpenL() function uses a mix of leaving and return code which is considered bad style generally. In addition, functions which leave something on the cleanup stack are generally named xxxxLC(), the trailing 'C' denoting a cleanup item.