Rants on software, computing, and any other topic I feel like.

Tuesday, October 11, 2011

Console Resolutions in Ubuntu

I recently (well, like a year ago) switched my personal server from Gentoo to Ubuntu server and have been generally pleased. However, when I tried putting the server in a closet and hooking up an old cheap LCD monitor to it, the text mode wouldn't come up right. It was all white and hard to read. I could figure out what was on the screen, but it was annoying every time I had to use the console for some reason or another. The problem was clearly that the wrong resolution or refresh rate or some other monitor setting was not being set correctly.

So I go online to find out how to switch the console resolution. Everything I can find talks about doing this by changing the kernel options. Great, I've done this before. I spent far too much time fiddling with vga=0xF00 on my old Matrox G400 trying to TV-Out to work. Just gotta figure out how to do it again.

No big deal right? Well, now Grub has exploded from a couple config files in /boot to several sets of config files in /etc and /boot. There's even a grub.d directory. I can see the Emacs syndrome coming on. It's just a bootloader folks. It doesn't need to be this complicated.

Anyway, I get this all figured out. Turns out that we don't use vga=791 or whatever anymore. That's deprecated. We now use set gfxpayload=640x480, but not on the kernel line. It goes somewhere in grub.conf. But we can't set it there because that gets overwritten by update-grub. Argh.

Oh! There's this file over here called /etc/default/grub that I change. But set gfxpayload isn't supported in that. /etc/default/grub looks like a bunch of environment variable definitions. Actually gfxpayload is supported, but it's not documented anywhere except in the bug report that added the feature. This is becoming not simple. It's called GRUB_GFXPAYLOAD_LINUX=640x480, by the way.

Ok, we're good now. Changed /etc/default/grub, ran update-grub. Reboot. Watching BIOS stuff, graphics card, IRQ list and Grub comes up. Yay! It's working. Alright, select the kernel and hit enter. We're booting. Uh oh, why is the mode changing again? Argh, it's still wrong. Apparently the mode change only works in Grub, then the kernel switches it to something else. Something defined in some config file I'm never going to find. Why are there so many posts about this if it only works in Grub? I don't really spend a lot of time in Grub. I'd think most folks would be ok if the display was a little glitchy in Grub. I'm missing something.

Should I post to a forum? No, I want to fix this now. If I don't fix it now, it'll just keep annoying me just enough to spend half an hour of my time trying to fix it every time I need to use the console, but then I'll give up and forget what I was trying to do in the first place. Then my wife will ask why it's taking me so long to fix that thing that I said would take five minutes. Uh, cause I'm not actually fixing that. I just say, "What was that? I couldn't hear you. Almost done dear!" I think she's on to me. She knows what this really means. I get on IRC.

Nice folks on #ubuntu, but not generally that helpful in certain situations. Nicer than the folks on #gentoo. I ask my question. Someone asks if I've done the obvious things. Yes, I've already done that. I almost decide to try to help some poor newbie with his problem. Nope, that will only delay things further. Tonight, guilt about being a better citizen doesn't make me do the right thing. Focus.

While in #ubuntu, someone posts something about completely unrelated, but pastes some part of their dmesg. Of course! Why do I always forget to check the logs? Checking dmesg. Uh, why is this "nouveau" thing changing my resolution to 640 by 350? 350? I don't think that's too standard. No wonder my cheap LCD is having issues. I'm surprised it's working at all. Now I'm on the right track.

Google "nouveau". Ok, this is better. Ahah! I just need to add some video=640x480 line to the kernel line. Good thing I now know about /etc/default/grub. Edit. update-grub. Reboot. Yay! It works.

Why are there fourteen different ways to deal with the console resolution settings? This is far more complicated than it should be. Now I remember why I could never get things working on my Matrox G400 just right. It's one of those terrible places where it's just too complicated, but no one is really using it. There are about two people in the world who know the answer to your question, and they don't get on IRC.

Why am I the one why gets the issues that no one else in web land ever gets?

Labels: , ,

Friday, May 06, 2011

Using malloc Safely in C++

