I found a nice blog entry that explains how to build static libraries and dependent projects with XCode. This is quite nice for iOS development, and relatively elegant. The only thing that bothers me is that the search path for headers has to be augmented manually. I wonder if there is a nice solution…
Month: February 2011
Controlling MPD with the iPhone
Alignment of double values on ARM architectures
Consider the following code:
class C {
...
uint8_t *data;
size_t size;
...
void writeDouble(double v)
{
...
reinterpret_cast<double*>(this->data)[this->size] = v;
this->size += sizeof(double);
...
}
};
Looks harmless enough, doesn’t it? But here is the problem: It’s not necessarily portable or well behaving code. After debugging for about three hours, I found out something interesting. Namely that on ARM platforms, such as the iPhone, double values on the stack need to be stored at 8 byte aligned memory addresses. This was some existing code I was using, so it took me a while to get to this function and to its problem. Single precision float values have no such restriction, by the way. There are two workarounds in the above case. 1) Write a small for-loop that casts the double value to a uint8_t * and copy the double value byte-wise, or 2) use malloc to copy the value. I did the for-loop, since I thought that maybe the malloc call has too much overhead. I guess you could also cast the double to a uint32_t * pointing to two 32 bit words. Anyway, take care when doing such drastic casts. Some platforms might want alignment for some datatypes!
Valgrind checking of iOS programs
Well, this is awesome news. First, valgrind has been available for OS X for some time now. And second, you can use it to check your iOS programs on the simulator with it.
The idea here is to let your program spawn valgrind itself. Because you cannot tell the simulator to run the program through valgrind. Well, maybe you could build a funky bundle, but I think this works just fine. So here is the code, taken from the above link:
#define VALGRIND "/usr/local/valgrind/bin/valgrind"
int main(int argc, char *argv[]) {
#ifdef VALGRIND_REXEC
/* Using the valgrind build config, rexec ourself
* in valgrind */
if (argc < 2 || (argc >= 2 && strcmp(argv[1], "-valgrind") != 0)) {
execl(VALGRIND, VALGRIND, "--leak-check=full", "--dsymutil=yes", argv[0], "-valgrind",
NULL);
}
#endif
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"PeepsAppDelegate");
[pool release];
return retVal;
}
You will obviously want to define the VALGRIND_REXEC macro, if you need valgrind output. You can also pass different command line arguments to valgrind. E.g. you can switch to different valgrind tools this way, or pipe everything to a log-file.
Update: I finally got around to trying out this method. One problem here is that valgrind will fail to run, since it tries to open /dev/random, which I guess is not allowed for sandboxed applications. But one can fix this by patching and recompiling valgrind, which is not too hard. Especially when using MacPorts. Furthermore, I needed to add –dsymutil=yes to the valgrind options, or else the program would just crash.
Conditionally rewriting mail subjects using exim4
Since MobileMe sadly does not support filtering using RegExps, and I get a lot of heterogenous system mails from our computer systems here, I implemented a workaround. I added some text like [System] to the subject, which can be filtered fine by MobileMe.
All of our machines here send their mail to a central smarthost running exim4. All the system mails are directed to “root” at some of our machines. What I did was first adding a file /etc/exim4/exim.filter containing this:
# Exim filter
if "$h_to:" matches Nroot@.*.your.domain.deN then
headers add "New-Subject: [System] $h_subject:"
headers remove subject
headers add "Subject: $h_new-subject:"
headers remove new-subject
endif
system_filter = /etc/exim4/exim.filter
After that I had to run update-exim4.conf and /etc/init.d/exim4 reload. Then I was all set up.