From: Gennadiy Rozental (gennadiy.rozental_at_[hidden])
Date: 2007-05-21 15:01:19


"Chad Maron" <cmaron_at_[hidden]> wrote in message
news:82DA1BC8E3377840AAC2B22ACFAB1EE4330A89D2_at_exchange3.corp.logicworks.net...
> Hey everyone,

Hi Chad,

I'm sorry for lond delay. I did not forget about you. I've been a bit busy
with boostcon.

> I'm new to the Boost libraries but *love* everything I've seen so far.
>
> I am having some trouble running my code on OS X.

Unfortunately I do not have access to this platform.

> Up until today I've been working in CentOS 4 on an older PIII server. I
> moved my code over to my Intel Mac workstation so I can use a fancier text
> editor (yea yea...). I made it through some linkage hurdles with Jam and
> everything compiled without issue. What happens now is I receive a Bus
> Error when running my unit tests. I've written a separate test app without
> using the Boost Unit Test Framework and I am error free.

Could you provide stack dump?

> I would not be surprised if this was the result of my not quite
> understanding the caveats of the Boost testing framework. I am using boost
> version 1.33.1 from Darwin Ports.

Couls you please try to use 1.34.0?

> I understand it might be tricky to provide feedback given I am not
> including all the source. I am fairly certain the issue I am having is
> with the testing framework and not my code BUT I will send it along if you
> want to take a look. It also appears that the test app fails *after*
> running the test cases:
>
> ----------
> # echo "SELECT attribute_id from attributes where interface_name =
> 'Login';" | ./sql_parse_test
> Running 2 test cases...
>
> -----1.38998
> SELECT attribute_id from attributes where interface_name = 'Login';
> SELECT : attributes
> Bus error
> ----------
>
> Even when I pipe millions of SQL statements to the test it will not die
> until after it's finished. NOTE: The second test case is a function that
> spits out some timing information (all the timing code is crappy and
> temporary). Even without the timing output the error takes place after
> running the proper test cases.
>
> GDB provides this tidbit:
> ----------
> Program received signal EXC_BAD_ACCESS, Could not access memory.
> Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
> 0x00812b22 in boost::unit_test::framework::get ()
> ----------
>
> Here is my Jamfile (I'm also a Jam newbie):
> ----------
> if $(OS) = MACOSX
> {
> C++ = "c++" ;
> C++FLAGS = "-g" ;
> LINK = "c++" ;
> HDRS = /opt/local/include/boost-1_33_1/ ;
> LINKLIBS = -lboost_unit_test_framework -lboost_thread ;
> LINKFLAGS += "-L/opt/local/lib" ;
> } else {
> HDRS = /usr/local/include/boost-1_33_1/ ;
> LINKLIBS = -lboost_unit_test_framework-gcc -lboost_thread-gcc-mt ;
> }
>
> Main sql_parse_test : SQLParser.cpp SQLDataCollector.cpp
> GenericSQLGrammar.cpp SQLParserTest.cpp ;
> ----------
>
> Here is my (broken) test code:
> ----------
> #include <sys/time.h>
> #include <unistd.h>
> #include <stdio.h>
>
> #include <iostream>
> #include <map>
> #include <string>
>
> // Boost.Test
> #include <boost/test/unit_test.hpp>
> #include <boost/test/parameterized_test.hpp>
> #include <boost/test/included/unit_test_framework.hpp>
>
> #include "SQLParser.h"
>
> using boost::unit_test::test_suite;
>
> int count = 0;
>
> SQLParser p;
>
> std::map<std::string,int> table_names;
> std::map<std::string,int> query_types;
>
> struct timeval tv;
> struct timezone tz;
>
> double total_time = 0.0;
> double start_time = 0.0;
> double end_time = 0.0;
> double execute_time = 0.0;
> double max_time = 0.0;
> double min_time = 1000000.0;
>
> void parse_test(const std::string& q) {
> gettimeofday(&tv, &tz);
> start_time = tv.tv_sec + (tv.tv_usec/1000000.0);
>
> BOOST_CHECK_MESSAGE(p.parse(q).full, "Statement: " << q);
>
> gettimeofday(&tv, &tz);
> end_time = tv.tv_sec + (tv.tv_usec/1000000.0);
> execute_time = end_time - start_time;
> if(execute_time > max_time) { max_time = execute_time; };
> if(execute_time < min_time) { min_time = execute_time; };
> total_time += execute_time;
> count++;
>
> // Output results of parse
> query_types = p.getQueryTypes();
> table_names = p.getTableNames();
>
> std::cout << "\n-----" << (execute_time*1000.0) << "\n" << q << "\n";
> std::map<std::string,int>::iterator iter;
> for(iter = query_types.begin(); iter != query_types.end(); iter++ ) {
> std::cout << (*iter).first << " ";
> }
> std::cout << ": ";
> for(iter = table_names.begin(); iter != table_names.end(); iter++ ) {
> std::cout << (*iter).first << " ";
> }
> std::cout << std::endl;
> }
>
> void weee() {
> std::cout << "\n\ntotal: " << total_time << " count: " << count << "
> avg(ms): " << ((total_time / count)*1000) << " max(ms): " <<
> (max_time*1000) << " min(ms): " << (min_time*1000) << std::endl;
> }
>
> struct sub_test_suite : public test_suite {
> sub_test_suite() {
> while(std::cin) {
> getline(std::cin, input_line);
> if(input_line.size() > 0) {
> queries.push_back(input_line);
> }
> }
> add( BOOST_PARAM_TEST_CASE( &parse_test, queries.begin(),
> queries.end() ), 0);
> }
> std::string input_line;
> std::vector<std::string> queries;
> };
>
> test_suite*
> init_unit_test_suite( int, char* [] ) {
> test_suite* test= BOOST_TEST_SUITE( "Spirit SQL parser" );
>
> test->add(new sub_test_suite);
> test->add(BOOST_TEST_CASE(&weee));
>
> return test;
> }
> ----------
>
> The working test code is quite similar:
> ----------
> #include <sys/time.h>
> #include <unistd.h>
> #include <stdio.h>
>
> #include <iostream>
> #include <map>
> #include <string>
>
> #include "SQLParser.h"
>
> int count = 0;
>
> SQLParser p;
>
> struct timeval tv;
> struct timezone tz;
>
> double total_time = 0.0;
> double start_time = 0.0;
> double end_time = 0.0;
> double execute_time = 0.0;
> double max_time = 0.0;
> double min_time = 1000000.0;
>
> void parse_test(const std::string& q) {
>
> gettimeofday(&tv, &tz);
> start_time = tv.tv_sec + (tv.tv_usec/1000000.0);
>
> if(!p.parse(q).full) {
> std::cout << "Parse failed" << std::endl;
> }
>
> gettimeofday(&tv, &tz);
> end_time = tv.tv_sec + (tv.tv_usec/1000000.0);
> execute_time = end_time - start_time;
> if(execute_time > max_time) { max_time = execute_time; };
> if(execute_time < min_time) { min_time = execute_time; };
> total_time += execute_time;
> count++;
>
> // Output results of parse
> query_types = p.getQueryTypes();
> table_names = p.getTableNames();
>
> std::cout << "\n-----" << (execute_time*1000.0) << "\n" << q << "\n";
> std::map<std::string,int>::iterator iter;
> for(iter = query_types.begin(); iter != query_types.end(); iter++ ) {
> std::cout << (*iter).first << " ";
> }
> std::cout << ": ";
> for(iter = table_names.begin(); iter != table_names.end(); iter++ ) {
> std::cout << (*iter).first << " ";
> }
> std::cout << std::endl;
> }
>
> int main() {
> std::string input_line;
>
> while(std::cin) {
> getline(std::cin, input_line);
> if(input_line.size() > 0) {
> parse_test(input_line);
> }
> }
>
> std::cout << "\n\ntotal: " << total_time << " count: " << count << "
> avg(ms): " << ((total_time / count)*1000) << " max(ms): " <<
> (max_time*1000) << " min(ms): " << (min_time*1000) << std::endl;
> return 0;
> }
> ----------
>
> Thanks in advance, any feedback would be greatly appreciated.

Could you simplify an example to the minimal possible failing snippet?

Gennadiy