Use gdb’s convenience functions

Today I tried to set a conditional breakpoint in my program when a string variable is assigned one specific value:

b foo.c:488 if (int)strcmp(foo, "foo") == 0

But unfortunately, the gdb will exit with following error:

Unable to restore previously selected frame:
Selected thread is running.
terminate called after throwing an instance of 'gdb_exception_error'
Aborted

After checking in stackoverflow, I found gdb‘s convenience functions. So using $_streq instead of strcmp:

b foo.c:488 if $_streq(foo, "foo")

The gdb works like a charm!

Use tshark to filter HTTP streams

Below is a screen shot of HTTP flows: GET request spans packet 4 and 5, while response is packet 9:

To filter HTTP stream, if use -Y http only:

$ tshark -nr tcp.pcap -Y http -w http.pcap

Only the last segment of GET request will be saved to file:

So -2 option is needed:

$ tshark -nr tcp.pcap -Y http -2 -w http.pcap

This time, the full GET request is saved:

An issue related to uninitialised memory

Today I met an interesting bug: A C program behaved differently between debug (gcc -O0) and release (gcc -O3) modes.

First of all, I compared the logs between two modes, and pinned down in which function, the logs began to diverge.

Secondly, I used gdb to debug two programs simultaneously, and checked the variables’ values, then found a variable which had disparate values that would cause two programs enter different branches in a if-else statement. Hmm, this was the root cause.

My gut feeling was the release mode program may fetch the staled value, but after reviewing code carefully, I found the reason is one block memory (the variable belonged to) allocated from heap was not initialised, so this will introduce notorious “undefined behaviour”.

As far as I know, the reasons for uninitialising variables:
(1) The programmer forgets;
(2) The programmer reckons the variable will be assigned correct value before use, and there may be performance penalty for initialising a block of memory.
Anyway, the lesson I learnt today is unless you are 100% sure it will be OK to uninitialise the specified variable, otherwise please initialise it, and this can save you several hours in the future.

Use DTrace on OmniOS

Using DTrace on OmniOS is not straightforward:

$ pfexec dtrace -n 'syscall:::'
dtrace: failed to initialize dtrace: DTrace device not available on system

Need to install both dtrace and dtrace/providers packages:

$ pfexec pkg install dtrace dtrace/providers

Now the DTrace module is loaded:

$ modinfo | grep dtrace
  5 fffffffff8243000  1af28 280   1  dtrace (Dynamic Tracing)

Then it will work!

P.S., Thanks for Andy Fiddaman‘s help!