For many of us C++ programmers, a key advantage of using the language is the compatibility with C. For the most part, this interface works well. However, there are some places where this interface isn't so easy to deal with. Take memory allocation for example. In C, one typically uses malloc (or some equivalent for the platform) to allocate memory and free to release it. In C++, we tend to use the built-in new and delete operators to accomplish the same thing.

When interacting with C libraries, it can sometimes be impossible to avoid using malloc and free. Libraries often assume that any memory that it allocates and hands off to the user will be freed using free. Since you can't tell what sort of memory a particular pointer points to, it's easy to make mistakes when deallocating them. Using mismatched allocators/deallocators might cause memory leaks, crash your program and work just fine depending the platform, compiler, or phases of the moon.

The first thought that any self respecting C++ programmer will think of is RAII (Resource Acquisition Is Initialization). So they might write a class that automatically calls free when the pointer is no longer needed.
template<typename T>
class malloc_handler
{
public:
malloc_handler() : _ptr(malloc(sizeof(T))) {}
~malloc_handler() { free(_ptr); }
T* ptr() { return _ptr; }
private:
T* _ptr;
};

void foo()
{
malloc_handler<int> x();
x.ptr();
}
This has a number of disadvantages including the lack of a copy constructor, the requirement of a new class and the lack of any convenient operator overloads to make it look more like a pointer. There's a much better way and one that doesn't require the programmer to roll their own solution. Use shared_ptr and its customer deleter feature.
shared_ptr<int> x((int*)malloc(sizeof(int)), free);
This feature is probably something that the creators of shared_ptr already envisioned, but I don't generally see it discussed. Now, the above code is a bit ugly, so we can make it a little bit easier by rolling our own code.
template<typename T>
shared_ptr<T> shared_malloc()
{
shared_ptr<T> rval((T*)malloc(sizeof(T)), free);
return rval;
}

shared_ptr<int> x = shared_malloc<int>();
We can create a safe version of strdup:
shared_ptr<char> shared_strdup(const char* str)
{
shared_ptr<char> rval(strdup(str), free);
return rval;
}

shared_ptr<char> s = shared_strdup("Hello World!\n");

Labels: , ,

Tuesday, February 22, 2011

Science and Religion

Recently the following article appeared over at Cosmic Variance, a blog I follow. Theologians Lobby Successfully to Change Definition of Evolution Some theologians (Cornell's Huston Smith and Notre Dame's Alvin Plantinga specifically) asked that the following definition of evolution used by the National Association of Biology Teachers be modified to remove the words "unsupervised" and "impersonal".

The diversity of life on earth is the result of evolution: an unsupervised, impersonal, unpredictable and natural process of temporal descent with genetic modification that is affected by natural selection, chance, historical contingencies and changing environments.

I think it's a good idea. I believe in science, I believe in religion and I believe in evolution. But I have a hard time understanding why it’s so important to some scientists to make sure that not only do we not mention God in science, but we must specifically reject him outright. I agree that there is no evidence that God is there. If there were evidence, then it would be pretty easy to believe in God. I’ll accept that. I don’t expect you to believe in God. But since there is also no evidence that he doesn’t exist, then I expect science to leave the topic alone. Let the Atheists discuss the absence of God. Science is about evidence, not belief.

I believe in science because I believe that science is a valid and useful way to discover things about the world. It’s been astoundingly successful at doing so. I don’t feel I can reject it, nor do I want to. I benefit from it every day.

I believe in religion because I believe that religion is a valid and useful way to discover things about the world. I believe that spiritual experiences are real and I can reconcile them with the things I learn from science. It may not be in the way that some scientists may think I should, but I do it all the same.

I believe in evolution because science has shown that there’s little chance that it happened any other way. I’m not going to reject the evidence that is clear as day. However, just like a scientist cannot reject “uncomfortable” evidence when it contradicts a pet theory, I cannot reject my spiritual experiences. They are as real to me as any evidence that science can provide. Are they perhaps nothing more than my brain being affected by too much dopamine? Perhaps. And I may reject them if sufficient evidence is presented to me. But sufficient evidence has not been presented to me. So, until that time, I must reconcile the evidence with which I am presented.

Just because I see some conflicts between science and religion doesn’t mean that I reject either one. General Relativity and Quantum Mechanics have conflicts. I don’t just blindly throw one out. They both have some of the truth. One day, we’ll understand how they fit together. I’m okay with some conflicts. I know they’ll be resolved eventually.

