Selecting a tool for debugging
The IDE works with several third-party tools and contains its own features that help you debug improper program results, process hanging, or process crashing.
- Improper program results
- No fatal error occurs but the application doesn't do what's expected.
- Process hanging
- The application becomes unresponsive but continues running.
- Process crashing
- The application exits abruptly, without properly terminating its operations.
Guidelines on selecting a tool for each use case are given below.
The debugging capabilities of these tools are listed in Integrated tools
.
Improper program results
There are many IDE tools that can help you find logic errors in program code or memory corruption issues. Generally, you should first launch the application with the debugger attached and try to reproduce the bad behavior. If you can't reproduce it, you can wait until you next see the improper results, then attach the debugger to determine what state the program is in and how it got there. For multiprocess programs, you can debug a child process.
- If you think that data is being corrupted, run a memory-checking tool—Memory Analysis, Valgrind Helgrind, or Valgrind Memcheck. These tools identify runtime errors that are often related to memory corruption, such as reads of uninitialized or invalid memory.
- If you suspect there's a bad value coming from another process or there's an odd interaction between processes, use the System Profiler to see the system-level activity (e.g., kernel calls, interprocess messaging) on the target. To do so, you must first run a kernel event trace to capture this activity. The System Profiler then lets you view the trace data.
- If both these options fail to identify the cause, you must continue using the debugger. You can set more breakpoints to see which code paths are followed when the bad behavior happens.
Process hanging
When you observe an unresponsive application, the IDE can help you inspect the application's current state. This way, you can learn which processes are hanging without having to rerun the application and attempt to reproduce the problem.
The quickest way to start investigating a hanging process is to view the current target machine state through the QNX System Information perspective. Here, the System Resources view lists CPU usage by process, so you can see right away which processes are consuming excessive resources or no resources. You can see thread-level details in the Process Information view, including thread states.
- You can run a kernel event trace to capture the system-level activity on the target and then view the trace data with the System Profiler. These data can tell you if a process is spinning (i.e., actively executing but not making progress) and if another process is involved. An example would be livelock, when the interaction between processes is causing them to cycle endlessly between the same states. The trace data can also reveal deadlock. For instance, if a process is waiting on both a mutex and a semaphore, it's likely a case of priority inversion.
- To see exactly where the application is stuck, you can attach the debugger to the hanging process. As soon as it attaches to a process, the GDB tool stops execution and shows the current line of code (assuming there are matching binaries on the host). This is particularly helpful for deadlock within a process. Suppose one thread is at the start of a critical section. This likely means it can't acquire a necessary resource and is the cause of the deadlock.
-
Sometimes, attaching the debugger to find the current execution position and stepping through
the code doesn't tell you why the program is stuck.
In this case, you can use the Application Profiler to enable sampling-based profiling. This profiling method makes the application report its current line
at regular intervals, which tells you if a function is consuming a lot of execution time.
Note:The Application Profiler won't help with deadlock because the application must be executing code for the tool to receive samples.
Process crashing
When a process crashes on a machine running dumper, a core file is generated and the IDE gives you the option of debugging that core file. If you choose to do so, the IDE downloads it from the target to the host's workspace and launches the debugger. The core file contains the final state of the program, allowing you to see what happened.
If you can reproduce the crash, it's better to launch the application with the debugger attached and do so. The postmortem debugging workflow involving a core file is intended for crashes that are hard to reproduce or for when you don't have access to the device on which the crash occurs.
- If you suspect that memory corruption is behind the crash, run a memory-checking tool—Memory Analysis, Valgrind Helgrind, or Valgrind Memcheck. These tools pinpoint problematic lines of code such as illegal memory accesses or double-freeing attempts.
- If you suspect that a bad value coming from another process or even from a thread within the same process is causing the crash, run a kernel event trace. The System Profiler then displays data that lets you see any odd interactions between threads or processes.
- If both these options fail to identify the cause, you must continue using the debugger. You can set more breakpoints to see which code paths are followed before the crash occurs.