Archive for category c/c++

libbash final report

My GSoC project will end in this weekend so this is the final report. This week, I spent most of my time making sure the project is in a good state for future developers.

So far, libbash can generate correct ebuild metadata for 8414 out of 27586 ebuilds. What is blocking us from moving on? We need to be able to parse all the eclasses. But there are still a few problems in the parser grammar. On the other hand, our runtime is not complete. In one word, more time is required. This is the ohloh page for libbash where you can learn some statistics of the code.

I wrote an ebuild for libbash and put it in my overlay. Now you can play with it by

layman -a qiaomuf
emerge libbash

Although libbash is not powerful enough to generate all ebuild metadata, it can do something useful now. As I said before, you can always check what libbash can support from these test scripts. One thing you should notice is that we do not support running external command.

The library is quite easy to use. To give you a taste, here is a code snippet showing how to use it:

#include <algorithm>
#include <iostream>
#include <iterator>

#include <libbash/libbash.h>

int main(int argc, char** argv)
  // store variable values and function names
  std::unordered_map<std::string, std::vector<std::string>> variables;
  std::vector<std::string> functions;

  // interpret the script specified by argv[1]
  libbash::interpret(argv[1], variables, functions);

  // do what ever you want with variables and functions
            std::ostream_iterator<std::string>(std::cout, " "));
  std::cout << std::endl;

To get it compiled, run

g++ -std=c++0x $(pkg-config --cflags --libs libbash) test.cpp

The program will interpret the script like bash and store the result in the variable map and function name list. All the variables are treated as arrays. For more information, you can check the API documentation.
(P.S.: The library is not stable so please don’t use it in any serious place)

So what’s next? I think it would be improving the parser grammar, figuring out problems from the output of instruo and implement more runtime. People are welcome to make contributions. I’ll continue making contributions after GSoC.

Last but not least, I’d like to thank Google and Gentoo community for giving me such great experience. Thank Petteri for mentoring me. I enjoyed a wonderful summer with you and learned a lot including C++0x, boost libraries, ANTLR, autotools, Scrum and so on. Thank Donnie, Robin and other people who helped me.

OK, I’m going to get myself prepared and seek a job 😉



Use gcov and lcov to know your test coverage

As we all know, unit test has been a crucial part of software development. I feel I was walking on ice if I was coding without writing tests. But even if we have unit tests, things may still go wrong if the tests have bad coverage. Fortunately, there are many tools today to help us analyze our code and give us every detail of the quality of our unit tests. GNU gcov is such a tool for code compiled with GCC.

gcov is very easy to use. If you’re developing a C/C++ project, all you have to do is to compile your project with “-g -O0 –coverage”. “–coverage” is a synonym for-fprofile-arcs, -ftest-coverage(compiling) and-lgcov(linking). This tells the compiler to generate additional information and code needed by gcov.

OK, let’s run our tests. GCC will generate a bunch of files(profiles) that will be used later. These files know how your tests was executed and record many information such as arc transition counts and some summary information. Now we’re ready to view our test coverage now with gcov.  But gcov doesn’t give us a report that is easy to read and it’s not convenient. Here comes the tool called “LCOV”.

LCOV test coverage report for libbash

Read the rest of this entry »

, , ,


Handling unit test with C++ visibility=hidden

Recently I started working on the libbash project. I will write several articles talking about it in future. Now I’d just like to write something about the problem we encountered during development.

Our project will be a shared library. The C++ visibility support could improve the overall performance. Put simply, it hides most of the ELF symbols which would have previously (and unnecessarily) been public. Well it’s good for the library, it’s not good for unit tests(namely gtest) because they need to know the symbols.

Of course we don’t want  the unit tests to be part of our library. So we need to find some way to let the unit test know the symbols and separate them into different automake targets. Our first solution is to use hidden visibility for the library and create an internal target with default visibility for the unit test. However, that requires compiling the source code twice. Finally Petteri Räty come with a solution (He is too busy to write a post :P):

libcppbash_la_SOURCES = blah
libcppbash_la_CXXFLAGS = $(AM_CXXFLAGS) -fvisibility=hidden -fvisibility-inlines-hidden

cppunittests_SOURCES = blah
cppunittests_LDADD = $(GTEST_LIBS)
cppunittests_LDFLAGS = -static

Here’s his explanation:
libtool by default builds both a shared and a static library for our project. This is why you see it building things twice (with PIC and without). Giving -static to libtool is just telling it to use the static version. Using the static version means everything ends up in the unit test binaries.

, , ,


Valgrind – Your Memory Assistant

Valgrind is a programmer tool that allows to track memory related errors in C and C++ programs. This tool helped me greatly when I was checking out potential memory leaks.

As we all know, it’s really difficult to ensure that your program don’t have any memory leak at all. A good coding practice always helps, but usually it’s infeasible to find all bugs by our eyes. So we need a tool to automatically find these bugs. Valgrind is such a tool and is very easy to use. Before using it, you could compile your program with -g to include debugging information and -O0 to disable compiler’s optimization. Doing these will let memcheck’s error messages include exact line numbers.

Then you just use:

valgrind --leak-check=yes myprog arg1 arg2

The result will be displayed and it will tell you where the potential memory leaks are. You could fix the bugs according to it. There are more options and you could check them out on man page.

For gnome applications building with glib, things are a little different since glib has it’s own memory management library. Here are some tips I stolen from  Gnome community:

G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=20 --log-file=vgdump your-program

and you could also use it for libtool program. Check this out to see how to do this.