Debugging an App


When Nsight Tegra, Visual Studio Edition builds a project in debug mode, a copy of GDB server is included in the application package file (.apk) and run on the device when the application is debugged. A gdb.setup file is also created in the project root directory and used to initialize the GDB client. This file contains commands to set the library search paths and source directories. The setup file is generated each time the project is built, but additional GDB user commands can be entered in the #BEGIN USER COMMANDS section and will not be overwritten.

In the case of a Make Application project, NDK-BUILD generates the gdb.setup file during a build. When a project is launched, the debugger will first look for the file in the project root, then search for it in the project directories.

By default, the application project set as the startup project will be debugged. To set a project for startup, right-click on it and select Set as Startup Project. A different project can also be debugged by right-clicking on the project and selecting the Debug > Start new instance menu.

An application can be installed, run, and debugged on the device using the Start Debugging button or menu. By default, Visual Studio will prompt to build the project if it is out of date. This can be changed using the Project and Solutions > Build and Run > On Run, when projects are out of date option.

By default when a project is started it will install, run, and attach to the application process on the device. If the application has already been installed and is running on the device, the debugger can be set to attach to the existing process. This can be selected in the project’s Debugging properties.

An existing process can also be attached by using the Debug > Attach to Process… menu. This will open the Visual Studio Attach to Process dialog.

  1. The Transport should be set to Android.
  2. All connected Android devices and emulators will be shown in the Qualifier list. Select the device that is running the application and the processes will be listed. The process for an application will have the same name as the application package.
  3. Select the process that corresponds to the application and click the Attach button.

Once an application is launched or attached, a status dialog will be displayed. If the connection is successful, the debug session will start. If the connection fails, information about the error will be displayed in the status dialog.

When debugging is stopped, a launched program will be terminated. An attached program will continue to run on the device.

Debugging Java and Native Code

In order to debug both Java and native code, the Debug Mode in the project debugging properties must be set to Java and Native code.

The debugger can only be stopped in either Java or native code at any given time. When encountering a Java breakpoint, the debugger will stop in Java code. Likewise, when encountering a C/C++ breakpoint, the debugger will stop in C/C++ code. When Break All is selected, the debugger uses the active editor to determine if it should stop in Java or native code. For .java files, the debugger will stop in Java code. For .c, .h, .cpp, .hpp, .cxx, and .hxx files, the debugger will stop in C/C++ code.

By default, a prompt will be displayed if the type of stop cannot be determined from the active editor.

This can be changed in the Tools > Options… > Android > Debug > Code to stop in by default option.

When the debugger is stopped in native code, Java threads may not be inspected. This is because the entire process is suspended and the Java virtual machine is not able to respond to commands.

A breakpoint set in Java code will not be installed until the program is resumed and the virtual machine can respond to the breakpoint request.


Execution

The Debug toolbar can be used to control execution of the program.

When a source file is active, a source step will be performed. When the Disassembly window is active, an instruction step will be performed.

Debugging an Existing APK

In order to debug an existing .apk file with native .so libraries compiled separately from Nsight Tegra, you should do the following: 

  1. Create a new project by going to FileNewProject. Select the Android Hello World Demo project.
  2. Go to BuildConfiguration Manager and uncheck the Build checkbox.


  3. Go to your project's Properties page and do the following: 
    1. On the Debugging tab, click the drop-down arrow next to Override APK Path, and select Edit. Then enter the path to your APK.


      Note that if you select the Browse dialog, it will require you to select an .exe file. This is a known issue.
    2. On the General tab, click the drop-down arrow next to Target Android API Level, and set the required API level.


  4. Create a libs\<architecture> directory inside the Hello World project root folder. The default setting is libs\armeabi-v7a. Alternately, this can be done through the project's debug properties.
  5. Update AndroidManifest.xml with relevant data, the most important of which is to change the package and activity names. Alternately, you can also substitute it with your own manifest file.
  6. Set breakpoints and begin debugging.

Setting Breakpoints

Breakpoints are set by clicking in the vertical margin of a source file, or by using the toggle breakpoint menu item (F9).

The debugger will stop program execution when the breakpoint is encountered. Breakpoints can be set before a project is launched.

When debugging, if a breakpoint fails to set, it will be annotated with a warning and the tooltip will include information. If a breakpoint is set in the source for a module that has not loaded yet, it will be marked pending.

When the module is loaded, the breakpoint will set and update in the source file.

Note: Pending breakpoints are only available using NVNDK GDB 7.2. The NDK GDB 6.6 does not support library load events.

Function Breakpoint

A breakpoint can be set on a named function using the Debug > New Breakpoint > Break at Function… menu.

The breakpoint will stop the program when the function is entered. The Line and Character elements are not supported and will result in an error if used.

Breakpoint Condition

A condition can be set for a breakpoint by right-clicking on it and selecting Condition… A valid GDB expression can be entered for the condition. Only expressions that result in a ‘true’ evaluation are supported. Breaking when an expression Has changed is not supported.

Breakpoint Hit Count

A breakpoint can be set to stop after it is hit a specified number of times by right-clicking on it and selecting Hit Count…

Breakpoint Filter

A filter can be set for a breakpoint by right-clicking on it and selecting Filter…

A breakpoint in code that is called by multiple threads can be set to stop only for certain threads by using the ThreadId or ThreadName intrinsics.

Tracepoints

A breakpoint can be set to print a message when it is hit. Right-click on the breakpoint and select When Hit…, or right-click in the source window and select Breakpoint > Insert Tracepoint. Instead of stopping on the breakpoint, the debugger will print the message when it is encountered. The message will be printed to the Debug pane of the Output window.

Note: Attempting to step over a function containing a tracepoint will cause the debugger to stop at the tracepoint.

Watchpoints

Watchpoints stop the program when the specific address in memory is read or written. There are two ways to set up a watchpoint in Nsight Tegra. First, you can select the New > New Data Breakpoint... menu item in the Breakpoints window and specify an address or an expression to watch, which will create an on-write watchpoint.

The other option is to use the Tegra > Debug > New Watchpoint menu item ( on the toolbar), which will bring up a dialog that allows you to choose the type of the watchpoint.

On-access watchpoints stop the program when the memory is either read or written.

Note: There is a device-dependent limit on amount of watchpoints that can be active at any given time. Exceeding this limit will trigger an error.

Signals

Signals are asynchronous events that can happen in the program. Android defines many signals that can occur during program execution. The signals can be configured in the Visual Studio Exceptions dialog accessed from the Debug > Exceptions… menu. The signals are located under Android Exceptions > Signals. The debugger can be set to stop for a signal; this setting will be remembered between debug sessions.

If the debugger is set to stop for a signal, the debugger will prompt when the signal occurs. You can choose to Break or Continue program execution, executing any signal handlers. You can also choose to Ignore the signal, and continue the program execution.

Exceptions

The debugger can be set to stop for C/C++ exceptions. This is enabled in the Visual Studio Exceptions Dialog accessed from the Debug > Exceptions… menu.

If enabled, the debugger will prompt when a C++ exception is thrown and you can choose to stop or continue program execution.

 

 


NVIDIA® GameWorks™ Documentation Rev. 1.0.211026 ©2014-2021. NVIDIA Corporation and affiliates. All Rights Reserved.