When writing programs on Windows that involve I/O operations using the serial port, one quickly ends up loving Sysinternals Portmon.
I just found myself in a situation where I needed the exact same functionality, but on Linux.
What I found was jpnevulator.
It’s plain, simple, and if you’re on Debian or Ubuntu, just apt-get install jpnevulator and you’re good to go.
If you want to know what goes in and out over your serial port (in my case ttyUSB0), just use the tool like this:
hikari:~$ jpnevulator --read --ascii --tty /dev/ttyUSB0
76 3F 0D 56 20 20 20 31 31 31 20 20 34 30 30 2E v?.V 111 400.
30 30 20 20 37 32 30 2E 30 30 20 35 31 35 39 31 00 720.00 51591
0D .
On a side note:
You can use it to write data to a serial port, too.
Or monitor/write to several ports at the same time.
Quite a nice tool!
< hadez> i’m too far ahead of my time
< hadez> every time i figure that something is the most awesome way to
solve a problem in c++, the compiler doesn’t understand what i mean
< hadez> stupid thing
< hadez> :(
< josh-hill> hm.. what compiler is that then?
< hadez> MSCL
< hadez> :/
< hadez> or maybe the c++ standard
< hadez> i’m just being misunderstood
< josh-hill> and are you really sure it’s a “nice” way to program it?
< hadez> yes
< josh-hill> (if it doesn’t understand it)
< josh-hill> heh
< hadez> well
< hadez> no
< josh-hill> hehe.. odd
< hadez> it’s not nice
< hadez> it’s AWESOME
how everyone who did some programming on windows using MFC should know,
making dynamically re-sizable dialogs/views isn’t that easy a deal.
it’s far from the beauty of trolltech Qt or other frameworks.
basically it all comes down to catching ON_SIZE and overriding the OnSize() method.
sounds fair enough; but having to resize/move each single element of the dialog to fit the new framesize is just so much crappy, boring work.
thank god^W the coder in germany, i could use some of his older code that had a nice helper class that nicely fits in between CFormView and my own view.
all i had to do was subclass it, put two dummy elements as anchors into the view, register the elements that need resizing with the layout class, et voila it’s done.
the only thing that was done was a nasty exception, it was thrown right into my face, and it came from far, far down in the MFC abyss.
access violation when accessing memory at 0xbaadf00d.
right on!
as i know now, 0xbaadf00d stands for uninitialized heap memory.
it’s one of the usual suspects of debugging-defaults like 0xdeadbeef (deleted heap memory), 0xcd (uninitialized data byte), 0xfd (runtime heap data guard), and last but not least 0xdd (deleted data byte).
so far, so good.
i know what’s happening, i even know where it is happening (somewhere in CWin::MoveWindow(...)) but i had no clue why.
to understand the problem, one has to know the basics of the layout manager internals.
it keeps a std::list of the information of each registred element as a struct holding a pointer to the element’s CWin class, it’s initial dimensions, and a set of flags.
once OnSize() is called the layouter gets the new size of the window, calculates the delta to do the resizing of each element, checks if the element is anchored in some way, and finally does the resizing.
the resizing itself is done by dereferencing the pointer to the previously stored CWin class of the element and calling MoveWindow(...).
and there it is i’m getting the exception.
so i do what all desperate coders do, i set a breakpoint and step thru the code instruction by instruction, call by call.
i spent hours staring at parameters, variables, return values, and what not.
then i noticed that what’s getting set when registering a new element with the layouter and what’s getting returned from the std::list it’s being held in, kind of is not the same.
i replaced the container with a std::vector and used operator[](...) instead of the iterator to access it.
didn’t help.
then i noticed that instead of passing a pointer to the RECT struct (that holds the dimensions of the element) to GetWindowRect(...) the code was passing the struct member itself. duh.
fixed it, didn’t help.
then my attention was drawn to the struct member which holds the flags.
instead of a low value (something in the range of 0 to at most 32) it was set to a value of over 19000. how could that be, it’s a simple assignment.
imagine this:
void AddElement(CWin *element, int myFlags)
{ // [...]
// struct MyStruct {CWin *winp; RECT dimensions; int flags};
MyStruct foo;
foo.winp = element;
foo.flags = myFlags;
GetWindowRect(&(foo.dimensions));
mylist.push_back(foo); }
the debugger stepped right over the two assignments.
all hail to the microsofties!
i don’t know what it was, but the compiler refused to compile correct code.
even in debug mode.
the problem was solved quite fast using the lazy man’s define-and-assign:
MyStruct foo = {element, CRect(0,0,0,0), myFlags};
i’m still having the feeling that it was just the debugger trying to trick me…
fixed that problem, but i would still get the nasty exception throwing bad food in my face. yuck.
i finally noticed that once i get the elements from the list and dereference the pointer to the CWin class, i get the class with all it’s members, but a handful of them would be set to 0xbaadf00d.
i can’t remember how i got the following idea, but it got it while listening to dmnk doing his live show on jungletrain.net.
i modified the struct and the code to work on a window handle (HWND) instead of the pointer to the window class (CWin*).
believe it or not, but i’ve never really used the HWND before, so i fired up the context sensitive help and while digging around i found out that while the CWin class might cease to exist even during the lifetime of a window, the window handle would be there all the time. in short: the CWin class is just a convenience-wrapper around the handle. geez. i love MFC.
instead of just calling currentElement.winp->MoveWindow(...) i ended up with some more code:
CWin foo;
foo.Attach(currentElement.winh);
foo.MoveWindow(...)
foo.Detach()
and magically it worked!
i’ve been with the company for over two years now, and i think i’ve only found 1, at most 2 bugs in that coders code.
today i hit the nasty jackpot.
and in retrospect i have to say: stupid bug, nasty bug, and it took-me-way-too-long-to-find-it bug