Nicolás Brailovsky


A modern blog

Search Results

save Jun-11-2010

Vim tips: make things work

So, you are an uber console geek, using only vim and the command line to compile all your projects, execute the tests, blah blah blah… if only you could squeeze that microsecond lost whenever you switch from vim to compile you’d be 1e-4 seconds more productive… oh, wait, you can!

Whenever you think you’re project is good enough to compile just hit :make to be proven wrong. Type :make test to run your tests (because you are using TDD, aren’t you?) and watch all those red flags fly by.Also, add the following mapping to your ~/.vimrc for an extra happy coding session:

  1. map <F5> :make
  2. map <F6> :make test
filed Posted under Vim Tips and the tags
save Jun-1-2010

Oh shit, the stack

* Post from the wayback machine. I wrote this a long time ago but it got way down the posts queue, don’t know why *

I liked my vacations very much, thank you. Some people enjoyed vacations from me too. At work they even decided to keep this gem for my return. Upon my arrival a nice coredump was waiting at my desk, so to speak. Check it out, isn’t it beautiful?

  1. 0 0xff05d070 in inflate_fast () from /usr/lib/libz.so
  2. 1 0xff05a13c in inflate () from /usr/lib/libz.so
  3. 2 0×00146224 in ZDecompress::decompress (this=0xfbc7b300, sauce=@0xfbe7b740, dest=@0×27c910) at Compressor.h:134
  4. 3 0×00145e80 in HandleClient::get_client_data (this=0×27c810, output_stream=0×27c910) at IPC/DataReceiver.cpp:54

Yeah, that’s getting killed inside zlib. Nice way to start the year, a bug in zlib. What led me to that conclusion? Easy, the same compressed file worked in Ubuntu. Must be a bug in zlib then!

The next step was getting zlib’s code and adding enough printf’s to know the problem was in the middle of the file, not at the beginning nor the end; indeed, most of the file could be correctly decoded, but then it just died. This looked more and more like a bug in zlib.

I began to scramble things around, trying to isolate the problem. Things just got weirder, the same code worked fine if instead of being inside a thread I was on the main thread. If you have psychic powers you now have enough information to know what the problem was. Although I should have known too (this wasn’t even the first time I saw a problem like this one!) I was mindset on finding a bug in zlib, which now, it seems, only appears while interacting with ACE (in my defence, I did see these kind of bugs too).

Fiddling around with the code some more, even stranger backtraces began to appear. First this one:

  1. Program received signal SIGSEGV, Segmentation fault.
  2. [Switching to LWP 10]
  3. 0xfd6b88fc in _pollsys () from /usr/lib/libc.so.1
  4. (gdb) bt
  5. #0  0xfd6b88fc in _pollsys () from /usr/lib/libc.so.1
  6. #1  0×696e7661 in ?? ()
  7. #2  0×696e7661 in ?? ()

And then this other one, which led me into the right direction:

  1. Program received signal SIGSEGV, Segmentation fault.
  2. [Switching to LWP 9]
  3. 0×000b6784 in std::operator| (__a=Cannot access memory at address 0xfbb7b094
  4. )
  5.     at /usr/local/lib/gcc/sparc-sun-solaris2.10/3.4.6/../../../../include/c++/3.4.6/bits/ios_base.h:124
  6. 124       { return _Ios_Openmode(static_cast(__a) | static_cast(__b)); }
  7. (gdb) bt
  8. #0  0×000b6784 in std::operator| (__a=Cannot access memory at address 0xfbb7b094
  9. )
  10.     at /usr/local/lib/gcc/sparc-sun-solaris2.10/3.4.6/../../../../include/c++/3.4.6/bits/ios_base.h:124
  11. #1  0×00152d5c in HandleClient::get_client_data (this=Cannot access memory at address 0xfbb7b088
  12. ) at IPC/DataReceiver.cpp:46

That last stack trace got me to think how could it be possible for an otherwise working program to coredump while creating an stdlib object. I mean, stdlib is quite well tested, isn’t it? Then it struck me: the keyword isn’t stdlib but creating. It was allocating memory from the stack, upon entering the function.

Some more research later I found out that Solaris default thread size is about 1 mb, while in Ubuntu this thread is of about 8 mb. And I also noticed the buffer I was allocating for zlib was taking up space in… the stack.

