From patchwork Thu Nov 20 21:24:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 3820 Received: (qmail 3820 invoked by alias); 20 Nov 2014 21:24:20 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 3811 invoked by uid 89); 20 Nov 2014 21:24:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.0 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 20 Nov 2014 21:24:17 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sAKLODbS012376 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 20 Nov 2014 16:24:14 -0500 Received: from host2.jankratochvil.net (ovpn-116-31.ams2.redhat.com [10.36.116.31]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sAKLO7fV028622 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 20 Nov 2014 16:24:09 -0500 Date: Thu, 20 Nov 2014 22:24:06 +0100 From: Jan Kratochvil To: Eli Zaretskii Cc: gdb-patches@sourceware.org Subject: Re: [PATCH v3 14/14] the "compile" command Message-ID: <20141120212406.GA23190@host2.jankratochvil.net> References: <20141101214552.13230.45564.stgit@host1.jankratochvil.net> <20141101214733.13230.49968.stgit@host1.jankratochvil.net> <8361exy4if.fsf@gnu.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <8361exy4if.fsf@gnu.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes 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 Jan Kratochvil * gdb.texinfo (Altering): Update. (Compiling and Injecting Code): New node. 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 + Jan Kratochvil + + * gdb.texinfo (Altering): Update. + (Compiling and Injecting Code): New node. + 2014-10-30 Doug Evans * 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