Yesterday, I needed to get my server’s network information for a Bash script I was writing. Here are the commands so I don’t forget. They were tested using Fedora 12.
Get IP address:
ifconfig eth0 | awk '/inet / {print $2}' | awk -F: '{print $2}‘
Get MAC address:
ifconfig eth0 | awk '/HWaddr/ {print $5}'
Get network gateway IP address:
route -n | awk '/^0.0.0.0/ {print $2}'
Using the Tcpreplay tools to edit a Wireshark capture (*.pcap), I wanted to change the destination address to be multicast. I knew the IP multicast address I wanted (server IP address with the first octet changed to 239), but I had to change the MAC address also.
Here’s the mapping, taken from a Microsoft TechNet article:
To support IP multicasting, the Internet authorities have reserved the multicast address range of 01-00-5E-00-00-00 to 01-00-5E-7F-FF-FF for… media access control (MAC) addresses.
To map an IP multicast address to a MAC-layer multicast address, the low order 23 bits of the IP multicast address are mapped directly to the low order 23 bits in the MAC-layer multicast address. Because the first 4 bits of an IP multicast address are fixed according to the class D convention, there are 5 bits in the IP multicast address that do not map to the MAC-layer multicast address. Therefore, it is possible for a host to receive MAC-layer multicast packets for groups to which it does not belong. However, these packets are dropped by IP once the destination IP address is determined.
For example, the multicast address 224.192.16.1 becomes 01-00-5E-40-10-01.
Happy hacking!
FFMpeg provides many powerful features for processing audio and video. One cool thing it can do is resample an audio stream. This allows you to convert, say, a 44.1kHz audio stream down to 8kHz, or up to 48kHz. What’s more, FFMpeg can do the conversion to any arbitrary sample rate. This allows you to do cool things like smoothly changing the audio playback speed over time (see sample code below).
There are many pages describing how to resample audio using the ffmpeg command line application, but what about doing resampling in your own program? To do that, you need to use the avcodec library (libavcodec.so on Linux and avcodec.dll on Windows).
- Include
avcodec.h - Call
avcodec_init()to initialize the FFMpeg library. - Create a resampling context using
av_resample_init()that describes how you want the resampling done. - Call
av_resample()to do the actual resampling on your audio buffer. - When you’re done with the resampling context, delete it with
av_resample_close(). - Finally, link your application against
avcodec,avutil, andzlib(it won’t work on Linux without this one).
Here it is in pseudocode:
#include "libavcodec/avcodec.h"
avcodec_init();
struct AVResampleContext* ctx = av_resample_init( ... );
av_resample( ctx, ... );
av_resample_close( ctx );
That’s it… seriously!
Sample Code (Linux):
Here’s a sample program I wrote that takes a raw 44.1kHz/16bit/mono audio file and plays it back using the pulseaudio API. The catch is that it allows you to specify a “skew” parameter which will cause the audio to dynamically speed up and slow down (via resampling). The amount of resampling is controlled by a sine wave, which is what drives the speed changes.
Download: resample.tar.bz
To unpack and build, type:
$ tar -xjvf resample.tar.bz
$ make
First, run the sample with no skew:
$ ./resample audio_16b_44k_mono_pcm_raw 0
Now, try it with a heavy skew:
$ ./resample audio_16b_44k_mono_pcm_raw -10000
When rendering graphics or video to the screen, it’s important to understand the display process; in particular, vertical sync (v-sync). A common problem when starting out is an issue called “tearing”… where the video appears to be torn horizontally down the middle (see picture). I’ve been looking for a good explanation to share about why video tearing occurs and how to solve it (from a technical perspective). I found the following thread over at [H]ard|Forum, which I think does a pretty good job.
For the thread “How VSync works, and why people loathe it“:
There is a technique called triple-buffering that solves this VSync problem. Lets go back to our 50FPS, 75Hz example. Frame 1 is in the frame buffer, and 2/3 of frame 2 are drawn in the back buffer. The refresh happens and frame 1 is grabbed for the first time. The last third of frame 2 are drawn in the back buffer, and the first third of frame 3 is drawn in the second back buffer (hence the term triple-buffering). The refresh happens, frame 1 is grabbed for the second time, and frame 2 is copied into the frame buffer and the first part of frame 3 into the back buffer. The last 2/3 of frame 3 are drawn in the back buffer, the refresh happens, frame 2 is grabbed for the first time, and frame 3 is copied to the frame buffer. The process starts over. This time we still got 2 frames, but in only 3 refresh cycles. That’s 2/3 of the refresh rate, which is 50FPS, exactly what we would have gotten without it. Triple-buffering essentially gives the video card someplace to keep doing work while it waits to transfer the back buffer to the frame buffer, so it doesn’t have to waste time. Unfortunately, triple-buffering isn’t available in every game, and in fact it isn’t too common. It also can cost a little performance to utilize, as it requires extra VRAM for the buffers, and time spent copying all of them around. However, triplebuffered VSync really is the key to the best experience as you eliminate tearing without the downsides of normal VSync (unless you consider the fact that your FPS is capped a downside… which is silly because you can’t see an FPS higher than your refresh anyway).
If the thread is ever unavailable, you can download a PDF version HERE.
ThreadNinja is a Linux library my team created that tracks pthread_create() and pthread_join() calls in an application. It prints a stacktrace where each thread is created and where it is joined. Any rogue (unjoined) threads are reported when the application exits. ThreadNinja is unobtrusive: it does NOT have to be compiled into the code. This means you can use it on applications you didn’t compile.
We found it useful and thought we’d share it. It’s be no means production code… just a tool. Hack on it, expand it, change it… whatever. It’s pretty small, so it should be easy to dive right in. We’ve released it under the BSD license.
Cut To The Chase
You can checkout the source code from Google Code, or download the version 1.0 tarball directly (threadninja.tar.gz).
To build ThreadNinja, simply untar it and call make:
> tar -zxf threadninja.tar.gz
> make
Now, simply use LD_PRELOAD to run the application:
> LD_PRELOAD=/path/to/threadninja/build/libthreadninja.so.1 TheApplication
If you don’t see function names in the stacktraces that are generated, then the application needs to be compiled with debug symbols. For my test app, I had to compile with the -rdynamic option:
> g++ -Wall -rdynamic main.cpp -lpthread
This causes the global symbol table to be included in the executable, which contains all the application’s function names. For more info, look at the --export-dynamic option on the GNU linker (ld) man page.
The Story Behind ThreadNinja
My team was assigned to stabilize a large video application that runs as a Linux-based appliance. The application consisted of 100,000+ of lines to code that was a tangle of build warnings, circular references, and many creative hacks. Our particular task was to fix a persistent set of seg-faults and memory leaks.
Continue reading »
High-performance timing is hard… no doubt about it. I can’t tell you how many times I’ve seen high-performance timing code done wrong. Timing is one of those things where a little knowledge can be problematic; the code may work, but it either won’t perform or will exhibit “unexplained” behavior. The purpose of this post is to explain a foundational component to getting timing right: the clock. I won’t focus on theory… this post is meant to be pragmatic.
Note: I’m talking here about interval timing (i.e. accurately measuring the duration between 2 events). This is different than synchronizing different clocks or maintaining accurate wall time.
Anatomy of the Clock
The first mistake most people make when doing timing is to use functions like gettimeofday(), GetSystemTime(), etc. These functions return what is called “wall time”… time that corresponds to a calendar date/time. These clocks suffer from the follow limitations:
- They have a low resolution: “High-performance” timing, by my definition, requires clock resolutions into the microseconds or better.
- They can jump forwards and backwards in time: Computer clocks all tick at slightly different rates, which causes the time to drift. Most systems have NTP enabled which periodically adjusts the system clock to keep them in sync with “actual” time. The adjustment can cause the clock to suddenly jump forward (artificially inflating your timing numbers) or jump backwards (causing your timing calculations to go negative or hugely positive).
For interval timing, all that’s needed for a clock is a simple counter that increments at a stable rate. For high-performance timing, the rate this counter increments should be high. A related constraint is that the counter must be monotonic (can never “tick” backwards… ever). The counter may overflow and wrap back to 0, but using unsigned math in your timing calculations can compensate for that (see example below).
Something to note: since we are usually measuring short durations, the drift of the clock is so small that we aren’t concerned by it (what matters is the drift between successive reads, not total drift over time).
Continue reading »
In C/C++, macros that take a variable number of arguments (called variadic macros) can be very useful. Having printf-style macros just makes certain things easier to read and understand. Below I’ll describe how to do this in a way that works on Windows and Linux, as well as supports empty argument lists.
Example
Consider the following log method:
void WriteLog( const LOG_LEVEL level, const char* file, const int line, const char* format, ... );
Pretty straight-forward: it allows you to specify the log level (NOTICE, WARNING, ERROR, etc), a file name and line number, and a user-defined description in “printf” format. To log a warning message, you would type:
WriteLog( LL_WARNING, __FILE__, __LINE__, "[WARNING] Failed to import descriptor '%s:%i'!", _descriptor, _id );
The entry in the log file would look like:
Core.cpp:715 [WARNING] Failed to import descriptor 'timing-engine'!
Creating a Variadic Macro
Calling WriteLog directly works fine, but it’s pretty verbose and annoying to use. One way to make it simpler is to wrap WriteLog with a variadic macro:
#define LOG_WARNING( format, ... ) \\
WriteLog( LL_WARNING, __FILE__, __LINE__, "[WARNING] " format, ##__VA_ARGS__ );
Then the example above would become:
LOG_WARNING( "Failed to import descriptor '%s:%i'!", _descriptor, _id );
The macro automatically fills in the file and line number where the log message was generated, and the log level is specified by the macro name (LOG_WARNING). This is much more straight-forward and I believe it makes the code easier to read.
Notice that __VA_ARGS__ is used to get the variable argument list and pass it to WriteLog. During compilation, the preprocessor replaces __VA_ARGS__ with the comma-separated list of arguments. The ‘##‘ that prefixes __VA_ARGS__ is vital if you want your macro to work like you expect. Without it, you would be required to have at least one argument after the format string. ’##‘ has a special meaning in this case: it causes the preceding comma to be deleted if there are no variable arguments. Without this, the following line would generate a syntax error:
LOG_WARNING( "This would cause a syntax error" );
Prefixing __VA_ARGS__ with ‘##‘ allows the above code to work just fine.
We ran into a weird problem the other day where our Linux video display appliance would lose audio support when the process was restarted. The audio was supposed to play through a custom joystick-keyboard that was attached via USB (the keyboard is used by security guards to PTZ cameras, control monitors, etc). The audio could be heard just fine when the box first booted, but if the application restarted audio would be lost.
Looking at the logs, we found that our audio pipeline was failing to open /dev/dsp on the restart. We then used lsof to list the open file descriptors to see which process currently held /dev/dsp:
# lsof | grep /dev/dsp
ntpd 18857 root 16u CHR 14,3 180099 /dev/dsp
What!?!?… why the heck is NTP opening the sound device and how did it steal it from us??? After some discussion we started remembering a problem in the past with ntpd stealing our SNMP diagnostics port. This just didn’t make any sense.
Digging into our appliance code, we found this line:
system( "service ntpd restart" );
This would be called each time we were notified by the security system that the NTP server address had changed (which fired once each time the process was started so we could get the initial address). But this still didn’t explain why NTP took over ownership of our file descriptors on restart.
Long story short: system() is implemented as fork() followed by execv(). By default, fork() gives a copy of the parent’s file descriptors to the child process (i.e. the ntpd child process got a copy of the /dev/dsp file descriptor). To prevent this, you have to set the FD_CLOEXEC flag on the file desciptors you don’t want copied.
For example:
fd = open( "/dev/dsp", O_RDWR );
fcntl( fd, F_SETFD, FD_CLOEXEC );
Conclusion: setting the FD_CLOEXEC flag on the /dev/dsp file descriptor fixed the problem for audio. However, most of the other file desciptors still got owned by ntpd. Did we go back and set the FD_CLOEXEC flag on all file descriptors, you ask? Nope. It turns out we had a script monitoring the NTP config file and restarting ntpd for us when the file got updated… we just had to update the config file and remove the system( "service ntpd restart" ) call.
Oh, and the reason audio worked on first boot but not subsequent restarts was due to a weird race condition around when /dev/dsp got opened.
Having printf-style functions is very useful. I find myself periodically having to remember how to write variable argument functions, so I decided to just blog about it.
#include <stdarg.h> // or <cstdarg>
// Hide annoying naming differences between Windows and other platforms
#ifdef WIN32
#define my_vsnprintf _vsnprintf
#else
#define my_vsnprintf vsnprintf
#endif
// The function
void Foo( const char* format, ... )
{
// Parse the argument list
va_list args;
va_start( args, format );
// Calculate the final length of the formatted string
int len = my_vsnprintf( 0, 0, format, args );
// Allocate a buffer (including room for null termination)
char* target_string = new char[++len];
// Generate the formatted string
my_vsnprintf( target_string, len, format, args );
// <Do something with the formatted string>
// Clean up
delete [] target_buffer;
va_end( args );
}
Gotchas
We ran into a problem with vsnprintf() using the Denx Linux distro on a PowerPC processor: vsnprintf( 0, 0, format, args ) would modify the va_list, which would cause a crash on the second call to vsnprintf()… the one that does the actual formatting. The work-around is to make a temporary copy of the va_list when determining the formatted string length:
va_list args_copy;
va_copy( args_copy, args );
int len = my_vsnprintf( 0, 0, format, args );
va_end( args_copy );
After some digging, I finally found out how to create a regex for Sed (stream editor) that will find a line that does NOT contain a particular string. First, I used ‘find’ to list all the *.cpp files in my source tree:
find . -name “*.cpp” -print
Then I piped the files to ’sed’ via ‘xargs’ (Note: replace the ‘-e’ with ‘-i’ to actually modify the files inline):
find . -name “*.cpp” -print | xargs sed -e ‘/STRING_TO_INGORE/! { d }’
The trick is adding the ‘!’ (exclamation point) after the search expression. Without it, ’sed’ would think you only want lines with the string, not without it.
This is different than another syntax I’ve seen used: /(?!STRING_TO_IGNORE)/.
Here’s another example. Say you want to replace STRING1 with STRING2 only if the first characters of the line (ignoring white space) are NOT “//”… i.e. skip the string replacement in code comments:
sed -i ‘/^[ \t]*\/\/.*/! { s/STRING1/STRING2/ }’
NOTE: ‘[ \t]*’ means ignore 0 or more spaces or tabs.



