[v3,14/14] the "compile" command

Message ID 20141120212406.GA23190@host2.jankratochvil.net
State New, archived
Headers

Commit Message

Jan Kratochvil Nov. 20, 2014, 9:24 p.m. UTC
  On Sun, 02 Nov 2014 17:02:48 +0100, Eli Zaretskii wrote:
> > +Compile @var{source} with the compiler language set as the current
> > +language in @value{GDBN} (@pxref{Languages}).
> 
> Does the user need to set the language, or will the language from the
> debug info be used, if available?

The latter.

> If the latter, the wording here needs to be modified, as it currently
> implies one needs to set the language "in GDB".

Used s/set/found/.
	Compile @var{source} with the compiler language found as the current
	language in @value{GDBN} (@pxref{Languages}).


> > If compilation and
> > +injection is not supported with the current language specified in
> > +@value{GDBN}, or the compiler does not support this feature,
> 
> Which "this feature" needs to be supported by the compiler?

The "compilation and injection" - the libcc1.so module and its
gcc_c_fe_context() interface for GDB.


> > +message will be printed.  If @var{source} compiles and links
> > +successfully, @value{GDBN} will load the object-code emitted,
> 
> Judging by the example, I would suggest to use @var{source-code}
> instead of @var{code}.

You wanted to say "instead of @var{source}.".

Changed it in these lines:
	@item compile code @var{source-code}
	@itemx compile code -raw @var{--} @var{source-code}
	Compile @var{source-code} with the compiler language found as the current
	[...]
	message will be printed.  If @var{source-code} compiles and links
	[...]
	provided @var{source-code} in a callable scope.  In this case, you must


> > +The command allows you to specify source code in two ways.  The simplest
> 
> @var{code}, so that the reader realizes you are talking about the
> argument mentioned above.

I think it should be @var{source-code} now, therefore used:
	The command allows you to specify @var{source-code} in two ways.  