If there’s something to learn from this story is that you should always know what goes in the stack: only small objects should live there, and you should always know the max stack depth a function could reach. Otherwise it may come back and bite you in the ass when you’re back from your vacations.

filed Posted under C++, Grumpy and the tags
save Apr-29-2010

Template metaprogramming III: Entering Pandemonium

If you are here and you have read the previous two parts then you are crazy. If you haven’t then go and read it, then never come back if you value your sanity at all. We saw last time an example of a factorial using template metaprogramming, now it’s time for something a little bit more fun. I was thinking on lists, but that’s a bit too much for starters: let’s do some more math. Now with fractions!

So, how would you express a fraction? The fun part, and you already know this, you have only types (*), there are no variables. Luckly static const int saves the day:

  1. template  struct Frak {
  2.         static const long Num = N;
  3.         static const long Den = D;
  4. };

Woo hoo… how boring, let’s do something on those Fraktions, so they don’t get bored… like multiplying:

  1. template  struct ScalarMultiplication {
  2.         static const long Num = N * X::Num;
  3.         static const long Den = N * X::Den;
  4. };

Well that does the job, I guess, but it’s ugly. Too ugly… why would we redefine a Fraction when we already have a great definition? Let’s try again:

  1. template  struct ScalarMultiplication {
  2.         typedef Frak result;
  3. };

OK, now you think I’m pulling your leg, but, promise, I’m not. This actually works, and it looks nice! Check out that sexy typedef: you can’t have variables, we said, so instead we return types. Frak is a type when binded to two concrete values, so Frak is a type too. Just typedef it to a result and be done with it.

How do we test if it worked? Easy:

  1. int main() {
  2.         typedef Frak< 2, 3 > Two_Thirds;
  3.         typedef ScalarMultiplication< 2, Two_Thirds >::result Four_Sixths;
  4.         std::cout << Four_Sixths::Num << "/" << Four_Sixths::Den << "\n";
  5. }

Nice! By now you should have learned how to return new types, which are the result types for template metaprogramming devices. You should have also learnt how to write a device which operates on another template device… congratulations, that’s metaprogramming. Next time, something a little bit more interesting.

(*) Boring theory rant: What do I mean you can’t have return values so you must use types instead? Let’s see: a variable or an attribute are both parts of an object. If I have a variable named height in a class named Person, then each person gets his own height. Even if the numeric value is the same there won’t be two shared height attributes. On the other hand static const vars are defining parts of classes, not objects; stupidity could be static const var of Person (only in this case we’d all be equally stupid… this is were the analogy falls apart, I’m sorry).

Knowing the difference between an object and a class defining characteristics, it is clear we can only use static const stuff – it’s nonsense talking about template-objects, it’s all about template classes.

filed Posted under C++, Templates and the tags
save Mar-23-2010

You know you’re a geek…

… when you try to log in to your homebanking account using admin:admin (*) (**)

(*) Alt take: a geek with weak passwords, yeah. My pin is 1234 and I’ll never change it.
(**) Replace homebanking with gmail, linkedin and $LATEST_NETWORKING_FAD and you’re most likely mental. (***)
(***) Replace mental with (*) to obtain a Moebious post.

/Delirious posting mode, deactivate!

filed Posted under WTF and the tags
save Nov-30-2009

Console Ninja

My latest presentation is now online: “Console ninja”. Spanish only, at least for now.

On a related note: I’m taking some time off, in a week or so I’ll be back to my (un)regular schedule.

filed Posted under My Articles and the tags
save Nov-2-2009

New talk on the way

I’m polishing my latest talk, “Ninja console” which will be made available to the public soon. More news to come.

filed Posted under Meta-post and the tags
save Oct-23-2009

Retrofitting unit tests for legacy code

Some time ago I saw a discussion at google test mailing list which made me ask myself how would I go about implementing TDD for a legacy codebase project, based from previous experiences. I came up with a list, open to discussion, which may be useful as a guideline for someone in this situation. punched_cards

Start with integration tests

Integration tests are ugly and won’t give you a lot of information about what went wrong when something does, but you have no chance of running real unit tests in non-injectable code.
Use the integration tests as a safenet to refactor the critical methods, those which will be changed the most during the projects lifetime, which leads me to the next point;

