8 AppDebug
David Anderson edited this page 2024-08-29 14:37:05 -07:00

Application testing and debugging

In developing a BOINC application, you need to make sure that it interfaces properly with the BOINC client. You can do this in stages, as follows:

Testing without a BOINC client, part 1

When you have built your application and linked it with the BOINC libraries, you can run it in standalone mode (without a BOINC client present). To do this, put instances of all input files in the same directory (with the proper logical, not physical, names). The application should run, produce output files (also with their logical names), and exit with 0 status. You can run the program under a debugger.

Note: boinc_time_to_checkpoint() will always return false, so your application will never checkpoint.

Testing without a BOINC client, part 2

To make sure that suspend, resume, and abort work:

  • Edit boinc/api/boinc_api.cpp; uncomment the #defines of MSGS_FROM_FILE and (if you want) VERBOSE. This tells the BOINC API to look for process control messages in a file "msgs.txt" rather than in shared memory. Rebuild the BOINC API library, and rebuild your app.
  • Run your app.
  • To suspend your app, write "<suspend/>" to msgs.txt. You need to do this atomically, e.g. write "<suspend/>" to another file, then rename that file to msgs.txt. "cat > msgs.txt" doesn't work.
  • Similar for <resume/> and <abort/>. Verify that they all work.

Testing with a BOINC client but no project

Once your application works in standalone mode, you can test it under the BOINC client, but without a project server. This will exercise the interaction with the client.

There are two ways to do this. Both of them require describing your app's input and output files, and its other attributes. In the first way, you describe these in C++; in the second, you use XML.

Using C++

In the BOINC source tree, open client/app_test.cpp and read the instructions there. In summary:

  • Edit app_test.cpp to specify your app's name, files and attributes.
  • Build the BOINC client.
  • Create a BOINC data directory, with a subdirectories slots/app_test and projects/app_test. Or you can use an existing BOINC data directory, and create these subdirectories.
  • Put your application's files, and input files, in the projects/app_test directory (with physical names).
  • Run the BOINC client in the data directory

The client will run the job. When it's done, the output files (physical names) will be in the project directory, and stderr.txt will be in slots/app_test.

Using XML

This example assumes that your executable name is test.exe, and that it has an input file with logical name in and physical name input.txt, and an output file with logical name out and physical name output.txt.

  • Make a directory and put the BOINC client there.
  • Put the file samples/client_state_save.xml in it. Modify this file as needed to reflect the input and output files of your application (add \<file_info> and \<file_ref> elements).
  • Create a file account_test.xml containing
<account>
    <master_url>http://test.test</master_url>
    <project_name>test_project</project_name>
</account>
  • Create a file cc_config.xml containing
<cc_config>
    <options>
        <skip_cpu_benchmarks/>
        <unsigned_apps_ok/>
    </options>
</cc_config>
  • Make a subdirectory projects/test.test; put test.exe and input.txt there.
  • To run the BOINC client (and your app) type
 cp client_state_save.xml client_state.xml ; boinc

(or do the equivalent on Windows). You can run the BOINC Manager after running the client, and verify that its various functions (fraction done reporting, elapsed time reporting, suspend/resume, etc.) are working.

The client will run your app and then sleep. When the job is done, check projects/test.test/output.txt to verify that it worked. Your app's stderr output will be somewhere in client_state.xml.

Running under a debugger

If your app is crashing, there are two ways to debug it. First, if you put

<exit_before_start/>

in the config options, the BOINC client will set up the "slot directory" (usually slots/0/) where your application will run, and then exit. You can cd into that directory, check that the needed files are there, and run the app manually (perhaps under a debugger) by typing

../../projects/test.test/test.exe

In this approach the app runs in standalone mode, since the BOINC client is not running. When it's done, its output files and stderr output file will be in the slot directory.

The second approach is to put

<run_apps_manually/>

in the config options. If you do this, the BOINC client will set up to run your app, but won't actually run it; you must run it manually as above. In this case your app will interact with the BOINC client (suspend/resume, fraction-done reporting, etc.). When it's done, the output files will be in the project directory and the stderr output in client_state.xml

Testing with a BOINC client and project

If you have a working BOINC project, you can test applications by repeatedly deploying new app versions in the project. However, this is tedious if you need to make a lot of fixes. It's easier to use BOINC's anonymous platform mechanism. To do this:

  • Following the directions, create a file 'app_info.xml' in the client's project_* directory, with the appropriate name and version number of your application.
  • Each time you build a new version of your application, copy the executable into the project_* directory, making sure it has the appropriate name. Then restart the core client.

On Unix, it's possible to attach a debugger to a running process. Use 'ps' to find the process ID of your application, then something like

gdb exec_filename PID

to attach a debugger to it.

Checking your templates and app files

If your app complains that it can't find its input files, or the BOINC complains that it can't find the output files, there's most likely a problem with your input/output template files. If your app can't find the libraries it expects, there's most likely a problem with your application file setup.

These problems can be debugged by running the client with these command-line options:

--exit_before_start

The client will exit just before running an app. At that point, look at the slot directory and make sure everything is correct. Try running the app manually in the slot directory.

--exit_after_finish

The client will exit just after an app finishes. At that point, look at the slot directory and project directories, and verify that the output files are there.

Getting and deciphering stack traces

Once your application is working on your own computers, you're ready to test it with outside computers (alpha testers initially). It may crash on some computers, e.g. because their software or hardware is different from yours. You'll get some information back in the stderr_txt field of the results. If your application called boinc_init_diagnostics() with the BOINC_DIAG_DUMPCALLSTACKENABLED flag set, and you included symbols, hopefully you'll get symbolic stack traces.

There are separate instructions about deciphering a Windows stack trace.

Otherwise, you should at least get numeric (hex) stack traces. There are several techniques for deciphering these. For details see Mac Backtrace. Although that page is written primarily for the Mac, much of it can be used on Linux and UNIX systems as well.