Compiling and Injecting Code (Debugging with GDB) (2024)

When the language in GDB is set to ‘C’, the compiler willattempt to compile the source code with a ‘C’ compiler. The sourcecode provided to the compile command will have much the sameaccess to variables and types as it normally would if it were part ofthe program currently being debugged in GDB.

Below is a sample program that forms the basis of the examples thatfollow. This program has been compiled and loaded into GDB,much like any other normal debugging session.

void function1 (void){ int i = 42; printf ("function 1\n");}void function2 (void){ int j = 12; function1 ();}int main(void){ int k = 6; int *p; function2 (); return 0;}

For the purposes of the examples in this section, the program above hasbeen compiled, loaded into GDB, stopped at the functionmain, and GDB is awaiting input from the user.

To access variables and types for any program in GDB, theprogram must be compiled and packaged with debug information. Thecompile command is not an exception to this rule. Without debuginformation, you can still use the compile command, but you willbe very limited in what variables and types you can access.

So with that in mind, the example above has been compiled with debuginformation enabled. The compile command will have access toall variables and types (except those that may have been optimizedout). Currently, as GDB has stopped the program in themain function, the compile command would have access tothe variable k. You could invoke the compile commandand type some source code to set the value of k. You can alsoread it, or do anything with that variable you would normally do inC. Be aware that changes to inferior variables in thecompile command are persistent. In the following example:

compile code k = 3;

the variable k is now 3. It will retain that value untilsomething else in the example program changes it, or anothercompile command changes it.

Normal scope and access rules apply to source code compiled andinjected by the compile command. In the example, the variablesj and k are not accessible yet, because the program iscurrently stopped in the main function, where these variablesare not in scope. Therefore, the following command

compile code j = 3;

will result in a compilation error message.

Once the program is continued, execution will bring these variables inscope, and they will become accessible; then the code you specify viathe compile command will be able to access them.

You can create variables and types with the compile command aspart of your source code. Variables and types that are created as partof the compile command are not visible to the rest of the program forthe duration of its run. This example is valid:

compile code int ff = 5; printf ("ff is %d\n", ff);

However, if you were to type the following into GDB after thatcommand has completed:

compile code printf ("ff is %d\n'', ff);

a compiler error would be raised as the variable ff no longerexists. Object code generated and injected by the compilecommand is removed when its execution ends. Caution is advisedwhen assigning to program variables values of variables created by thecode submitted to the compile command. This example is valid:

compile code int ff = 5; k = ff;

The value of the variable ff is assigned to k. The variablek does not require the existence of ff to maintain the valueit has been assigned. However, pointers require particular care inassignment. If the source code compiled with the compile commandchanged the address of a pointer in the example program, perhaps to avariable created in the compile command, that pointer would pointto an invalid location when the command exits. The following examplewould likely cause issues with your debugged program:

compile code int ff = 5; p = &ff;

In this example, p would point to ff when thecompile command is executing the source code provided to it.However, as variables in the (example) program persist with theirassigned values, the variable p would point to an invalidlocation when the command exists. A general rule should be followedin that you should either assign NULL to any assigned pointers,or restore a valid location to the pointer before the command exits.

Similar caution must be exercised with any structs, unions, and typedefsdefined in compile command. Types defined in the compilecommand will no longer be available in the next compile command.Therefore, if you cast a variable to a type defined in thecompile command, care must be taken to ensure that any futureneed to resolve the type can be achieved.

(gdb) compile code static struct a { int a; } v = { 42 }; argv = &v;(gdb) compile code printf ("%d\n", ((struct a *) argv)->a);gdb command line:1:36: error: dereferencing pointer to incomplete type ‘struct a’Compilation failed.(gdb) compile code struct a { int a; }; printf ("%d\n", ((struct a *) argv)->a);42

Variables that have been optimized away by the compiler are notaccessible to the code submitted to the compile command.Access to those variables will generate a compiler error which GDBwill print to the console.

Compiling and Injecting Code (Debugging with GDB) (2024)

References

Top Articles
Latest Posts
Article information

Author: Ms. Lucile Johns

Last Updated:

Views: 6392

Rating: 4 / 5 (61 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Ms. Lucile Johns

Birthday: 1999-11-16

Address: Suite 237 56046 Walsh Coves, West Enid, VT 46557

Phone: +59115435987187

Job: Education Supervisor

Hobby: Genealogy, Stone skipping, Skydiving, Nordic skating, Couponing, Coloring, Gardening

Introduction: My name is Ms. Lucile Johns, I am a successful, friendly, friendly, homely, adventurous, handsome, delightful person who loves writing and wants to share my knowledge and understanding with you.