From The MPEG-4 Structured Audio Book by John Lazzaro and John Wawrzynek.

Part V/1: Debugging SAOL Programs

Sections

Language Elements:

printf  

Introduction

A popular staple of afternoon television is the cooking show. At the start of the show, a complex meal is planned, and by the end of the show, a perfect dinner pops out of the kitchen.

The examples shown in this book have a similar flavor. Code is shown on the right-hand panel, which always works to produce the desired audio output.

Like TV cooking shows, the book examples don't show the real development process: syntax errors, compiler bugs, program crashes, and bad-sounding audio.

In this chapter, we describe common ways that SAOL programs fail to work, and techniques to use to find and fix the problems.

The right panel shows a list of the major traps in the development cycle. In the sections of this chapter, we describe how to approach these problems.

In this chapter, we use the sfront SAOL-to-C translator, running under Linux, to demonstrate debugging. However, even if you use another SAOL development systems, the concepts in this chapter should help you debug your programs.

Errors: Where, When, and What


Before execution:

  • sfront reports SAOL Syntax Error.
  • sfront crashes or hangs up.
  • gcc fails to compile sa.c.

During execution:

  • Program ends, prints "Runtime Error" banner.
  • Program crashes, with Linux OS error.
  • Program runs forever.

After execution:

  • Audio sounds totally wrong.
  • Audio almost sounds correct.
  • Audio ends too soon or too late.

Reported Errors

Many SAOL programming errors are detected automatically and reported to the user. Depending on the error, sfront may report a compile-time error, or the C program sfront creates may terminate and report an error.

The right panel shows one kind of sfront compile-time error, a syntax error (in this case, a missing semicolon).

Since sfront can't understand the SAOL program without the semicolon, its error message doesn't describe the problem exactly. However, it does report a line number and filename, which (usually) is sufficient to debug the problem.

Syntax Error Report


SAOL fragment:

instr tremelo ( ) {
   asig count    // lacks ';'
   ksig kinit;


sfront reports:

Syntax error during 
-saolfile parsing.

Error occurred near line
28 in file min.saol:

instr tremelo ( ) {
   asig count
   ksig kinit;
   ksig halfperiod;

Ending sfront.

A second type of compile-time error is a type mismatch error. The right panel shows an example of a type mismatch (a table used in a signal expression).

Because sfront successfully understood the syntax of the program, it was able to print a meaningful error message.

Whenever you run sfront, your session should end in one of the following ways:

  1. Sfront runs and reports error or warning messages about your program. The SAOL program must be fixed to eliminate these messages.
  2. Sfront runs without reporting an error. In this case, the C file it creates should compile and produce an runnable executable.

However, if your session ends in one of the following ways:

  1. Sfront never completes.
  2. Sfront crashes.
  3. Sfront printing an Internal compiler error message.
  4. The C file sfront produces won't compile.
you've stumbled across a bug in sfront itself, which should be sent in as a bug report.

Type Error Report


SAOL fragment:

instr square ( ) {
   table delta(harm, 128, 1);

   delta = delta + 1; // type error
   

sfront reports:

Error: Table(map) delta 
used inappropriately.

Error occured near line
56 in file min.saol:

   table delta(harm, 128, 1);

   delta = delta + 1;
   

Ending sfront.

When sfront creates a C program, it includes error checking code for certain types of errors. If this error checking code is tripped, a run-time error report is printed and the program exits.

The right panel shows an example of run-time error checking. In this case, a table is defined, using the sample wavetable generator. However, the file specified doesn't actually exist.

During execution, the program tries to open the file and fails; it then prints the run-time error shown and exits.

Reported errors are the simplest type of run-time error to catch and fix. To help the programmer write good code, the MP4-SA standard mandates that decoders catch report many kinds of real-time errors checks.

Eventually, sfront will implement all of these error checks. At the present time, however, sfront implements many but not all required checks.

Specifically, sfront does not check to see if the index value of an array, oparray, or tablemap is out of range. In addition, CPU intensive checks on certain core opcodes, such as checking the range of the index parameter to tableread and tablewrite, are only performed if sfront is run with the -isocheck flag.

If your program does one of these illegal operations, it won't produce a run-time error message. Instead, the program might crash, or it may run forever, or (most likely) the sound created might not be what it should.

Runtime Error Report


SAOL fragment:

// file doesn't actually exist

global { 
  table oneclap(sample, -1,
               "samp_2.aif"); 



Execution trace:

gcc -O3 sa.c -lm  -o sa
./sa 



Runtime Error.
Location: File claps.saol 
          near line 10.

While executing: table.
Potential problem: Samplefile
           not found (aif(f)).

Exiting program.

Program Crashes

In many ways, a program that crashes is easier to debug than one that silently does the wrong thing.

In the future, sfront will include modes for reporting exactly where and how a program crashes. For now, the easiest way to debug a program crash under Linux is to follow these steps:

  1. Recompile the sa.c program, using the -g option of gcc
  2. Run gdb on the program, as shown on the right panel.
  3. The C code sfront generates embeds SAOL variable names into its C identifiers. Look at the debug printout gdb produces to pinpoint the error location.

It may be helpful to look at the sa.c file in this process, if you are comfortable with the C language.

The remainder of this chapter focuses on techniques for handling SAOL programs that don't crash, but which produce the wrong audio.

Running Gdb


[1] Run sfront without -except option

[2] Compile sa.c with debug switch:

gcc -g -O3 sa.c -lm  -o sa

[3] Run gdb:

gdb ./sa

GNU gdb 4.17.0.11 

(gdb) run

Starting program: ./sa 

Segmentation fault, in
arpsound2__sym_butter_gainlp3
(gdb) bt

#0  in arpsound2__sym_butter_gainlp3 ()
#1  in arpsound2_kpass ()
#2  in main_kpass ()
#3  in main ()

[3] Example what gdb prints in 
response to "bt" as shown above.
In this case, bug was in the 
kpass of instr arpsound2,
during a call to opcode 
butter_gainlp3.

Finding Runtime Errors

Finding the root cause of a run-time problem in a SAOL progr