But I do expect you to state conclusions based on good evidence. There is no evidence that God didn’t have some small hand in the evolutionary process. Perhaps evolution is the mechanism by which he created a diverse ecosystem on this planet. That’s what the theologians are asking for. The National Association of Biology Teachers is overstating what science knows about evolution.

The words unsupervised and impersonal are quite problematic. “Unsupervised” implies the absence of some intelligence involved. Well, what is intelligence? Once humans showed up did evolution stop? We can discuss a number of situations where humans had a clear hand in the evolutionary process. What about other possibly intelligent animals? How much intelligence do you need before you’re a “supervisor”? And “impersonal”, which would mean that no person was involved. Well, since humans didn’t show up until pretty late in the game, that’s sorta obvious, but has the same problems as “unsupervised”.

I’m really getting tired of two things in the scientific community. One, the alliance with the atheists which some in science seem to think is the only way it can be. Science and religion can coexist peacefully you know. And two, the accusations of stupidity at anyone who doesn’t accept everything a scientist says without question. I understand you’ve studied your field in more depth than anyone else, but that doesn’t alleviate the need to explain your reasoning to those you’re speaking with.

When I have a scientific discussion, I don’t bring my religion into it since it’s irrelevant to everyone else. Some scientists are atheists and they should do the same. Scientific statements should be scientific. There’s no place for statements that God doesn't exist when there’s no evidence for that statement. If we want the world to accept evolution, then please stop overstating the case for it. The evidence is convincing enough without saying things we don’t really know.

"Is there any conflict between science and religion? There is no conflict in the mind of God, but often there is conflict in the minds of men." — Henry Eyring, developer of the Transition State Theory of Chemical Reactions

Labels: ,

Thursday, February 17, 2011

Calling a constructor or destructor without an object

Now, I have no idea why you'd actually want to call constructors or destructors without an object, since they're really normally meant to be called with objects, but it's something interesting I thought I'd share. It turns out that constructors and destructors aren't really that special in C++. They're just regular functions like almost anything else and can be called that way. You just need to know how to do it.

I'll start with destructors, which may seem backwards, but doing this with destructors is actually easier than with constructors. It's not that much easier, but it makes a bit more sense. Let's start by calling a destructor with an object. We'll get to the no-object case next.

To call a destructor if you have an object, well, just call it:


struct A {
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
};

void main()
{
A a;
a.~a(); // just call it like anything else
}


So how do we do this without an object? We need to think about what happens when any member function is called. When the compiler compiles a member function call, all it does differently from a normal function call is to add a pointer to the object as an extra parameter (at the begining) and call the function normally. Now certain compilers even use a different calling convention, but in the end, it's just a modified function call.

So can we get the compiler to make that function call, but not require a real object to pass in? Of course:


A* a = NULL;
a->~a();


or more compactly:


((A*)NULL)->~a();


Now, as long as nothing in the destructor actually tries to access the this pointer (by accessing data members for example), then all is well. The destructor is called and no object was ever created.

What is this useful for? I have no idea, but one thought that I had centered around one particularly special behavior of destructors. They automatically call the destructor of the parent class. Every other type of member function doesn't do this. Parent class versions of functions much be explicitly called. In some cases, this can be frustrating, especially in template classes where the parent class may be hard to determine.

In order to call a constructor without creating an object, we can use a special feature of C++ rarely seen outside of things like STL and embedded code, placement new. Placement new is just like new, except that it doesn't allocate memory for you. It leaves the memory allocation up to the programmer. Here's what it looks like normally.


void* ptr = malloc(sizeof(A));
A* a = new (ptr) A();


The syntax is a little funny, but that's okay. All we're doing there is calling the constructor member function using our own pointer (ptr) for the this pointer instead an automatically generated one.

So, using the same trick of using NULL instead of a valid pointer as we did with the destructors, we can do the same with constructors:


A* a = new ((void*) NULL) A();


Except it doesn't work. At least with gcc. The constructor never is called since the this pointer is NULL. Well, no worries, we're not trying to actually do anything with the this pointer, so we just need to pass in something that the compiler thinks is good.