Test as you refactor (or implement new functionality)

If you plan to stop the business and write a kabillion tests for your legacy codebase you’re out of luck. Not only you’ll fail because the lack of value but you’ll spend weeks writing tests and never see the ROI – you’ll quickly grow tired.
With integration tests in place take your time to write real unit tests as needed, that is when you implement new functionality or when you plan to refactor something – which should be to implement new functionality or to fix a bug.

KISS

kiss2 Can’t stress this enough: keep your tests simple. You’ll notice you end up with 80% boilerplate code, setting up mocks, creating test objects, etc. When that test fails you’ll have no clue why was it there in the first place.
This happens a lot with legacy codebases, where stagnant code tends to get quite coupled and messy. If you plan to write a big mega test to cover every use case with a single test, the day it fail you’ll quickly know it’s not production ready but you’ll have no clue why is that.

Mock layers

If you have a project divided in components (even the ugliest legacy code tends have some sort of layers separation, even if coupled with other components) try to create mocks for a whole layer of the application (I ended up with a complete mock of a DB, for example). This will help you in the long run to isolate troublesome modules. layers

Have a team commitment

If you’re working on your own or with a team, make it mandatory to run the tests for each commit. Even better if you can implement a continuous integration server.

filed Posted under Programming and the tags
save Sep-28-2009

CM WTF

Seen on a cablemodem’s configuration page:

  1. <form action="http:/loginData.htm" method="GET">
Long version: The other day, while stranded on a CLI (using ssh) I did a wget $IP, to see a modem’s status web page. I’d have thought an electronic device (which, obviously, is much more difficult to upgrade than a software product, and that’s difficult enough as it is) is a little bit better tested than that. I should have known better by now. comcast_cablemodem
filed Posted under Uncategorized and the tags
save Aug-18-2009

C++ oddities: Self initialization

I get it, C++ is a complex language, but man, I’d like a little warning (lol) when this happens:

  1. class Foo {
  2.   int bar;
  3.   Foo() : bar(bar) {}
  4. };
cpp

Yeah, it bit me in the ass the other day. Why? A method’s signature was awfully long, I wanted to delete a parameter and ended up deleting two. Luckly my unit tests where there to save the day, but regardless, WTF?

filed Posted under C++, Programming and the tags
save Jul-14-2009

GNU/Linux: Emergency Restart

It happens: we’re happily hacking on some code and out of nowhere X server freezes. It may be the latest Compiz whose at fault, or perhaps a stray program that decided it should start consuming all available CPU. Anyway, it’s easier to reboot than trying to fix whatever got broken but Ctrl – Alt – Backspace is unresponsive and we can’t drop to a console. It’s not ussual but it happens. What can we do about it? tuxcolgado

There’s a cool shortcut to help us when shit happens, it’ll reboot the computer and it’s a little bit nicer than yanking out the power cord. You just need to remember REISUB and have some keyboard dexitry – holding down Ctrl – Alt – SysRQ/PrintScreen is required while typing REISUB (don’t do it now, it’ll reboot your computer!).

So, what’s REISUB all about? It’s a little bit better than a forced hard reboot because it’ll:

R: Restore console
E: Send SIGTERM to all processes
I: Send SIGKILL to all processes
S: Emergency sync of all filesystems (commit any changes to the phisical media)
U: Read only remount of all filesystems
B: Reboot now

So, off course, you’ll have to wait a little bit between every keystroke. Press Ctrl + Alt + PrntScreen + H on a console to get some help on every command.

Why does it work?

There’s a lot of magic involved to make this secret incantation work. It involves kernels, vectors and other mythical beasts. There’s a crazy thing called interruption vector; it’s the place where every (hardware) event gets dispatched to a handling function. There lives a function call to handle keyboard input, amongst other things. This function call will be executed always, though the SO may just decide to queue the keyboard input if it’s too busy handling something else.

Well, this key combination can’t be delayed ’till later, it must be handled NOW, therefore, even if there’s a stray process or a driver gone mad, it’ll always be caught and the computer will be rebooted.
What’s the catch? You won’t be saving that precious code you we’re hacking away when it all started, but at least you’ll save some fscking time on the next start up.

filed Posted under Linux and the tags