arch detail

arch detail

Friday, September 09, 2011

Better Emacs window switching

For years, I've hated the way emacs switches between windows with the next-window function (C-x o is the usual binding) - it operates as a cycle, which means that if you have 3 buffers open and you're doing editing in two of them, you always have to cycle through that last buffer (say, the one that holds compiler output) every time. This is irritating.

 Only today did I decide to find a better way. I found this: http://nex-3.com/posts/45-efficient-window-switching-in-emacs#comments

 (global-set-key [M-left] 'windmove-left)  
 (global-set-key [M-right] 'windmove-right)  
 (global-set-key [M-up] 'windmove-up) 
 (global-set-key [M-down] 'windmove-down)

Much better! Hold down your alt key and move around with your arrow keys. Nice! My ideal system would be to find a way to cycle through windows in order of last use, much like alt-tab works on most window managers. I'm not sure if this is possible in emacs, though; alt-tab works because you hold down the alt key and press tab as many times as you need. I don't think emacs supports that kind of key-press/key-release behavior, but maybe someone could prove me wrong?

Friday, September 02, 2011

Crazy C program

I don't know why I love this, but you can actually call main() from inside a C program! Or at least, with GCC 4.4.3 will let you. I wonder if other compilers allow this?

#include 


int main(int argc, char** argv) {
if (argc == 0) {
return 0;
}
else {
printf("%s\n", argv[0]);
main(argc - 1, &(argv[1]));
}
}


Compile it and try:

$ ./a.out a b c d

./a.out
a
b
c
d

Wednesday, November 17, 2010

C++ Iterators: Interesting bug

I've often heard it said that C++ lends itself to surprising and subtle bugs. I recently encountered an interesting (and simple) example myself.

I have a class foo which holds an iterable implemented with the STL (say, in this case, a std::set of ints); say this iterable is called myBar. So we give foo public member functions getBar() and setBar().

class foo {
public:
const std::set getBar() { return myBar; } const;
void setBar(std::set newIntSet) { myBar = newIntSet; };

private:
std::set myBar;
};


At one point, I wanted to iterate over myFoo.myBar, so I used the following:

std::set::const_iterator barIter;
for (barIter = myFoo.getBar().begin();
barIter != myFoo.getBar().end();
barIter++) {
Do work on barIter
}


This periodically produced some really horrible behavior. Do you see why?

It's because we call getBar() once when we start the "for" loop (barIter = myFoo.getBar().begin()) and get one copy of myFoo.myBar. At every successive iteration of the loop, we get another copy of myFoo.myBar, when checking for the termination condition: barIter != myFoo.getBar().end().

Amazingly, this didn't manifest right away with a seg fault or other conspicuous error. This is probably because for all STL iterators that I know of, .end() evaluates to NULL, so we could iterate barIter until it pointed at a 0 in memory, at which point the iteration would stop.

Surprisingly, on my program barIter would usually point at memory which held a copy of myBar. It wasn't until we had a non-trivial program that I found this bug; in fact, this broken program would often pass unit tests!

Overall, this was a boneheaded mistake on my part. Once I put on my C programmer cap and thought about what the compiler was doing, it was easy to see why this was wrong.

Overall, this experience strengthens my belief that one should never do C++ without doing a lot of low-level C programming first, and that C++ classes can hurt as much as they can help.

Saturday, November 06, 2010

Pulseaudio -> JACK2 on Ubuntu 10.04

So, I'm running Ubuntu 10.04 and decided I wanted to run PulseAudio into Jack. Turns out you can do this now! Hurrah!

First, Pulseaudio must be able to write to create a JACK sink. You can add that functionality with:

sudo apt-get install pulseaudio-module-jack


Oddly, this does not automatically enable the module in PulseAudio. So to get it auto-loaded into PulseAudio, I dutifully follow instructions HERE and I do the following:

I edit /etc/pulse/default.pa and change:

### Load audio drivers statically (it is probably better to not load
### these drivers manually, but instead use module-hal-detect --
### see below -- for doing this automatically)
#load-module module-alsa-sink
#load-module module-alsa-source device=hw:1,0
#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
#load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#load-module module-null-sink
#load-module module-pipe-sink

### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
load-module module-udev-detect
.else
### Alternatively use the static hardware detection module (for systems that
### lack udev support)
load-module module-detect
.endif


to:

### Load audio drivers statically (it is probably better to not load
### these drivers manually, but instead use module-hal-detect --
### see below -- for doing this automatically)
#load-module module-alsa-sink
#load-module module-alsa-source device=hw:1,0
#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
#load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#load-module module-null-sink
#load-module module-pipe-sink
load-module module-jack-source
load-module module-jack-sink

### Automatically load driver modules depending on the hardware available
#.ifexists module-udev-detect.so
#load-module module-udev-detect
#.else
### Alternatively use the static hardware detection module (for systems that
### lack udev support)
#load-module module-detect
#.endif


Of course, I also add back up my default.pa and add some comments in there announcing to myself when I changed it, why, and where the backup is. Tutorials should tell you to do that, but they never do, for some reason.

Next, I kill off pulse and restart it, which should force it to load the new modules:

 pulseaudio -k ; pulseaudio 


For some unholy reason Ubuntu is respawning pulseaudio if it is killed, so sometimes the above doesn't work; sometimes inbetween the "pulseaudio -k" to kill and "pulseaudio" to restart, the system reboots pulseaudio. I suck at Gnome and have no idea how to fix this but whatever.

At this point, I make sure JACK is running and use System -> Preferences -> PulseAudio Preferences (that's paprefs, you may need to install it) to make sure the JACK sink is my default output.

I then try opening Movie Player to test. Failure! I get a weird error from Movie Player and my terminal running PulseAudio now says:

W: module-jack-sink.c: JACK error >zombified - calling shutdown handler< 


Then it seg faults. Whoooo!

I do some Googling. It seems that there is a problem with the interface between PulseAudio and JACK but the PulseAudio folks claim that this is now stabilized in newer versions of JACK: "There was some breakage in this area in JACK a while ago. I assume that this problem does not exist anymore. If it does feel free to reopen."

So, it seems that the version of JACK shipping with Ubuntu 10.04 is not compatible with the version of PulseAudio and/or pulseaudio-module-jack. So it's time to install JACK2, the current version of which is (oddly) 1.9.6. You can download the source here.

I download and untar the file:

$ mkdir ~/builds
$ cd ~/builds
$ cp ~/Downloads/jack-1.9.6.tar.bz2
$ bunzip2 jack-1.9.6.tar.bz2
$ tar -xvf jack-1.9.6.tar
$ cd jack-1.9.6


I read the README file and discover I'll need the ALSA and Freebob headers, so:

apt-get install libasound2-dev libfreebob0-dev


Now I have to configure and build. The README instructs me to use ./waf, but they don't really warn me about the options I need on ./waf configure. I used ./waf configure --help and determined that we need --alsa to build with ALSA support and --freebob to configure with Freebob support. Also, since I'm a cautious dude and don't want to hose my system, I also specify --prefix=$HOME and when I install, I use "./waf install" instead of "sudo ./waf install" to get a per-user, locally-installed JACK2 rather than overwrite the old JACK which is installed by Ubuntu.

So in total, do this in the jack source directory you untarred:
 $ ./waf configure --prefix=$HOME --alsa --frebob
(Check that that goes okay.)
$ ./waf build
$ ./waf install


Done! Now you should have jackd in your ~/bin/ and libraries in your ~/lib.

You'll now need to set up your LD_LIBRARY_PATH to use ~/lib/ before the system libraries in /usr/, etc. so that the correct libjack is loaded; you may also wish to modify your PATH variable. For me:

$ echo 'LD_LIBRARY_PATH=$HOME/lib/:$LD_LIBRARY_PATH' >> ~/.bashrc
$ echo 'PATH=$HOME/bin:$PATH >> ~/.bashrc
$ source ~/.bashrc


This will mean that apps you launch from a terminal should now use the new JACK2, but Ubuntu's launch buttons don't seem to pick it up. I'm working on that.

Friday, March 20, 2009

/dev/random and /dev/urandom

This is likely common knowledge, but I hadn't possessed it before. I'd always wondered why sometimes something like
cat /dev/random > randomStuff

would be so oddly-behaved.

It's because /dev/random will block until there is sufficient data floating around in the system (keystrokes, network packets) for the OS to come up with something sufficiently random. /dev/urandom just degrades your random-ness in order to stay speedy. Cool.

Tuesday, March 03, 2009

/bin/false

Consult
man false
someday.

FALSE(1)                         User Commands                        FALSE(1)







NAME

false - do nothing, unsuccessfully



... that is all.

Monday, September 08, 2008

C++ Irritation

In C++ (compiled with g++), the following will use foo's copy constructor:


foo f;
foo g = f;


Whereas I had really imagined it would use the default constructor, followed by the operator= function if present.

In other news, I am working on interesting stuff but haven't spoken about it yet. See CIL, the C Intermediate Language for a really interesting approach to compiler IR: It uses (a subset of) C as an intermediate language for C.