Debugging a Program With dbx

Chapter 11 Fixing and Continuing

Using fix allows you to quickly recompile edited source code without stopping the debugging process.

This chapter is organized into the following sections:

Basic Concepts

The fix and continue feature allows you to modify and recompile a source file and continue executing without rebuilding the entire program. By updating the .o files and splicing them into your program, you don't need to relink.

The advantages of using fix and continue are:

How fix and continue Operates

Before applying the fix command you need to edit the source in the editor window. After saving changes, type fix.

Once fix has been invoked, dbx calls the compiler with the appropriate compiler options. The modified files are compiled and shared object (.so) files are created. Semantic tests are done by comparing the old and new files.

The new object file is linked to your running process using the runtime linker. If the function on top of the stack is being fixed, the new stopped in function is the beginning of the same line in the new function. All the breakpoints in the old file are moved to the new file.

You can use fix and continue on files that have been compiled with or without debugging information, but there are some limitations in the functionality of fix and continue for files originally compiled without debugging information. See the -g option description in "Command Reference" for more information.

You can fix shared objects (.so) files, but they have to be opened in a special mode. You can use either RTLD_NOW|RTLD_GLOBAL or RTLD_LAZY|RTLD_GLOBAL in the call to dlopen.

Modifying Source Using fix and continue

You can modify source code in the following ways when using fix and continue:

Restrictions

Sun WorkShop might have problems when functions are mapped from the old file to the new file. To minimize such problems when editing a source file:

If you need to make any of the proceeding changes, rebuild your program.

Fixing Your Program

To fix your file:

  1. Save the changes to your source.

    Sun WorkShop automatically saves your changes if you forget this step.

  2. Type fix at the dbx prompt.

Although you can do an unlimited number of fixes, if you have done several fixes in a row, consider rebuilding your program. fix changes the program image in memory, but not on the disk. As you do more fixes, the memory image gets out of sync with what is on the disk.

fix does not make the changes within your executable file, but only changes the .o files and the memory image. Once you have finished debugging a program, you need to rebuild your program to merge the changes into the executable. When you quit debugging, a message reminds you to rebuild your program.

Continuing after Fixing

You can continue executing using continue.

Before resuming program execution, you should be aware of the following conditions:

Changing an executed function

If you made changes in a function that has already executed, the changes have no effect until:

If your modifications involve more than simple changes to variables, use fix then run. Using run is faster because it does not relink the program.

Changing a function not yet called

If you made changes in a function not yet called, the changes will be in effect when that function is called.

Changing a function currently being executed

If you made changes to the function currently being executed, fix's impact depends on where the change is relative to the stopped in function:

Changing a function presently on the stack

If you made changes to a function presently on the stack, but not the stopped in function, the changed code will not be used for the present call of that function. When the stopped in function returns, the old versions of the function on the stack execute.

There are several ways to solve this problem:

If there are breakpoints in modified functions on the stack, the breakpoints are moved to the new versions of the functions. If the old versions are executed, the program does not stop in those functions.

Changing Variables after Fixing

Changes made to global variables are not undone by the pop or fix command. To manually reassign correct values to global variables, use the assign command.

The following example shows how a simple bug can be fixed. The application gets a segmentation violation in line 6 when trying to dereference a NULL pointer:


dbx[1] list 1,$
	1	#include <stdio.h>
	2	
	3	char *from = "ships";
	4	void copy(char *to)
	5	{
	6		while ((*to++ = *from++) != '\0');
	7		*to = '\0';
	8	}
	9	
	10	main()
	11	{
	12		char buf[100];
	13	
	14		copy(0);
	15		printf("%s\n", buf);
	16		return 0;
	17	}
(dbx) run
Running: testfix
(process id 4842)
signal SEGV (no mapping at the fault address) in copy at
line 6 in file "testfix.cc"
	6		while ((*to++ = *from++) != '\0');

Change line 14 to copy to buf instead of 0 and save the file, then do a fix:


	14		copy(buf);  	<=== modified line
(dbx) fix
fixing "testfix.cc" .....
pc moved to "testfix.cc":6
stopped in copy at line 6 in file "testfix.cc"
	6		while ((*to++ = *from++) != '\0')

If the program is continued from here, it still gets a segmentation fault because the zero-pointer is still pushed on the stack. Use the pop command to pop one frame of the stack:


(dbx) pop
stopped in main at line 14 in file "testfix.cc"
      14 copy(buf); 

If the program is continued from here, it will run, but it will not print the correct value because the global variable from has already been incremented by one. The program would print hips and not ships. Use the assign command to restore the global variable and then continue. Now the program prints the correct string:


(dbx) assign from = from-1(dbx) contships

Command Reference

The fix command takes the following options:


fix [options]
[file1, file2
,...]

-a

Fixes all modified files. 

-f

Forces fixing the file, even if the source was not changed. 

-c

Prints the compilation line, which may include some options added internally for use by dbx.

-g

Strips -O flags from the compilation line and adds the -g flag to it.

-n

Sets a no execution mode. Use this option when you want to list the source files to be fixed without actually fixing them. 

file1, file2,...

Specifies a list of modified source files to fix. 

If fix is invoked with an option other than -a and without a filename argument, only the current modified source file is fixed.


Note -

Sometimes it may be necessary to modify a header (.h) file as well as a source file. To be sure that the modified header file is accessed by all source files in the program that include it, you must give as an argument to the fix command a list of all the source files that include that header file. If you do not include the list of source files, only the primary source file is recompiled and only it includes the modified version of the header file. Other source files in the program continue to include the original version of that header file.



Note -

C++ template definitions cannot be fixed directly. Fix the files with the template instances instead. You can use the -f option to overwrite the date-checking if the template definition file has not changed. dbx looks for template definition .o files in the default repository directory SunWS_cache. The -ptr compiler switch is not supported by the fix command in dbx.


When fix is invoked, the current working directory of the file that was current at the time of compilation is searched before executing the compilation line. There might be problems locating the correct directory due to a change in the file system structure from compilation time to debugging time. To avoid this problem, use the command pathmap, which creates a mapping from one pathname to another. Mapping is applied to source paths and object file paths.