At first glance, both the executables that a compiler produces, and the libraries that are used during the building process seem like they’re not very accessible. They are these black boxes that make an application go, or make the linker happy when you hand it the ‘right’ library file. There is also a lot to be said for not digging too deeply into either, as normally things will Just Work™ without having to bother with such additional details.
The thing is that both executables and libraries contain a lot of information that normally is just used by the OS, toolchain, debuggers and similar tools. Whether these files are in Windows PE format, old-school Linux
a.out or modern-day
.elf, when things go south during development, sometimes one has to break out the right tools to inspect them in order to make sense of what is happening.
This article will focus primarily on the Linux platform, though most of it also applies to BSD and MacOS, and to some extent Windows.
Continue reading “Peeking Inside Executables And Libraries To Make Debugging Easier”
What is the right time to optimize code? This is a very good question, which usually comes down to two answers. The first answer is to have a good design for the code to begin with, because ‘optimization’ does not mean ‘fixing bad design decisions’. The second answer is that it should happen after the application has been sufficiently debugged and its developers are at risk of getting bored.
There should also be a goal for the optimization, based on what makes sense for the application. Does it need to process data faster? Should it send less data over the network or to disk? Shouldn’t one really have a look at that memory usage? And just what is going on inside those CPU caches that makes performance sometimes drop off a cliff on a single core?
All of this and more can be analyzed using tools from the Valgrind suite, including Cachegrind, Callgrind, DHAT and Massif.
Keeping Those Cores Cool
Modern day processors are designed with low power usage in mind, regardless of whether they are aimed at servers, desktop systems or embedded applications. This essentially means that they are in a low power state when not doing any work (idle loop), with some CPUs and microcontrollers turning off power to parts of the chip which are not being used. Consequently, the more the processor has to do, the more power it will use and the hotter it will get.
Continue reading “Using Valgrind To Analyze Code For Bottlenecks Makes Faster, Less Power-Hungry Programs”
We all know what bugs in code are. We don’t like them when they are in programs we use, and they’re even worse when they are in code which we have written. Clearly, the best code is bug-free, but how do we get there?
This isn’t a new question, of course, just one that has become ever more important as the total number of lines of code (LoC) that run modern day society keeps increasing and which is affecting even hobbyists more and more often now that everything has a microcontroller inside.
Although many of us know the smug satisfaction of watching a full row of green result markers light up across the board after running the unit tests for a project, the painful reality is that you don’t know whether the code really is functionally correct until it runs in an environment that is akin to the production environment. Yet how can one test an application in this situation?
This is where tools like those contained in the Valgrind suite come into play, allowing us to profile, analyze and otherwise nitpick every single opcode and memory read or write. Let’s take a look, shall we?
Continue reading “Using Valgrind To Track Down Known And Unknown Bugs In Your Code”
If you use C or C++, you have probably learned how to open a file and read data from it. Usually, we read a character or a line at a time. At least, it seems that way. The reality is there are usually quite a number of buffers between you and the hard drive, so your request for a character might trigger a read for 2,048 characters and then your subsequent calls return from the buffer. There may even be layers of buffers feeding buffers.
A modern computer can do so much better than reading using things using old calls like
fgetc. Given that your program has a huge virtual address space and that your computer has a perfectly good memory management unit within it, you can ask the operating system to simply map the file into your memory space. Then you can treat it like any other array of characters and let the OS do the rest.
The operating system doesn’t necessarily read the entire file in at one time, it just reserves space for you. Any time you hit a page that isn’t in memory, the operating system grabs it for you invisibly. Pages that you don’t use very often may be discarded and reloaded later. Behind the scenes, the OS does a lot so you can work on very large files with no real effort. The call that does it all is
Continue reading “Linux Fu: Mapping Files”
As a budding automotive enthusiast, you finally took the plunge and scored yourself a sweet project car. After going through it from top to toe, you’ve done your basic maintenance and it’s now running like a top. Now you’re getting comfortable, you’ve set your sights on turning your humble ride into a corner carving machine. Here’s a guide to get yourself started.
It’s All About Grip
When it comes to creating a handling monster, the aim is to create a car that sticks to the road like glue, and is controllable when it does break loose. Having a car that handles predictably at the limit is a big help when you’re pushing hard on track, particularly for an inexperienced driver. And, whether you’re hitting the canyons on the weekend or trying to slash your laptimes, it’s always nice to have more grip. Through selecting the right parts and getting the set up right, it’s possible to hone your car’s cornering ability to make it a rewarding experience to drive fast and hard. Continue reading “How To Get Into Cars: Handling Mods”
One of the goals of programming languages back in the 1950s was to create a way to write assembly language concepts in an abstract, high-level manner. This would allow the same code to be used across the wildly different system architectures of that era and subsequent decades, requiring only a translator unit (compiler) that would transform the source code into the machine instructions for the target architecture.
Other languages, like BASIC, would use a runtime that provided an even more abstract view of the underlying hardware, yet at the cost of a lot of performance. Although the era of 8-bit home computers is long behind us, the topic of cross-platform development is still highly relevant today, whether one talks about desktop, embedded or server development. Or all of them at the same time.
Let’s take a look at the cross-platform landscape today, shall we?
Continue reading “Write Once, Run Everywhere: Cross-Platform Programming Done Right”
Most countries have dropped the requirement for learning Morse code to become a ham radio operator. Because of that, you might think Morse code is dead. But it isn’t. Some people like the nostalgia. Some like that you can build simple equipment to send and receive Morse code. Others like that Morse code is much more reliable than voice and some older digital modes. Regardless of the reason, many people want to learn Morse code and it is still a part of the ham radio scene. The code has a reputation of being hard to learn, but it turns out that is mostly because people haven’t been taught code in smart ways.
I don’t know if they still do, but some youth organizations used to promote some particularly bad ways to learn the code. The second worse way is to learn “dots and dashes” and many people did learn that way. The very worst way was using an image like the adjacent one to try to map the dots and dashes into letter shapes. This chart dates back to at least 1918 when a Girl Guides handbook printed it.
Even if you are a visual learner, this is a bad idea. The problem is, it is nearly impossible to hear sounds at 20 or 30 words per minute and map them to this visual representation. Another visual method is to use a binary tree where left branches are dots and right branches are dashes.
If you only need to master 5 words per minute to get a merit badge, you might get away with this. But for real use, 5 words a minute is very slow. For example, this sentence would take about 3 minutes to send at that speed. Just that one sentence.
So what are the better ways? Let’s take a look.
Continue reading “Learning Morse Code The Ludwig Koch Way”