> > +Specifying @samp{-raw}, prohibits @value{GDBN} from wrapping the
> > +provided @var{source} in a callable scope.  In this case, you must
> > +specify the entry point of the code by defining a function named
> > +@code{_gdb_expr_}.  The @samp{-raw} code does not automatically
> > +access variables of the inferior, for their import you must use the
> > +@samp{#pragma} line first:
> > +
> > +@smallexample
> > +#pragma GCC user_expression
> > +@end smallexample
> 
> I think an example of using 'raw' is in order; the description above
> is not very clear.
> 
> > +@samp{#include} lines are better to be placed before the @samp{#pragma}
> > +line.
> 
> Why? what happens if one doesn't?

While debugging it I have found that for -raw file #pragma GCC user_expression
does not make sense as it does not work - it is explicitly disabled by:
gdb/compile/compile-c-symbols.c
       /* Don't emit local variable decls for a raw expression.  */
       if (context->base.scope != COMPILE_I_RAW_SCOPE
          || symbol_name == NULL)

Therefore I have reworked the paragraph to:
	Specifying @samp{-raw}, prohibits @value{GDBN} from wrapping the
	provided @var{source-code} in a callable scope.  In this case, you must
	specify the entry point of the code by defining a function named
	@code{_gdb_expr_}.  The @samp{-raw} code cannot access variables of the
	inferior.  Using @samp{-raw} option may be needed for example when
	@var{source-code} requires @samp{#include} lines which may conflict with
	inferior symbols otherwise.

In the future we may extend -raw to make the inferior variables accessible
somehow but as that requires GDB-generated code it mostly conflicts with the
goal of -raw.


> >        The use of @samp{-raw} is considered to be expert usage, and care
> > +should be taken when using it.
> 
> Like what?
> 
> This kind of remarks in documentation are "considered harmful": either
> explain in detail what you mean, or don't say that at all.  Leaving
> mysterious comments about "here be dragons" doesn't help the reader
> understand how to use the feature correctly.

Removed it.


> > +If the filename/path contains whitespace it must be enclosed in
> > +quotes.
> 
> Which quotes? single? double?

I have found if the filename/path contains whitespace it must be left as is,
without any quotes of any kind.  I have removed the sentence; or do you
suggested something else?


> > +There are a few caveats to keep in mind when using the @code{compile}
> > +command.  As the caveats are different per language, the table below
> > +highlights specific issues on a per language basis.
> 
> This and the following stuff is better put in its own subsection.

Done:
	@subsection Caveats when using the @code{compile} command


> > +something else in the example program changes it, or another
> > +@code{compile} command changes it.
> 
> So why did you say the changes are persistent?  Persistent might mean
> the value will be the same if the program is re-run.

The command "compile code k = 3;" makes the change persistent.  Contrary to it
command "compile code int k = 3;" would not be persistent which is described
about 3 paragraphs beneath:
	Variables and types that are created as part
	of the @code{compile} command are not persistent, and only exist as
	long as the injected object code exists.  This example is valid:

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


> > +Normal scope and access rules apply to source code compiled and injected
> > +by the @code{compile} command.  In the example, the variables @code{j}
> > +and @code{k} are not accessible; subsequent execution will bring these
> > +variables into scope, and later, code written and compiled with the
> > +@code{compile} command will be able to access them.  At this point the
> > +program is stopped in the @code{main} function so the following example:
> > +
> > +@smallexample
> > +compile code j = 3;
> > +@end smallexample
> > +
> > +would result in a compilation error, and @value{GDBN} would print that
> > +error to the console.
> 
> I needed to read this twice to understand what you mean.  Suggest to
> reword as follows:
> 
>   Normal scope and access rules apply to source code compiled and
>   injected by the @code{compile} command.  In the example, the variables
>   @code{j} and @code{k} are not accessible yet, because the program is
>   currently stopped in the @code{main} function, where these variables
>   are not in scope.  Therefore, the following command
> 
>   @smallexample
>   compile code j = 3;
>   @end smallexample
> 
>   @noindent
>   will result in a compilation error message.
> 
>   Once the program is continued, execution will bring these variables in
>   scope, and they will become accessible; then the code you specify via
>   the @code{compile} command will be able to access them.

I do not see there a difference but I used your text.


> > +However, if you were to type the following into @value{GDBN} after that
> > +command has completed:
> > +
> > +@smallexample
> > +compile code printf ("ff is %d\n'', ff);
> > +@end smallexample
> > +
> > +A compiler error would be raised as the variable @code{ff} no longer
> 
> Again, @noindend after the @example, and start "a compiler error" with
> a lower-case letter, as this is a continuation of the sentence before
> the example.

TBH I do not agree with this formatting as the previous sentence has been
terminated by its colon (':').  I see the difference as:
	See the expression: 1+2=3  Now we have to start a new sentence.
	See the expression 1+2=3 while here we continue the sentence.
But sure following your directions.


> > +@code{k} does not require the existence of @code{ff} to maintain the value
> > +it has been assigned.  Pointers and other types of references require
> 
> "However, pointers ..."
> 
> What "other types"?  How about one or two examples?

I would say just "pointers" myself.  "references" would be possible in C++ but
currently this patchset supports only plain C.  Currently one can pass also
a function name but that gets converted to a function pointer.  Reference to
a nest function via trampoline would be in fact also a function pointer.

I have removed "and other types of references" for now.


> > +location when the command exists.  A general rule should be followed
> > +in that you should either assign @code{NULL} to any assigned pointers,
> > +or restore a valid location to the pointer before the command exits.
> 
> Why NULL?  Any constant address will do, right?

NULL is the only valid constant address.  Otherwise a valid address points to
some object.

I find that sentence correct.


> > +Similar caution must be exercised with any types defined in
> > +@code{compile} command.
> 
> I would explain what you mean by "defined types" here.  I'm guessing
> you mean structs, unions, and typedefs, but let's say this explicitly.

Therefore used:
	Similar caution must be exercised with any structs, unions, and typedefs 
	defined in @code{compile} command.


> >                             Types defined in the @code{compile} are also
> > +deleted when the command exits.
> 
> I think types are not deleted, they simply don't exist in compiled
> code.  Right?

The meaning is that for example in a second "compile" command the types
defined in previous "compile" command are no longer available.


> >                                    Therefore, if you cast a variable to a
> > +type defined in the @code{compile} command, care must be taken to ensure
> > +that any future need to resolve the type can be achieved.
> 
> I don't understand the meaning of this.  Defining a type and casting
> to a type are two different things, so what does this text warn about?

I have put there:
	@smallexample
	(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
	@end smallexample


Attaching only the new gdb.texinfo diff.


Thanks,
Jan
gdb/doc/ChangeLog
    2014-10-07  Phil Muldoon  <pmuldoon@redhat.com>
    	    Jan Kratochvil  <jan.kratochvil@redhat.com>
    
    	* gdb.texinfo (Altering): Update.
    	(Compiling and Injecting Code): New node.
  

Comments

Eli Zaretskii Nov. 21, 2014, 7:58 a.m. UTC | #1
> Date: Thu, 20 Nov 2014 22:24:06 +0100
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> Cc: gdb-patches@sourceware.org
> 
> > > +something else in the example program changes it, or another
> > > +@code{compile} command changes it.
> > 
> > So why did you say the changes are persistent?  Persistent might mean
> > the value will be the same if the program is re-run.
> 
> The command "compile code k = 3;" makes the change persistent.  Contrary to it
> command "compile code int k = 3;" would not be persistent which is described
> about 3 paragraphs beneath:
> 	Variables and types that are created as part
> 	of the @code{compile} command are not persistent, and only exist as
> 	long as the injected object code exists.  This example is valid:
> 
> 	@smallexample
> 	compile code int ff = 5; printf ("ff is %d\n", ff);
> 	@end smallexample

Then maybe we need to tell what "persistent" means in this context.
Something like "visible to the rest of the program for the duration of
this run".

> > > +However, if you were to type the following into @value{GDBN} after that
> > > +command has completed:
> > > +
> > > +@smallexample
> > > +compile code printf ("ff is %d\n'', ff);
> > > +@end smallexample
> > > +
> > > +A compiler error would be raised as the variable @code{ff} no longer
> > 
> > Again, @noindend after the @example, and start "a compiler error" with
> > a lower-case letter, as this is a continuation of the sentence before
> > the example.
> 
> TBH I do not agree with this formatting as the previous sentence has been
> terminated by its colon (':').

But then that previous sentence is incomplete, because it in effect
goes like "If you were to type the following: SOMETHING."  A sentence
with an "if" but no "then" part is incomplete.  I thought what follows
the @example is the "then" part, which is why I suggested those
changes.

> I see the difference as:
> 	See the expression: 1+2=3  Now we have to start a new sentence.
> 	See the expression 1+2=3 while here we continue the sentence.

These 2 examples are both fine, but they lack the "if" part, which is
what triggered my comment.

> > >                             Types defined in the @code{compile} are also
> > > +deleted when the command exits.
> > 
> > I think types are not deleted, they simply don't exist in compiled
> > code.  Right?
> 
> The meaning is that for example in a second "compile" command the types
> defined in previous "compile" command are no longer available.

OK, then let's say so explicitly.  Something like

  Types defined in the @code{compile} will no longer be available in
  the next @code{compile} command.

> +If you specify options on the command line as well as source code, they
> +may conflict.  The @samp{@var{--}} delimiter can be used to separate options

No need for @var here, as "--" is a literal string.

Otherwise, your new text is OK.

Thanks.
  

Patch

diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 2e619da..f314c89 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,9 @@ 
+2014-10-07  Phil Muldoon  <pmuldoon@redhat.com>
+	    Jan Kratochvil  <jan.kratochvil@redhat.com>
+
+	* gdb.texinfo (Altering): Update.
+	(Compiling and Injecting Code): New node.
+
 2014-10-30  Doug Evans  <dje@google.com>
 
 	* python.texi (Progspaces In Python): Document ability to add
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 15c2908..a0b6ea7 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -16493,6 +16493,7 @@  address, or even return prematurely from a function.
 * Returning::                   Returning from a function
 * Calling::                     Calling your program's functions
 * Patching::                    Patching your program
+* Compiling and Injecting Code:: Compiling and injecting code in @value{GDBN}
 @end menu
 
 @node Assignment
@@ -16915,6 +16916,237 @@  Display whether executable files and core files are opened for writing
 as well as reading.
 @end table
 
+@node Compiling and Injecting Code
+@section Compiling and injecting code in @value{GDBN}
+@cindex injecting code
+@cindex writing into executables
+@cindex compiling code
+
+@value{GDBN} supports on-demand compilation and code injection into
+programs running under @value{GDBN}.  GCC 5.0 or higher built with
+@file{libcc1.so} must be installed for this functionality to be enabled.
+This functionality is implemented with the following commands.
+
+@table @code
+@kindex compile code
+@item compile code @var{source-code}
+@itemx compile code -raw @var{--} @var{source-code}
+Compile @var{source-code} with the compiler language found as the current
+language in @value{GDBN} (@pxref{Languages}).  If compilation and
+injection is not supported with the current language specified in
+@value{GDBN}, or the compiler does not support this feature, an error
+message will be printed.  If @var{source-code} compiles and links
+successfully, @value{GDBN} will load the object-code emitted,
+and execute it within the context of the currently selected inferior.
+It is important to note that the compiled code is executed immediately.
+After execution, the compiled code is removed from @value{GDBN} and any
+new types or variables you have defined will be deleted.
+
+The command allows you to specify @var{source-code} in two ways.
+The simplest method is to provide a single line of code to the command.
+E.g.:
+
+@smallexample
+compile code printf ("hello world\n");
+@end smallexample
+
+If you specify options on the command line as well as source code, they
+may conflict.  The @samp{@var{--}} delimiter can be used to separate options
+from actual source code.  E.g.:
+
+@smallexample
+compile code -r -- printf ("hello world\n");
+@end smallexample
+
+Alternatively you can enter source code as multiple lines of text.  To
+enter this mode, invoke the @samp{compile code} command without any text
+following the command.  This will start the multiple-line editor and
+allow you to type as many lines of source code as required.  When you
+have completed typing, enter @samp{end} on its own line to exit the
+editor.
+
+@smallexample
+compile code
+>printf ("hello\n");
+>printf ("world\n");
+>end
+@end smallexample
+
+Specifying @samp{-raw}, prohibits @value{GDBN} from wrapping the
+provided @var{source-code} in a callable scope.  In this case, you must
+specify the entry point of the code by defining a function named
+@code{_gdb_expr_}.  The @samp{-raw} code cannot access variables of the
+inferior.  Using @samp{-raw} option may be needed for example when
+@var{source-code} requires @samp{#include} lines which may conflict with
+inferior symbols otherwise.
+
+@kindex compile file
+@item compile file @var{filename}
+@itemx compile file -raw @var{filename}
+Like @code{compile code}, but take the source code from @var{filename}.
+
+@smallexample
+compile file /home/user/example.c
+@end smallexample
+@end table
+
+@subsection Caveats when using the @code{compile} command
+
+There are a few caveats to keep in mind when using the @code{compile}
+command.  As the caveats are different per language, the table below
+highlights specific issues on a per language basis.
+
+@table @asis
+@item C code examples and caveats
+When the language in @value{GDBN} is set to @samp{C}, the compiler will
+attempt to compile the source code with a @samp{C} compiler.  The source
+code provided to the @code{compile} command will have much the same
+access to variables and types as it normally would if it were part of
+the program currently being debugged in @value{GDBN}.
+
+Below is a sample program that forms the basis of the examples that
+follow.  This program has been compiled and loaded into @value{GDBN},
+much like any other normal debugging session.
+
+@smallexample
+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;
+@}
+@end smallexample
+
+For the purposes of the examples in this section, the program above has
+been compiled, loaded into @value{GDBN}, stopped at the function
+@code{main}, and @value{GDBN} is awaiting input from the user.
+
+To access variables and types for any program in @value{GDBN}, the
+program must be compiled and packaged with debug information.  The
+@code{compile} command is not an exception to this rule.  Without debug
+information, you can still use the @code{compile} command, but you will
+be very limited in what variables and types you can access.
+
+So with that in mind, the example above has been compiled with debug
+information enabled.  The @code{compile} command will have access to
+all variables and types (except those that may have been optimized
+out).  Currently, as @value{GDBN} has stopped the program in the
+@code{main} function, the @code{compile} command would have access to
+the variable @code{k}.  You could invoke the @code{compile} command
+and type some source code to set the value of @code{k}.  You can also
+read it, or do anything with that variable you would normally do in
+@code{C}.  Be aware that changes to inferior variables in the
+@code{compile} command are persistent.  In the following example:
+
+@smallexample
+compile code k = 3;
+@end smallexample
+
+@noindent
+the variable @code{k} is now 3.  It will retain that value until
+something else in the example program changes it, or another
+@code{compile} command changes it.
+
+Normal scope and access rules apply to source code compiled and
+injected by the @code{compile} command.  In the example, the variables
+@code{j} and @code{k} are not accessible yet, because the program is
+currently stopped in the @code{main} function, where these variables
+are not in scope.  Therefore, the following command
+
+@smallexample
+compile code j = 3;
+@end smallexample
+
+@noindent
+will result in a compilation error message.
+
+Once the program is continued, execution will bring these variables in
+scope, and they will become accessible; then the code you specify via
+the @code{compile} command will be able to access them.
+
+You can create variables and types with the @code{compile} command as
+part of your source code.  Variables and types that are created as part
+of the @code{compile} command are not persistent, and only exist as
+long as the injected object code exists.  This example is valid:
+
+@smallexample
+compile code int ff = 5; printf ("ff is %d\n", ff);
+@end smallexample
+
+However, if you were to type the following into @value{GDBN} after that
+command has completed:
+
+@smallexample
+compile code printf ("ff is %d\n'', ff);
+@end smallexample
+
+@noindent
+a compiler error would be raised as the variable @code{ff} no longer
+exists.  Object code generated and injected by the @code{compile}
+command is removed when its execution ends.  Caution is advised
+when assigning to program variables values of variables created by the
+code submitted to the @code{compile} command.  This example is valid:
+
+@smallexample
+compile code int ff = 5; k = ff;
+@end smallexample
+
+The value of the variable @code{ff} is assigned to @code{k}.  The variable
+@code{k} does not require the existence of @code{ff} to maintain the value
+it has been assigned.  However, pointers require particular care in
+assignment.  If the source code compiled with the @code{compile} command
+changed the address of a pointer in the example program, perhaps to a
+variable created in the @code{compile} command, that pointer would point
+to an invalid location when the command exits.  The following example
+would likely cause issues with your debugged program:
+
+@smallexample
+compile code int ff = 5; p = &ff;
+@end smallexample
+
+In this example, @code{p} would point to @code{ff} when the
+@code{compile} command is executing the source code provided to it.
+However, as variables in the (example) program persist with their
+assigned values, the variable @code{p} would point to an invalid
+location when the command exists.  A general rule should be followed
+in that you should either assign @code{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 typedefs
+defined in @code{compile} command.  Types defined in the @code{compile}
+are also deleted when the command exits.  Therefore, if you cast
+a variable to a type defined in the @code{compile} command, care must be
+taken to ensure that any future need to resolve the type can be
+achieved.
+
+@smallexample
+(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
+@end smallexample
+
+Variables that have been optimized away by the compiler are not
+accessible to the code submitted to the @code{compile} command.
+Access to those variables will generate a compiler error which @value{GDBN}
+will print to the console.
+@end table
+
 @node GDB Files
 @chapter @value{GDBN} Files