Trusted Software Excellence across Desktop and Embedded
Take a glance at the areas of expertise where KDAB excels ranging from swift troubleshooting, ongoing consulting and training to multi-year, large-scale software development projects.
Find out why customers from innovative industries rely on our extensive expertise, including Medical, Biotech, Science, Renewable Energy, Transportation, Mobility, Aviation, Automation, Electronics, Agriculture and Defense.
High-quality Embedded Engineering across the Stack
To successfully develop an embedded device that meets your expectations regarding quality, budget and time to market, all parts of the project need to fit perfectly together.
Learn more about KDAB's expertise in embedded software development.
Where the capabilities of modern mobile devices or web browsers fall short, KDAB engineers help you expertly architect and build high-functioning desktop and workstation applications.
Extensible, Safety-compliant Software for the Medical Sector
Create intelligent, patient-focused medical software and devices and stay ahead with technology that adapts to your needs.
KDAB offers you expertise in developing a broad spectrum of clinical and home-healthcare devices, including but not limited to, internal imaging systems, robotic surgery devices, ventilators and non-invasive monitoring systems.
Building digital dashboards and cockpits with fluid animations and gesture-controlled touchscreens is a big challenge.
In over two decades of developing intricate UI solutions for cars, trucks, tractors, scooters, ships, airplanes and more, the KDAB team has gained market leading expertise in this realm.
Build on Advanced Expertise when creating Modern UIs
KDAB assists you in the creation of user-friendly interfaces designed specifically for industrial process control, manufacturing, and fabrication.
Our specialties encompass the custom design and development of HMIs, enabling product accessibility from embedded systems, remote desktops, and mobile devices on the move.
Legacy software is a growing but often ignored problem across all industries. KDAB helps you elevate your aging code base to meet the dynamic needs of the future.
Whether you want to migrate from an old to a modern GUI toolkit, update to a more recent version, or modernize your code base, you can rely on over 25 years of modernization experience.
KDAB offers a wide range of services to address your software needs including consulting, development, workshops and training tailored to your requirements.
Our expertise spans cross-platform desktop, embedded and 3D application development, using the proven technologies for the job.
When working with KDAB, the first-ever Qt consultancy, you benefit from a deep understanding of Qt internals, that allows us to provide effective solutions, irrespective of the depth or scale of your Qt project.
Qt Services include developing applications, building runtimes, mixing native and web technologies, solving performance issues, and porting problems.
KDAB helps create commercial, scientific or industrial desktop applications from scratch, or update its code or framework to benefit from modern features.
Discover clean, efficient solutions that precisely meet your requirements.
Boost your team's programming skills with in-depth, constantly updated, hands-on training courses delivered by active software engineers who love to teach and share their knowledge.
Our courses cover Modern C++, Qt/QML, Rust, 3D programming, Debugging, Profiling and more.
The collective expertise of KDAB's engineering team is at your disposal to help you choose the software stack for your project or master domain-specific challenges.
Our particular focus is on software technologies you use for cross-platform applications or for embedded devices.
Since 1999, KDAB has been the largest independent Qt consultancy worldwide and today is a Qt Platinum partner. Our experts can help you with any aspect of software development with Qt and QML.
KDAB specializes in Modern C++ development, with a focus on desktop applications, GUI, embedded software, and operating systems.
Our experts are industry-recognized contributors and trainers, leveraging C++'s power and relevance across these domains to deliver high-quality software solutions.
KDAB can guide you incorporating Rust into your project, from as overlapping element to your existing C++ codebase to a complete replacement of your legacy code.
Unique Expertise for Desktop and Embedded Platforms
Whether you are using Linux, Windows, MacOS, Android, iOS or real-time OS, KDAB helps you create performance optimized applications on your preferred platform.
If you are planning to create projects with Slint, a lightweight alternative to standard GUI frameworks especially on low-end hardware, you can rely on the expertise of KDAB being one of the earliest adopters and official service partner of Slint.
KDAB has deep expertise in embedded systems, which coupled with Flutter proficiency, allows us to provide comprehensive support throughout the software development lifecycle.
Our engineers are constantly contributing to the Flutter ecosystem, for example by developing flutter-pi, one of the most used embedders.
KDAB invests significant time in exploring new software technologies to maintain its position as software authority. Benefit from this research and incorporate it eventually into your own project.
Start here to browse infos on the KDAB website(s) and take advantage of useful developer resources like blogs, publications and videos about Qt, C++, Rust, 3D technologies like OpenGL and Vulkan, the KDAB developer tools and more.
The KDAB Youtube channel has become a go-to source for developers looking for high-quality tutorial and information material around software development with Qt/QML, C++, Rust and other technologies.
Click to navigate the all KDAB videos directly on this website.
In over 25 years KDAB has served hundreds of customers from various industries, many of them having become long-term customers who value our unique expertise and dedication.
Learn more about KDAB as a company, understand why we are considered a trusted partner by many and explore project examples in which we have proven to be the right supplier.
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications.
Read more about the history, the values, the team and the founder of the company.
When working with KDAB you can expect quality software and the desired business outcomes thanks to decades of experience gathered in hundreds of projects of different sizes in various industries.
Have a look at selected examples where KDAB has helped customers to succeed with their projects.
KDAB is committed to developing high-quality and high-performance software, and helping other developers deliver to the same high standards.
We create software with pride to improve your engineering and your business, making your products more resilient and maintainable with better performance.
KDAB has been the first certified Qt consulting and software development company in the world, and continues to deliver quality processes that meet or exceed the highest expectations.
In KDAB we value practical software development experience and skills higher than academic degrees. We strive to ensure equal treatment of all our employees regardless of age, ethnicity, gender, sexual orientation, nationality.
Interested? Read more about working at KDAB and how to apply for a job in software engineering or business administration.
In this blog on debugging and profiling, I would like to give you an overview of the debugging tools that exist for C and C++ applications.
Automated Testing
The first thing you need to do is make sure your code is properly tested. This, in itself, is not debugging, but it enables you to make sure that you don't introduce three new bugs when you fix one. One of the ideas that you can use for this is called Test-Driven-Development, which means writing the tests before you write the code that it will test. This way, you can make sure the test is testing the right thing. If the test fails, you fix it, and then it passes. It's a very good idea to add full unit test coverage for classes you're going to rewrite or refactor, so that you don't introduce regressions compared to the old code. To do this, you can use one of the existing unit test frameworks. As a Qt developer, I know especially QTestLib. But you can also use Google Test or Catch and there are actually many others. The goals of those is to save you time because you don't have to set up everything so you can write a test, make sure that all the test methods are called, how to handle failures, and all of that.
One step further is to integrate these tests with your continuous integration so that, after every commit or every night, you get a full build from scratch and a full run of all of the unit tests. All of this improves the quality of your application and is very necessary for the actual debugging that we are going to talk about because you'll make sure you don't introduce regressions when actually fixing a bug.
Code Coverage Tools
Another thing that is quite related to unit testing is code coverage. You want to make sure that you have a sufficient number of unit tests, and that they cover an important percentage of your code. Note however that it's usually pointless to try to go to 100% coverage. What's important is to test the parts of the application that are critical to you. That could be simple utility classes that are used everywhere, like the string class or the vector class if you have one of those. Or it can be the part of the application where the actual business logic is and you don't want any bugs in it. One thing you can do to find out if your unit tests cover enough of the important code is set up code coverage.
There are tools that will tell you 90% of these files have been covered by unit tests and you can then figure out exactly which part of the code you're missing in your tests. There are many tools for doing that. The most well known of them is gcov on Linux. It actually goes together with the compilers GCC and Clang, since those generate the information for gcov, when passing the --coverage compiler flag. There are also tools on Windows as part of Visual Studio, or you can install OpenCppCoverage. Also, Squish Coco is another one. All of these tools allow you to measure how much of your code is actually tested by your unit tests. This is an area where there are many, many concurrent solutions because it's something that's very much used in some domains, for instance anything that will fly in a plane has to be very well unit tested and covered by those tests. These are domains where code coverage is really important.
Static Code Analysis Tools
Another thing you can do to improve the quality of your code is set up static code analysis. This is another area with many different tools. The goal is to have bug detection without even running the application, simply having a tool that looks at the code and tells you where there's a construct or pattern that might have a bug. It's then up to a developer to look into it. These days, the most well-known tools for this are actually the compilers themselves. If you enable sufficient amounts of warnings in GCC and Clang, or Visual Studio, you will get feedback from your compiler about what you can improve in your code. So my recommendation would be to enable as many of those warnings as you can in order to detect as many problems as possible. Also, use more compilers than just one. If you can use two or three, that's better because you will get different feedback from the compilers. Then, there are some additional tools that you can use.
A well-known one is clang-tidy, which comes with many checks for C++ code, some of which even come with automatic fixing of the code. Using the same clang-based libraries, a KDAB developer, Sérgio Martins, wrote a plugin for Clang called Clazy, which allows the detection of common coding errors, especially when using Qt but also in general C++ applications.
Then, there are many more specialized tools, like Coverity, PVS-Studio, and so many others. It's quite interesting to look at, for instance, what PVS-Studio can find by reading their blogs. They have lots of interesting finds in open source applications, for instance. It's quite educational. This is also something that you can set up as part of your continuous integration so you get regular feedback on what can be improved in your code.
Logging (debug messages)
Let's talk about things that look a little bit more like what you would expect in terms of debugging. The most well-known debugging technique would be printf or equivalent: some logging of messages for figuring out into which function we're going into, what is the value of this variable, and so on. So, there are many variants to this: obviously, the ones that are part of C and C++, like printf and cout, and all those that come with your framework, like qDebug in Qt, or additional libraries, like log4cxx, boost::log, log4cplus, easylogging++... One thing most of those have in common is that they make install to turn on and off whole sets of debugging statements. So, if you are debugging a parser you would only enable the parser set of messages or if you are debugging printing you would enable all of the messages that are about printing, and so on. This is a lot more practical than having 10,000 messages per second and then you have to figure this out, or having everything off by default and you need to comment what you need. This is a lot easier if you can just toggle a switch somewhere and get what you need.
Assertions
Now let's talk about assertions. These are, at runtime, a way to say "this will never happen". If it does happen, stop the application and let me debug why it happened. That is something you would use for logic errors. You'd think your program is done in a way that this can never happen. This is especially useful for preconditions, like this pointer shouldn't be known before passed to this function; or postconditions, like this function will never return a unit pointer; or invariants, things that shouldn't change while the function is being executed. But, of course, it's useful for many other things as well. You shouldn't use it for runtime errors, like this file was not found. That is not really a logic error, it's more of a setup problem. You don't want to abort your application just because the user misplaced a file.
Another kind of assertion is the static assertion. Those are part of the compilation step. The compiler will tell you that a check failed, so you have to look into it. For instance, you would use this for an enum with the wrong amount of values, for inconsistent read only data, for inheritance that isn't as we expected, for unsupported CPU architecture, and so on.
Tracing
Let's talk about tracing. One of the things you can do is investigate which dynamic libraries are being used by your application. That's something you would do by using tools like ldd on Linux, Dependencies.exe on Windows, or otool on MacOS. This will simply list the shared libraries that are used by your application because possibly you are not using the one you thought and this could be the reason for the bug.
At runtime you can also figure out what your application is doing, as a black box. From the outside, you ask the application to show you all the files it's opening. That's something you can do with strace or the equivalent tools on other operating systems. You can ask it to show you any time it's going to (attempt to) open a file, use a socket or anything else that goes through a system call. It's a common debugging technique when you don't actually have the source code for your application, but it's also very useful if you do.
Debuggers
Then we have the very well-known debuggers, like gdb on Linux, lldb on MacOS, cdb on Windows, which allows you to do step-by-step debugging in your application. What you might not know is that there's another debugger called RR, which allows you to go backwards and forwards in your application. Isn't that amazing?
The way it works is you record the run of your application, hopefully triggering the bug you're after. Then, when you replay that recording (in gdb, launched by RR), you can go backwards and forwards and skip ahead, skip backwards, and so on. You can navigate through the recorded run of your application any way you like. That is extremely useful when you would usually hit that problem with gdb where you think the value is wrong and wonder how it's calculated and need to go back in time to find out. You can't do that because you don't have a time machine (at least I don't). But RR has the full recording and can go back because it has recorded all of the information to be able to do that. So, that's a very worthy tool to look into.
KDAB's GammaRay
For those of you doing Qt development, I want to tell you about a tool that was developed by KDAB, called GammaRay. It's free and open source, you can get it on github.
What it can do is introspect a Qt application, which means look into it and tell you all of the QObjects that are present, show you all the QWidgets graphically, same for all the QML elements in the scene, and all of the 3D elements in the Qt 3D scene, and so on, and so on. It has a large number of modules where you can get all of that information and know more about your application. It's not a debugger, per se. It's not going to go step-by-step in your code. This is much more like getting an overview of your Qt application and everything that it has created, and it's a way to debug problems like why a widget isn't big enough. Is the minimum size wrong? Is the size policy wrong? You can get information about all of these properties from GammaRay. It even supports remote debugging if you're doing embedded development and it supports attaching to a running application, which is also quite interesting.
Valgrind
Now let me tell you about Valgrind. This is a tool that is especially known on Linux. It also works on MacOS.
It will run your application in a very slow way. It takes its time, but it will look at what your application is doing, once compiled right. It's running on the binary. It will tell you things like you are using memory after you deleted it -- that's very bad -- or you are using this bit of memory without initializing it, and all of these kinds of errors. So that's quite useful when you have behavior that doesn't seem to be reproducible. You run the application again and get a different result. That's the type of bug where Valgrind really shines because it will tell you exactly where this source of invalid memory usage comes from. It has other tools besides this one. It has helgrind for race conditions. It has massif for memory usage and it has callgrind for profiling. For these three things, there are alternatives listed in this blog that end up actually being better. But the default tool, memcheck, is very, very useful.
Sanitizers
Finally, let's talk about sanitizers. This is another way to detect problems like the use of invalid memory or debug deletion. Instead of doing that with an outside tool, what we can do with sanitizers is actually ask the compiler to inject code into your own code that does all of these verifications. Any time your code is going to allocate memory, it will remember that. Any time your code will use an area of memory, it will first check that it's able to do so. This is extremely powerful. It's a lot faster than Valgrind. It is part of your compilers, if you're using GCC 4.9 (or later) or Clang 3.1 (or later) on Linux or if you're using Clang 6 (or later) or Visual Studio 2019 16.4 (or later) on Windows.
There are four types of sanitizers:
the address sanitizer will tell you about all of the memory usage issues
the leak sanitizer (included in the address sanitizer, but available separately) will tell you about memory leaks
the thread sanitizer is extremely good at telling you about race conditions in particular, which is something that's really hard to detect otherwise
There are some additional sanitizers being developed, such as the memory sanitizer to detect uninitialized memory, but this one requires recompiling all your libraries with it, so it's not really convenient.
This was a summary of all of the debugging tools that are available for C and C++ applications. If you'd like more details about any of these, we actually do full trainings on this so that you can learn more about using these tools, what they can do in practice, and then do some exercises to get used to them.
About KDAB
Trusted software excellence across embedded and desktop platforms
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications. In addition to being leading experts in Qt, C++ and 3D technologies for over two decades, KDAB provides deep expertise across the stack, including Linux, Rust and modern UI frameworks. With 100+ employees from 20 countries and offices in Sweden, Germany, USA, France and UK, we serve clients around the world.
Great blog. Very useful compilation (sic) of great tools. I did not know RR. I'll have a look quickly.
24 - Nov - 2022
Alois Kraus
Which tracing tools are you using for Windows? ETW?
24 - Nov - 2022
David Faure
Hello Alois. ETW is the most versatile utility on Windows and best suited for advanced users that have spent some time on Bruce Dawson to figure out how to tame its complexity. For simpler profiling, but also for deeper file/line level code annotation and more, we can also recommend using Intel VTune which is nowadays free of charge as part of the oneAPI offering from Intel. It even works on AMD CPUs to some degree thanks to integration with xperf underneath, just like ETW.
25 - Nov - 2022
Alois Kraus
Ahh ok thanks. I am doing quite a bit with ETW so I just wanted to check if I have missed great tool like rr. On Windows its counterpart would be ttt (Time Travel Trace) which is part of Windbg Preview. In theory it is great, but the performance impact for larger multi GB applications makes nearly unusable (speed hit x20 and you quickly will run into communication timeouts due to the slowdown). I have written some post which should make profiling on Windows with ETW significantly easier: https://aloiskraus.wordpress.com/2022/07/25/pdd-profiler-driven-development/. Especially for automated regression tests this approach has proven to be very successful.
20 - Dec - 2022
Damian Dixon
I would recommend cppcheck for a C++ static analysis tool.
David Faure
Senior Software Engineer
Senior software engineer and Managing Director of KDAB’s French office, David is a Qt user since its beginning. He has made numerous contributions to Qt, including new classes for QtCore in Qt 5. David is well known in the KDE project for his work on the web browser and especially on KDE Frameworks. He has become a specialist in multithreading with Qt, as well as performance optimizations. David holds an MSc in Computer Science.
Our hands-on Modern C++ training courses are designed to quickly familiarize newcomers with the language. They also update professional C++ developers on the latest changes in the language and standard library introduced in recent C++ editions.
5 Comments
21 - Oct - 2022
Kleag
Great blog. Very useful compilation (sic) of great tools. I did not know RR. I'll have a look quickly.
24 - Nov - 2022
Alois Kraus
Which tracing tools are you using for Windows? ETW?
24 - Nov - 2022
David Faure
Hello Alois. ETW is the most versatile utility on Windows and best suited for advanced users that have spent some time on Bruce Dawson to figure out how to tame its complexity. For simpler profiling, but also for deeper file/line level code annotation and more, we can also recommend using Intel VTune which is nowadays free of charge as part of the oneAPI offering from Intel. It even works on AMD CPUs to some degree thanks to integration with xperf underneath, just like ETW.
25 - Nov - 2022
Alois Kraus
Ahh ok thanks. I am doing quite a bit with ETW so I just wanted to check if I have missed great tool like rr. On Windows its counterpart would be ttt (Time Travel Trace) which is part of Windbg Preview. In theory it is great, but the performance impact for larger multi GB applications makes nearly unusable (speed hit x20 and you quickly will run into communication timeouts due to the slowdown). I have written some post which should make profiling on Windows with ETW significantly easier: https://aloiskraus.wordpress.com/2022/07/25/pdd-profiler-driven-development/. Especially for automated regression tests this approach has proven to be very successful.
20 - Dec - 2022
Damian Dixon
I would recommend cppcheck for a C++ static analysis tool.