A* a = new ((void*) 1) A();


Let's get rid of the assignment, since we're not going to use that pointer anyway.


new ((void*) 1) A();


And voila, we're calling constructors. No object needed.

One key point here that should be repeated is that none of this will work on destructors or constructors that actually try to dereference the this pointer in any way. The most obvious time this is done is when accessing data members. Another is calling virtual functions, since the virtual function table will need to be referenced. Also, any class hierarchy that includes virtual inheritance won't work since that mechanism uses the this pointer as part of knowing what destructor to call.

Labels: ,

Thursday, January 20, 2011

Emacs for Visual Studio users

Now that I'm using Linux to do all my development, I'm finding that a few things that I got used to in Visual Studio can be a little more difficult in emacs and a terminal. However, I'm finding that emacs generally has all the features I'm looking for and more if I take the time to learn them. Here are a few features I used in Visual Studio for which I've found equivalents in emacs.

Find in Files



"Find in Files" is a particularly useful feature in Visual Studio. For a while I was just using grep in a terminal and manually jumping to files it found. Slow and annoying. M-x find-grep is just what I was looking for. It would be nice if I could more easily tell it not to search everything and just *.cpp and *.h files for example.

M-x find-grep-dired puts the found files in a dired buffer (something I need to learn more about) and lets you do things like query-replace on a marked file. I haven't used this but it seems much more powerful than Visual Studio's system.

Debugging



Until I'm convinced otherwise, I still think that Visual Studio's debugger is the best in the business. Qt Creator comes close but the rest of the interface there isn't so hot. Emacs with gdb is surprisingly good and much better than the last time I tried using it a few years ago.

One problem is that I can't set or even enable a breakpoint while the program is running. Sometimes this is really useful as you have to run some code that will hit the breakpoint a lot before the one time you're interested in. Sometimes, it's really a matter of clicking "enable" at just the right time. Conditions help here, but sometimes it's just easier to enable when you need to.

Saving breakpoints was something I didn't think I could do, but the "save breakpoints" command seems to overcome that. Not as clean as Visual Studio, as I have to "source" the resulting file when I restart.

One command that has promise is rbreak, which I can use to set a breakpoint on all functions which match some regex. I couldn't get it to work however. It seems to find all the functions, but when it tries to set the breakpoints, it can't find them and asks if I want to delay setting them. Bug.

File Navigation



I like "C-x b", which allows you to load existing buffers quickly. I think there was something in Visual Studio that did this, but I never used it. If anything, I don't think it had tab completion, which emacs does.

Labels: ,

Thursday, January 13, 2011

iPhone on a virtual machine

Ever since I started my new job where I don't have to run Windows all the damn time, I haven't sync'ed my iPhone. So, when I tried to just back it up on Ubuntu, it totally messed up the iPod app. So I decided I wouldn't try that again. Anyway, now that VirtualBox supports USB passthrough, I figured it was time to try to get it working again. I created a Windows 7 virtual machine and installed iTunes, moved my library over, and started syncing. Some things that might make it easier on those trying to do this:

1. Make sure you're in the vboxusers group. Things worked for me without doing this, but I had problems, so just do it even if things work for you.

2. The iPhone occasionally will disconnect on certain types of operations and come up as a different device which won't get automatically captured by VirtualBox. iTunes then waits and waits for the iPhone, but never sees it so bad things happen. Watch for this and tell VirtualBox to capture the iPhone when it happens. I think the USB filter thing in VirtualBox helps here. This is especially important when updating to a new version of iOS. If you have problems, look up UDF mode.

Labels: ,

Tuesday, January 04, 2011

Switching on Boolean Conditions and Flags

I just posted an article over at CodeProject.com about what I call a boolean switch or switch flags (as the library I wrote is called). I've thought a lot about it over the years and implemented in a couple ways. It reduces the complexity of nested if statements. Basically, it allows for code like this:

switch_flags_2(a > b, c != d)
{
case flags_2(T,T):
// only execute when "a > b" and "c != d"
break;
case flags_2(F,X):
// execute when "a > b" is false
break;
}

Labels: , ,

This page is powered by Blogger. Isn't yours?