* [PATCH 0/2] Make chained function calls in expressions work @ 2014-09-26 13:29 Siva Chandra 2014-10-01 0:42 ` Siva Chandra 0 siblings, 1 reply; 16+ messages in thread From: Siva Chandra @ 2014-09-26 13:29 UTC (permalink / raw) To: gdb-patches This patch series enables having chained function calls in expressions. An example of a chained function call is shown in PR c++/11606. It has an example of a chain of two function calls. This patch series enables chains of any number of function calls. Currently, an inferior function call is handled via call_function_by_hand. The value returned by the inferior function is copied into a GDB value whose lval_type is not_lval. Its contents are stored within the value irrespective of whether the return value is in inferior memory or in a register. Consequently, any subsequent function call in the expression which requires this value's address as an argument throws an error as the value is not in inferior memory. This patch series keeps most of the current flow intact, except that the value returned by the inferior function is made to be a new lval_type called lval_mirrored_on_inferior_stack. These values have a mirrored value of lval_type lval_memory which reside on the inferior stack. They reside on the stack only for the duration for which the expression is evaluated. This enables value_address to return the address of the stack mirror instead of throwing an error. Patch 1/2 - Adds new lval_type named lval_mirrored_on_inferior_stack. Also adds support for values with this lval_type. Patch 2/2 - Enables chained function calls by mirroring values returned by inferior functions in the inferior stack. Patch 2/2 only targets values returned by call_function_by_hand. I think similar things can done for call_internal_function and call_xmethod. I will extend the idea to these functions as well after this patch series is approved (if at all). Thanks, Siva Chandra ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-09-26 13:29 [PATCH 0/2] Make chained function calls in expressions work Siva Chandra @ 2014-10-01 0:42 ` Siva Chandra 2014-10-01 13:15 ` Ulrich Weigand 2014-10-09 0:02 ` Siva Chandra 0 siblings, 2 replies; 16+ messages in thread From: Siva Chandra @ 2014-10-01 0:42 UTC (permalink / raw) To: gdb-patches On Fri, Sep 26, 2014 at 6:29 AM, Siva Chandra <sivachandra@google.com> wrote: > This patch series enables having chained function calls in > expressions. An example of a chained function call is shown in PR > c++/11606. It has an example of a chain of two function calls. This > patch series enables chains of any number of function calls. > > Currently, an inferior function call is handled via > call_function_by_hand. The value returned by the inferior function is > copied into a GDB value whose lval_type is not_lval. Its contents are > stored within the value irrespective of whether the return value is in > inferior memory or in a register. Consequently, any subsequent > function call in the expression which requires this value's address as > an argument throws an error as the value is not in inferior memory. > > This patch series keeps most of the current flow intact, except that > the value returned by the inferior function is made to be a new > lval_type called lval_mirrored_on_inferior_stack. These values have a > mirrored value of lval_type lval_memory which reside on the inferior > stack. They reside on the stack only for the duration for which the > expression is evaluated. This enables value_address to return the > address of the stack mirror instead of throwing an error. > > Patch 1/2 - Adds new lval_type named lval_mirrored_on_inferior_stack. > Also adds support for values with this lval_type. > Patch 2/2 - Enables chained function calls by mirroring values > returned by inferior functions in the inferior stack. > > Patch 2/2 only targets values returned by call_function_by_hand. I > think similar things can done for call_internal_function and > call_xmethod. I will extend the idea to these functions as well after > this patch series is approved (if at all). I used global state in patch 2/2. I thought eliminating that would not be a straightforward task. However, I spent time looking into it and it turned out to be much simpler than I had anticipated. I have now updated both 1/2 and 2/2 to not use any global state. I have also regression tested and found that a known failure now passes. Will follow up with v2 of 1/2 and 2/2 both. Thanks, Siva Chandra ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-01 0:42 ` Siva Chandra @ 2014-10-01 13:15 ` Ulrich Weigand 2014-10-01 18:05 ` Siva Chandra 2014-10-09 0:02 ` Siva Chandra 1 sibling, 1 reply; 16+ messages in thread From: Ulrich Weigand @ 2014-10-01 13:15 UTC (permalink / raw) To: Siva Chandra; +Cc: gdb-patches > On Fri, Sep 26, 2014 at 6:29 AM, Siva Chandra <sivachandra@google.com> wrote: > > This patch series enables having chained function calls in > > expressions. An example of a chained function call is shown in PR > > c++/11606. It has an example of a chain of two function calls. This > > patch series enables chains of any number of function calls. > > > > Currently, an inferior function call is handled via > > call_function_by_hand. The value returned by the inferior function is > > copied into a GDB value whose lval_type is not_lval. Its contents are > > stored within the value irrespective of whether the return value is in > > inferior memory or in a register. Consequently, any subsequent > > function call in the expression which requires this value's address as > > an argument throws an error as the value is not in inferior memory. > > > > This patch series keeps most of the current flow intact, except that > > the value returned by the inferior function is made to be a new > > lval_type called lval_mirrored_on_inferior_stack. These values have a > > mirrored value of lval_type lval_memory which reside on the inferior > > stack. They reside on the stack only for the duration for which the > > expression is evaluated. This enables value_address to return the > > address of the stack mirror instead of throwing an error. I'm wondering if there isn't a simpler way to solve this issue: couldn't you instead during preparation of the second call_function_by_hand simply allocate extra space on the stack and copy not_lval values whose address needs to be taken there? This would avoid adding the new lval type, all the extra state to track mirrored values during an expression, and would actually allow you to pass *other* not_lval values to inferior calls too (not just those originating from another inferior call). Bye, Ulrich -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-01 13:15 ` Ulrich Weigand @ 2014-10-01 18:05 ` Siva Chandra 2014-10-01 18:26 ` Siva Chandra 0 siblings, 1 reply; 16+ messages in thread From: Siva Chandra @ 2014-10-01 18:05 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Wed, Oct 1, 2014 at 6:15 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: >> On Fri, Sep 26, 2014 at 6:29 AM, Siva Chandra <sivachandra@google.com> wrote: >> > This patch series enables having chained function calls in >> > expressions. An example of a chained function call is shown in PR >> > c++/11606. It has an example of a chain of two function calls. This >> > patch series enables chains of any number of function calls. >> > >> > Currently, an inferior function call is handled via >> > call_function_by_hand. The value returned by the inferior function is >> > copied into a GDB value whose lval_type is not_lval. Its contents are >> > stored within the value irrespective of whether the return value is in >> > inferior memory or in a register. Consequently, any subsequent >> > function call in the expression which requires this value's address as >> > an argument throws an error as the value is not in inferior memory. >> > >> > This patch series keeps most of the current flow intact, except that >> > the value returned by the inferior function is made to be a new >> > lval_type called lval_mirrored_on_inferior_stack. These values have a >> > mirrored value of lval_type lval_memory which reside on the inferior >> > stack. They reside on the stack only for the duration for which the >> > expression is evaluated. This enables value_address to return the >> > address of the stack mirror instead of throwing an error. > > I'm wondering if there isn't a simpler way to solve this issue: couldn't > you instead during preparation of the second call_function_by_hand simply > allocate extra space on the stack and copy not_lval values whose address > needs to be taken there? This would avoid adding the new lval type, all > the extra state to track mirrored values during an expression, and would > actually allow you to pass *other* not_lval values to inferior calls too > (not just those originating from another inferior call). I did think about this route. However, look at the comment at eval.c:1405. It has an argument for why we should not in general copy function args on to the stack. My patches here target return values of functions. Though return values end up being function arguments in a chained function call expression, IMO return values do not suffer from the same problem pointed to in the comment from above. 1. If a function returns a reference, creating a copy of the reference on the stack and passing it around for the duration the expression is being evaluated should not be a problem. 2. If a function returns a value, then it is either returned on the stack or in a register. My patches do not really disturb the case of a value being returned on stack. Even when values are returned in registers, intermediate return values are only temporaries and holding onto their addresses in some stateful entity will be an error. Thanks, Siva Chandra ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-01 18:05 ` Siva Chandra @ 2014-10-01 18:26 ` Siva Chandra 2014-10-20 16:01 ` Ulrich Weigand 0 siblings, 1 reply; 16+ messages in thread From: Siva Chandra @ 2014-10-01 18:26 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Wed, Oct 1, 2014 at 11:05 AM, Siva Chandra <sivachandra@google.com> wrote: > On Wed, Oct 1, 2014 at 6:15 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: >>> On Fri, Sep 26, 2014 at 6:29 AM, Siva Chandra <sivachandra@google.com> wrote: >>> > This patch series enables having chained function calls in >>> > expressions. An example of a chained function call is shown in PR >>> > c++/11606. It has an example of a chain of two function calls. This >>> > patch series enables chains of any number of function calls. >>> > >>> > Currently, an inferior function call is handled via >>> > call_function_by_hand. The value returned by the inferior function is >>> > copied into a GDB value whose lval_type is not_lval. Its contents are >>> > stored within the value irrespective of whether the return value is in >>> > inferior memory or in a register. Consequently, any subsequent >>> > function call in the expression which requires this value's address as >>> > an argument throws an error as the value is not in inferior memory. >>> > >>> > This patch series keeps most of the current flow intact, except that >>> > the value returned by the inferior function is made to be a new >>> > lval_type called lval_mirrored_on_inferior_stack. These values have a >>> > mirrored value of lval_type lval_memory which reside on the inferior >>> > stack. They reside on the stack only for the duration for which the >>> > expression is evaluated. This enables value_address to return the >>> > address of the stack mirror instead of throwing an error. >> >> I'm wondering if there isn't a simpler way to solve this issue: couldn't >> you instead during preparation of the second call_function_by_hand simply >> allocate extra space on the stack and copy not_lval values whose address >> needs to be taken there? This would avoid adding the new lval type, all >> the extra state to track mirrored values during an expression, and would >> actually allow you to pass *other* not_lval values to inferior calls too >> (not just those originating from another inferior call). > > I did think about this route. However, look at the comment at > eval.c:1405. It has an argument for why we should not in general copy > function args on to the stack. > > My patches here target return values of functions. Though return > values end up being function arguments in a chained function call > expression, IMO return values do not suffer from the same problem > pointed to in the comment from above. > > 1. If a function returns a reference, creating a copy of the reference > on the stack and passing it around for the duration the expression is > being evaluated should not be a problem. > 2. If a function returns a value, then it is either returned on the > stack or in a register. My patches do not really disturb the case of a > value being returned on stack. Even when values are returned in > registers, intermediate return values are only temporaries and holding > onto their addresses in some stateful entity will be an error. A tangential point, GDB does not call destructors on these temporaries which IMO is an error. That is why, in my 2/2, you will notice that the expression's state is holding onto all the return value temporaries in a vector instead of just the last one created; In a future pass, I would like to implement invoking the destructors on these temporaries after the expression result is evaluated. Thanks, Siva Chandra ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-01 18:26 ` Siva Chandra @ 2014-10-20 16:01 ` Ulrich Weigand 2014-10-20 19:56 ` Siva Chandra 0 siblings, 1 reply; 16+ messages in thread From: Ulrich Weigand @ 2014-10-20 16:01 UTC (permalink / raw) To: Siva Chandra; +Cc: gdb-patches Siva Chandra wrote: > On Wed, Oct 1, 2014 at 11:05 AM, Siva Chandra <sivachandra@google.com> wrote: > > On Wed, Oct 1, 2014 at 6:15 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > >> I'm wondering if there isn't a simpler way to solve this issue: couldn't > >> you instead during preparation of the second call_function_by_hand simply > >> allocate extra space on the stack and copy not_lval values whose address > >> needs to be taken there? This would avoid adding the new lval type, all > >> the extra state to track mirrored values during an expression, and would > >> actually allow you to pass *other* not_lval values to inferior calls too > >> (not just those originating from another inferior call). > > > > I did think about this route. However, look at the comment at > > eval.c:1405. It has an argument for why we should not in general copy > > function args on to the stack. Good point, we cannot do that in the general case. > > My patches here target return values of functions. Though return > > values end up being function arguments in a chained function call > > expression, IMO return values do not suffer from the same problem > > pointed to in the comment from above. > > > > 1. If a function returns a reference, creating a copy of the reference > > on the stack and passing it around for the duration the expression is > > being evaluated should not be a problem. > > > > 2. If a function returns a value, then it is either returned on the > > stack or in a register. My patches do not really disturb the case of a > > value being returned on stack. Even when values are returned in > > registers, intermediate return values are only temporaries and holding > > onto their addresses in some stateful entity will be an error. However, I'm still not convinced that the decision ought to made at the point a function *returns*. As I understand the C++ standard, creation of the temporary is rather triggered by the fact that a value is bound to a function *argument* of reference type. For example, if we had a function taking a "const int &" argument, then passing an integer constant to that function should result in the creation of a temporary, even though there is no function return value involved. It seems to me the proper place to handle this would be the TYPE_CODE_REF case in value_arg_coerce, where we currently have this comment: /* Cast the value to the reference's target type, and then convert it back to a reference. This will issue an error if the value was not previously in memory - in some cases we should clearly be allowing this, but how? */ > A tangential point, GDB does not call destructors on these temporaries > which IMO is an error. That is why, in my 2/2, you will notice that > the expression's state is holding onto all the return value > temporaries in a vector instead of just the last one created; In a > future pass, I would like to implement invoking the destructors on > these temporaries after the expression result is evaluated. I see. This is indeed a good argument for temporaries to persist longer than a single inferior call. We could still *allocate* (and initialize) the temporary when processing function arguments for the "outer" call, though, see above. (As an aside, the precise rules on temporary creation and lifetime are of course language specific. So in an ideal world, we might want the language parser to handle this and insert temporary creation/destruction opcodes into the expression, and have expression evaluation simply process those as usual without having to hard-code C++ semantics. However, as there's unfortunately already lots of other C++ semantics hardcoded, this is certainly not a hard requirement to get the patch accepted at this point ...) Another point: Even if we allow for temporaries to persist, I'm still not sure I understand the need for the new lval_mirrored_on_inferior_stack type. Why can't they just be regular (non-lazy) lval_memory values? Those already both refer to an inferior address and cache the contents in GDB memory. At the point the temporaries in the inferior disappear, those values could then be flipped to non_lval. (Actually, I'm not seeing anywhere in your current patches where lval_mirrored_on_inferior_stack values are marked invalid once the inferior stack contents disappear?) A final concern is that leaving temporaries on the stack after an inferior call is finishes just seems a bit fragile, in particular since they're *below* the thread's SP value at times, making them potentially vulnerable to being overwritten by signal handlers etc. Now I *think* this is not a problem in current GDB (with your patch) since we will not be running the inferior thread before expression evaluation ends, *except* for executing further inferior calls, and those will again adjust the SP. But future modifications to epression evaluation logic will have to keep this in mind, so there should at least be a comment somewhere ... Bye, Ulrich PS: Sorry for the delay in replying, I was out of office for a bit and then got sidetracked with other stuff. I'll try to be more prompt in further discussion on this topic. I certainly appreciate you working on this; improving GDB's C++ debugging capabilities is important! -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-20 16:01 ` Ulrich Weigand @ 2014-10-20 19:56 ` Siva Chandra 2014-10-21 11:15 ` Ulrich Weigand 0 siblings, 1 reply; 16+ messages in thread From: Siva Chandra @ 2014-10-20 19:56 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Mon, Oct 20, 2014 at 9:01 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > However, I'm still not convinced that the decision ought to made at the > point a function *returns*. I am not sure any decision is being made here. All my patch set does is to make temporary copies of return values on the stack. > As I understand the C++ standard, creation > of the temporary is rather triggered by the fact that a value is bound > to a function *argument* of reference type. I am confused about what you are describing. As far as mechanics of function calls goes, references are just pointers: http://mentorembedded.github.io/cxx-abi/abi.html#reference-parameter And, that is how GDB treats reference arguments any way. But ... > For example, if we had a function taking a "const int &" argument, then > passing an integer constant to that function should result in the creation > of a temporary, even though there is no function return value involved. ... for this case, as you point out, a temporary on the stack has to be created and its address has to be passed as argument. GDB is broken for this case currently and my patch set does not fix it. > It seems to me the proper place to handle this would be the TYPE_CODE_REF > case in value_arg_coerce, where we currently have this comment: > > /* Cast the value to the reference's target type, and then > convert it back to a reference. This will issue an error > if the value was not previously in memory - in some cases > we should clearly be allowing this, but how? */ I have not thought enough about "any" function argument in general as it can in general be a bad thing. But I agree that there could be exceptions made for cases like this. I can take this up as a follow up task after this patch set is either accepted or abandoned. >> A tangential point, GDB does not call destructors on these temporaries >> which IMO is an error. That is why, in my 2/2, you will notice that >> the expression's state is holding onto all the return value >> temporaries in a vector instead of just the last one created; In a >> future pass, I would like to implement invoking the destructors on >> these temporaries after the expression result is evaluated. > > I see. This is indeed a good argument for temporaries to persist longer > than a single inferior call. We could still *allocate* (and initialize) > the temporary when processing function arguments for the "outer" call, > though, see above. How do we distinguish between which func arg can be copied on to the stack and which cannot? May be we could, but GDB already creates temporary copies for objects returned by value when the ABI requires that the return value's address be passed as a hidden first arg. My patch set actually derives inspiration from this; why not treat all return values like this instead of only when the ABI requires it? > Another point: Even if we allow for temporaries to persist, I'm still > not sure I understand the need for the new lval_mirrored_on_inferior_stack > type. Why can't they just be regular (non-lazy) lval_memory values? Those > already both refer to an inferior address and cache the contents in GDB > memory. At the point the temporaries in the inferior disappear, those > values could then be flipped to non_lval. I agree that the new lval type is not required in principle. However, I brought them in so that it is clear as to how they have actually come to exist in that way at all. I can remove them it if it seems like noise. > (Actually, I'm not seeing > anywhere in your current patches where lval_mirrored_on_inferior_stack > values are marked invalid once the inferior stack contents disappear?) Ah, Catch! It seems like I generated the diff from a wrong commit. Will shortly send the v3 of the patch set which has this correctly handled. > A final concern is that leaving temporaries on the stack after an inferior > call is finishes just seems a bit fragile, in particular since they're > *below* the thread's SP value at times, making them potentially vulnerable > to being overwritten by signal handlers etc. Now I *think* this is not > a problem in current GDB (with your patch) since we will not be running > the inferior thread before expression evaluation ends, *except* for > executing further inferior calls, and those will again adjust the SP. > But future modifications to epression evaluation logic will have to > keep this in mind, so there should at least be a comment somewhere ... I will add a comment for this. However, I am not sure how an expression evaluation (involving inferior function calls) can be performed when the inferior thread is actually running. > PS: Sorry for the delay in replying, I was out of office for a bit and > then got sidetracked with other stuff. I'll try to be more prompt in > further discussion on this topic. I certainly appreciate you working > on this; improving GDB's C++ debugging capabilities is important! Thanks a lot for actually taking time to look at this. The gymnastics of this patch set should not be required iff and when the 'compile' command can get going for C++. Until then, it will be great if we can get GDB to do "obvious" things correctly. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-20 19:56 ` Siva Chandra @ 2014-10-21 11:15 ` Ulrich Weigand 2014-10-21 20:30 ` Siva Chandra 0 siblings, 1 reply; 16+ messages in thread From: Ulrich Weigand @ 2014-10-21 11:15 UTC (permalink / raw) To: Siva Chandra; +Cc: gdb-patches Siva Chandra wrote: > On Mon, Oct 20, 2014 at 9:01 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > > As I understand the C++ standard, creation > > of the temporary is rather triggered by the fact that a value is bound > > to a function *argument* of reference type. > > I am confused about what you are describing. As far as mechanics of > function calls goes, references are just pointers: > http://mentorembedded.github.io/cxx-abi/abi.html#reference-parameter I was not refering to the ABI, but the C++ standard semantics that define what happen when you pass an *object* as argument to a function that expects a *reference* parameter. See e.g.: http://en.cppreference.com/w/cpp/language/reference_initialization References are initialized in the following situations: [...] 3) In a function call expression, when the function parameter has reference type [...] The effects of reference initialization are: [...] if the reference is [...] lvalue reference to const: [...] a temporary of type T is constructed and copy-initialized from object. The reference is then bound to this temporary [ B.t.w. note that for full compatibility with C++, we might also need to invoke the *constructor* when creating the temporary, not just the destructor afterwards. ] > > For example, if we had a function taking a "const int &" argument, then > > passing an integer constant to that function should result in the creation > > of a temporary, even though there is no function return value involved. > > ... for this case, as you point out, a temporary on the stack has to > be created and its address has to be passed as argument. GDB is broken > for this case currently and my patch set does not fix it. My point was that if you'd implemented construction of the temporary *there*, then the patch would handle that case as well, without needing two separate implementations. > > It seems to me the proper place to handle this would be the TYPE_CODE_REF > > case in value_arg_coerce, where we currently have this comment: > > > > /* Cast the value to the reference's target type, and then > > convert it back to a reference. This will issue an error > > if the value was not previously in memory - in some cases > > we should clearly be allowing this, but how? */ > > I have not thought enough about "any" function argument in general as > it can in general be a bad thing. But I agree that there could be > exceptions made for cases like this. I can take this up as a follow up > task after this patch set is either accepted or abandoned. The C++ standard says that if the function accepts a const reference, then *any* object of that type can be passed, and will always lead to creation of a temporary (unless the object is already an lvalue). This should make it safe to do the same in GDB as well. > > I see. This is indeed a good argument for temporaries to persist longer > > than a single inferior call. We could still *allocate* (and initialize) > > the temporary when processing function arguments for the "outer" call, > > though, see above. > > How do we distinguish between which func arg can be copied on to the > stack and which cannot? As mentioned above, it should always be safe if we have a const reference. (And if we don't, the call *should* fail even if we pass the return value of another function call, since it wouldn't be allowed in C++ either.) > May be we could, but GDB already creates > temporary copies for objects returned by value when the ABI requires > that the return value's address be passed as a hidden first arg. My > patch set actually derives inspiration from this; why not treat all > return values like this instead of only when the ABI requires it? I really feel this attempts to address the problem at the wrong point. Not only do you not handle arguments that aren't function return values, it would be difficult to get constructor calls correct (see above), and you create mirrored values even for return values that are *not* used as function arguments subsequently ... > > Another point: Even if we allow for temporaries to persist, I'm still > > not sure I understand the need for the new lval_mirrored_on_inferior_stack > > type. Why can't they just be regular (non-lazy) lval_memory values? Those > > already both refer to an inferior address and cache the contents in GDB > > memory. At the point the temporaries in the inferior disappear, those > > values could then be flipped to non_lval. > > I agree that the new lval type is not required in principle. However, > I brought them in so that it is clear as to how they have actually > come to exist in that way at all. I can remove them it if it seems > like noise. Yes, I think it would be better to just use lval_memory. There isn't really anything special about those values, *except* that might have to clean them up later; and for that, we have to keep them on a separate list anyway. [ As an aside, I'm wondering whether it wouldn't be cleaner to keep that list of on-stack temporaries associated with the current *thread* instead of an expression; it might be more natural since they reside on the thread stack, and call_function_by_hand already uses the thread struct, so no need to pass an expression all the way down into it. Also, infrun then might verify that temporaries were indeed cleaned up before restarting execution of the thread (for anything except inferior calls). ] > > (Actually, I'm not seeing > > anywhere in your current patches where lval_mirrored_on_inferior_stack > > values are marked invalid once the inferior stack contents disappear?) > > Ah, Catch! It seems like I generated the diff from a wrong commit. > Will shortly send the v3 of the patch set which has this correctly > handled. Note that 2/2 of the v3 seems to be missing the actual patch ... > > A final concern is that leaving temporaries on the stack after an inferior > > call is finishes just seems a bit fragile, in particular since they're > > *below* the thread's SP value at times, making them potentially vulnerable > > to being overwritten by signal handlers etc. Now I *think* this is not > > a problem in current GDB (with your patch) since we will not be running > > the inferior thread before expression evaluation ends, *except* for > > executing further inferior calls, and those will again adjust the SP. > > But future modifications to epression evaluation logic will have to > > keep this in mind, so there should at least be a comment somewhere ... > > I will add a comment for this. However, I am not sure how an > expression evaluation (involving inferior function calls) can be > performed when the inferior thread is actually running. As I said, I agree that this cannot really happen with current code. > > PS: Sorry for the delay in replying, I was out of office for a bit and > > then got sidetracked with other stuff. I'll try to be more prompt in > > further discussion on this topic. I certainly appreciate you working > > on this; improving GDB's C++ debugging capabilities is important! > > Thanks a lot for actually taking time to look at this. The gymnastics > of this patch set should not be required iff and when the 'compile' > command can get going for C++. Until then, it will be great if we can > get GDB to do "obvious" things correctly. Agreed. Thanks, Ulrich -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-21 11:15 ` Ulrich Weigand @ 2014-10-21 20:30 ` Siva Chandra 2014-10-21 21:07 ` Siva Chandra 2014-10-22 17:00 ` Ulrich Weigand 0 siblings, 2 replies; 16+ messages in thread From: Siva Chandra @ 2014-10-21 20:30 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Tue, Oct 21, 2014 at 4:15 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > I was not refering to the ABI, but the C++ standard semantics that > define what happen when you pass an *object* as argument to a function > that expects a *reference* parameter. See e.g.: > http://en.cppreference.com/w/cpp/language/reference_initialization > > References are initialized in the following situations: > [...] > 3) In a function call expression, when the function parameter > has reference type > [...] > The effects of reference initialization are: > [...] > if the reference is [...] lvalue reference to const: > [...] > a temporary of type T is constructed and copy-initialized from > object. The reference is then bound to this temporary I do not think applies in general for const references. IIUC, it applies to prvalues/literals [section 12.2 in the C++ std]. For all other kind of values, the two cases above this point should be applied. (Moreover, if it applies to all const reference arguments, what benefit are references bringing in over value arguments? One could just pass const value args.) > [ B.t.w. note that for full compatibility with C++, we might also need > to invoke the *constructor* when creating the temporary, not just the > destructor afterwards. ] This is another reason why targeting return values is simpler: we do not need to construct anything (via a constructor) as the inferior function would have constructed it appropriately. We only need to invoke the destructor on these objects. In the current state of the union however: 1. GDB does not distinguish between const and non-const reference arguments. IMO, this is semantically OK as the compiler would have ensured the inferior function does not modify values pointed to by const-references. 2. For value arguments which need to be passed as a reference (when the ABI determines so), GDB still does what it does in #1 above. This IMO is wrong in the case on non-const value arguments as non-const value arguments can be written to in the called inferior function. The correct fix for this would be to invoke the constructor and destructor. (At the very least, make a bit copy on the stack which will not need construction or destruction, but see point 3 below.) 3. For values passed by value, GDB does not invoke a copy constructor, but only does a bit copy. Consequently, invocation of a destructor is also not required. I think this is OK for 99% of the use cases, but could be fixed for the remaining cases. 4. GDB does not invoke destructors on function return values returned by value. This is not OK as it can potentially leak inferior memory. >> > For example, if we had a function taking a "const int &" argument, then >> > passing an integer constant to that function should result in the creation >> > of a temporary, even though there is no function return value involved. >> >> ... for this case, as you point out, a temporary on the stack has to >> be created and its address has to be passed as argument. GDB is broken >> for this case currently and my patch set does not fix it. > > My point was that if you'd implemented construction of the temporary *there*, > then the patch would handle that case as well, without needing two separate > implementations. > >> > It seems to me the proper place to handle this would be the TYPE_CODE_REF >> > case in value_arg_coerce, where we currently have this comment: >> > >> > /* Cast the value to the reference's target type, and then >> > convert it back to a reference. This will issue an error >> > if the value was not previously in memory - in some cases >> > we should clearly be allowing this, but how? */ >> >> I have not thought enough about "any" function argument in general as >> it can in general be a bad thing. But I agree that there could be >> exceptions made for cases like this. I can take this up as a follow up >> task after this patch set is either accepted or abandoned. > > The C++ standard says that if the function accepts a const reference, > then *any* object of that type can be passed, and will always lead to > creation of a temporary (unless the object is already an lvalue). Function arguments could be xvalues. IIUC, temporaries are created only for prvalues. You can point me to the appropriate section in the C++ standard if I am wrong. > This should make it safe to do the same in GDB as well. > >> > I see. This is indeed a good argument for temporaries to persist longer >> > than a single inferior call. We could still *allocate* (and initialize) >> > the temporary when processing function arguments for the "outer" call, >> > though, see above. >> >> How do we distinguish between which func arg can be copied on to the >> stack and which cannot? > > As mentioned above, it should always be safe if we have a const reference. > (And if we don't, the call *should* fail even if we pass the return value > of another function call, since it wouldn't be allowed in C++ either.) Functions can have value arguments and can also return by value. This piece of code is valid C++ without involving const references in a chained function call: class A { public: int a; A () { } A (const A &obj) { a = obj.a; } int geta (void); }; int A::geta () { return a; } A func (A a) { A n; n.a = a.a + 1000; return n; } int main (void) { A a; a.a = 0; a.a = func (func (func (a))).geta(); /* function chain */ return 0; } >> May be we could, but GDB already creates >> temporary copies for objects returned by value when the ABI requires >> that the return value's address be passed as a hidden first arg. My >> patch set actually derives inspiration from this; why not treat all >> return values like this instead of only when the ABI requires it? > > I really feel this attempts to address the problem at the wrong point. > Not only do you not handle arguments that aren't function return values, > it would be difficult to get constructor calls correct (see above), and As I mentioned above, return values will not need a constructor invocation. > you create mirrored values even for return values that are *not* used I think > as function arguments subsequently ... 1. The last return value is mirrored on the stack even if not used as an argument to a subsequent function call. But, this is necessary anyway. We clean it up after the expression is evaluated. 2. Intermediate non-class(struct/union) return values also get mirrored on stack even though they might not be used as a function args. But, since expressions are actually "interpreted" rather than "compiled" from within GDB, there is no way to determine which need a copy, which do not. >> > Another point: Even if we allow for temporaries to persist, I'm still >> > not sure I understand the need for the new lval_mirrored_on_inferior_stack >> > type. Why can't they just be regular (non-lazy) lval_memory values? Those >> > already both refer to an inferior address and cache the contents in GDB >> > memory. At the point the temporaries in the inferior disappear, those >> > values could then be flipped to non_lval. >> >> I agree that the new lval type is not required in principle. However, >> I brought them in so that it is clear as to how they have actually >> come to exist in that way at all. I can remove them it if it seems >> like noise. > > Yes, I think it would be better to just use lval_memory. There isn't really > anything special about those values, *except* that might have to clean them > up later; and for that, we have to keep them on a separate list anyway. OK. I will remove the new lval type. > [ As an aside, I'm wondering whether it wouldn't be cleaner to keep that list > of on-stack temporaries associated with the current *thread* instead of an > expression; it might be more natural since they reside on the thread stack, > and call_function_by_hand already uses the thread struct, so no need to > pass an expression all the way down into it. Also, infrun then might > verify that temporaries were indeed cleaned up before restarting execution > of the thread (for anything except inferior calls). ] > >> > (Actually, I'm not seeing >> > anywhere in your current patches where lval_mirrored_on_inferior_stack >> > values are marked invalid once the inferior stack contents disappear?) >> >> Ah, Catch! It seems like I generated the diff from a wrong commit. >> Will shortly send the v3 of the patch set which has this correctly >> handled. > > Note that 2/2 of the v3 seems to be missing the actual patch ... Sent it now. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-21 20:30 ` Siva Chandra @ 2014-10-21 21:07 ` Siva Chandra 2014-10-22 17:00 ` Ulrich Weigand 1 sibling, 0 replies; 16+ messages in thread From: Siva Chandra @ 2014-10-21 21:07 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Tue, Oct 21, 2014 at 1:30 PM, Siva Chandra <sivachandra@google.com> wrote: > On Tue, Oct 21, 2014 at 4:15 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: >> I was not refering to the ABI, but the C++ standard semantics that >> define what happen when you pass an *object* as argument to a function >> that expects a *reference* parameter. See e.g.: >> http://en.cppreference.com/w/cpp/language/reference_initialization >> >> References are initialized in the following situations: >> [...] >> 3) In a function call expression, when the function parameter >> has reference type >> [...] >> The effects of reference initialization are: >> [...] >> if the reference is [...] lvalue reference to const: >> [...] >> a temporary of type T is constructed and copy-initialized from >> object. The reference is then bound to this temporary > > I do not think applies in general for const references. IIUC, it > applies to prvalues/literals [section 12.2 in the C++ std]. For all > other kind of values, the two cases above this point should be > applied. I should have said prvalues of non-class type. > Function arguments could be xvalues. IIUC, temporaries are created > only for prvalues. You can point me to the appropriate section in the > C++ standard if I am wrong. Same here. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-21 20:30 ` Siva Chandra 2014-10-21 21:07 ` Siva Chandra @ 2014-10-22 17:00 ` Ulrich Weigand 2014-10-23 15:07 ` Siva Chandra 1 sibling, 1 reply; 16+ messages in thread From: Ulrich Weigand @ 2014-10-22 17:00 UTC (permalink / raw) To: Siva Chandra; +Cc: gdb-patches Siva Chandra wrote: > On Tue, Oct 21, 2014 at 4:15 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > > I was not refering to the ABI, but the C++ standard semantics that > > define what happen when you pass an *object* as argument to a function > > that expects a *reference* parameter. See e.g.: > > http://en.cppreference.com/w/cpp/language/reference_initialization > > > > References are initialized in the following situations: > > [...] > > 3) In a function call expression, when the function parameter > > has reference type > > [...] > > The effects of reference initialization are: > > [...] > > if the reference is [...] lvalue reference to const: > > [...] > > a temporary of type T is constructed and copy-initialized from > > object. The reference is then bound to this temporary > > I do not think applies in general for const references. IIUC, it > applies to prvalues/literals [section 12.2 in the C++ std]. For all > other kind of values, the two cases above this point should be > applied. > I should have said prvalues of non-class type. You're right that class and non-class types need to be distinguished, sorry about the confusion. [ It seems this is an area that changed between C++98 and the current standard; in C++98 the implementation would have been free to chose to either bind directly to the rvalue or else construct a temporary. ] In any case, there are still at least some cases where we should create temporaries at the point an argument is passed. But -as discussed below- you're right that there are other cases where we need to create a temporary to hold a function return value. So I guess in GDB the infrastructure we're about to set up should allow for creation and tracking of temporaries for either function arguments or return values. > > [ B.t.w. note that for full compatibility with C++, we might also need > > to invoke the *constructor* when creating the temporary, not just the > > destructor afterwards. ] > > This is another reason why targeting return values is simpler: we do > not need to construct anything (via a constructor) as the inferior > function would have constructed it appropriately. We only need to > invoke the destructor on these objects. That's another good point I missed. You've now convinced me we definitely need to track return values, in those cases where they were constructed by the inferior according to the ABI. (Which should be more-or-less the cases where language_pass_by_reference returns true.) Those instances should then result in GDB value objects that point to the on-stack temporary; and if such objects are passed to further calls, that on-stack temporary should be used directly. I'm still not quite sure about the remaining cases (e.g. class types with no constructors that are returned e.g. in registers according to the ABI); it still seems preferable to me to have those pushed to the stack only at the time they are used as arguments to another call. > In the current state of the union however: > > 1. GDB does not distinguish between const and non-const reference > arguments. IMO, this is semantically OK as the compiler would have > ensured the inferior function does not modify values pointed to by > const-references. Well, the only point in making a distinction in GDB would be to error out when the user attempts to make an inferior call using an argument that would be invalid in C++ (e.g. passing a prvalue to a non-const reference argument). > 2. For value arguments which need to be passed as a reference (when > the ABI determines so), GDB still does what it does in #1 above. This > IMO is wrong in the case on non-const value arguments as non-const > value arguments can be written to in the called inferior function. The > correct fix for this would be to invoke the constructor and > destructor. (At the very least, make a bit copy on the stack which > will not need construction or destruction, but see point 3 below.) Agreed. > 3. For values passed by value, GDB does not invoke a copy constructor, > but only does a bit copy. Consequently, invocation of a destructor is > also not required. I think this is OK for 99% of the use cases, but > could be fixed for the remaining cases. Hmmm, I thought the ABI requires the use of a temporary in all cases where a non-trivial copy constructor exists, so this shouldn't be an issue? > 4. GDB does not invoke destructors on function return values returned > by value. This is not OK as it can potentially leak inferior memory. Agreed. [ Snipped some more arguments why we need to track temporaries for return values, since you've already convinced me :-) ] > > you create mirrored values even for return values that are *not* used I think > > as function arguments subsequently ... > > 1. The last return value is mirrored on the stack even if not used as > an argument to a subsequent function call. But, this is necessary > anyway. We clean it up after the expression is evaluated. > 2. Intermediate non-class(struct/union) return values also get > mirrored on stack even though they might not be used as a function > args. But, since expressions are actually "interpreted" rather than > "compiled" from within GDB, there is no way to determine which need a > copy, which do not. Well, the way to determine whether we need to copy in those cases would be to actually perform the copy at the point the value is used as *argument*. As I understand, those are exactly the types of values that would be handled if we allowed creation of temporaries when passing a non-class prvalue as const reference. [ Passing as value should be fine for such types anyway. ] So in summary, what looks the best approach to me right now would be: - Do something along the lines of your patch (with the changes already discussed) to preserve return value temporaries as lval_memory objects in those cases where they are mandated by the ABI (i.e. for types that have a non-trivial copy constructor or destructor). - (As in your patch) Keep those values on a list, and once the current expression evaluation is finished, invoke destructors and convert the value to non_lval if necessary. - Add code to create temporaries when passing non_lval values of types without non-trivial copy constructors or destructors as const references. - Add code to invoke copy constructors when passing objects by value via temporary as mandated by the ABI. Keep such temporaries on the list for the destructors to be called later. Of course, all that can be done in stages. Does this look reasonable now or am I still missing something? Bye, Ulrich -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-22 17:00 ` Ulrich Weigand @ 2014-10-23 15:07 ` Siva Chandra 2014-10-23 16:09 ` Ulrich Weigand 0 siblings, 1 reply; 16+ messages in thread From: Siva Chandra @ 2014-10-23 15:07 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches I agree with everything you have said and listed. I have one last point to make. On Wed, Oct 22, 2014 at 9:59 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > - Do something along the lines of your patch (with the changes already > discussed) to preserve return value temporaries as lval_memory objects > in those cases where they are mandated by the ABI (i.e. for types that > have a non-trivial copy constructor or destructor). Restricting to just those values whose address is returned in a hidden param (per ABI) is OK, but an implementation detail made me to include all types of return values. There are two times when a return value's address is required: 1. When a method is invoked on the return value: GDB has to evaluate the 'this' pointer. This is done in eval.c. 2. When the return value is in turn passed as a parameter to a function expecting a reference: GDB has to evaluate the address of the value and generate a TYPE_CODE_REF value from it. This logic is in 'value_arg_coerce' in infcall.c. For objects returned in registers, having logic to create a copy on the stack for situations like 2 is fine. However, for situations like 1, I do not think there is any way to tell whether one is dealing with an intermediate return value or not. In which case, we are hit by the comment at eval.c:1405. This is the reason why I have return values returned in registers copied on to the stack in my patch. Note that, doing a bit copy of objects returned in registers should be just fine as they do not have non-trivial copy constructors or destructors (if they do, then ABI says that they wont be returned in registers). One way to get around the comment at eval.c:1405 is to make copies of only those objects which are not_lval and which do not have non-trivial copy-ctors or d-tors. The same thing has be to done for 2 anyway if we take this route, meaning that we change the flow in two places (infcall.c and eval.c). If you feel that this is OK, I will take this route. My intention was to keep the existing logic as is for as much as possible. If we keep what I have in my patch, then we only need to change 'value_arg_coerce' in infrun.c (and that too, only to enable passing non-lvalue parameters to functions expecting const-reference arguments). ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-23 15:07 ` Siva Chandra @ 2014-10-23 16:09 ` Ulrich Weigand 2014-10-23 23:31 ` Siva Chandra 0 siblings, 1 reply; 16+ messages in thread From: Ulrich Weigand @ 2014-10-23 16:09 UTC (permalink / raw) To: Siva Chandra; +Cc: gdb-patches Siva Chandra wrote: > Restricting to just those values whose address is returned in a hidden > param (per ABI) is OK, but an implementation detail made me to include > all types of return values. There are two times when a return value's > address is required: > > 1. When a method is invoked on the return value: GDB has to evaluate > the 'this' pointer. This is done in eval.c. Ah, I knew there was something else I was missing :-) In this case, I agree with the rest of your explanation. Please add a comment in the final version of the patch that explains why the extra copy is necessary. There's just one minor change I think would be good: can we allocate that extra copy on the stack at least only for *class* types, then? I'd prefer to avoid this for the common case of routines just returning a scalar. Thanks, Ulrich -- Dr. Ulrich Weigand GNU/Linux compilers and toolchain Ulrich.Weigand@de.ibm.com ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-23 16:09 ` Ulrich Weigand @ 2014-10-23 23:31 ` Siva Chandra 0 siblings, 0 replies; 16+ messages in thread From: Siva Chandra @ 2014-10-23 23:31 UTC (permalink / raw) To: Ulrich Weigand; +Cc: gdb-patches On Thu, Oct 23, 2014 at 9:09 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote: > In this case, I agree with the rest of your explanation. Please add a > comment in the final version of the patch that explains why the extra > copy is necessary. > > There's just one minor change I think would be good: can we allocate that > extra copy on the stack at least only for *class* types, then? I'd prefer > to avoid this for the common case of routines just returning a scalar. I will soon send a new version of the patch with all the suggested changes in this thread. Thanks, Siva Chandra ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-01 0:42 ` Siva Chandra 2014-10-01 13:15 ` Ulrich Weigand @ 2014-10-09 0:02 ` Siva Chandra 2014-10-15 13:43 ` Siva Chandra 1 sibling, 1 reply; 16+ messages in thread From: Siva Chandra @ 2014-10-09 0:02 UTC (permalink / raw) To: gdb-patches On Tue, Sep 30, 2014 at 5:42 PM, Siva Chandra <sivachandra@google.com> wrote: > On Fri, Sep 26, 2014 at 6:29 AM, Siva Chandra <sivachandra@google.com> wrote: >> This patch series enables having chained function calls in >> expressions. An example of a chained function call is shown in PR >> c++/11606. It has an example of a chain of two function calls. This >> patch series enables chains of any number of function calls. >> >> Currently, an inferior function call is handled via >> call_function_by_hand. The value returned by the inferior function is >> copied into a GDB value whose lval_type is not_lval. Its contents are >> stored within the value irrespective of whether the return value is in >> inferior memory or in a register. Consequently, any subsequent >> function call in the expression which requires this value's address as >> an argument throws an error as the value is not in inferior memory. >> >> This patch series keeps most of the current flow intact, except that >> the value returned by the inferior function is made to be a new >> lval_type called lval_mirrored_on_inferior_stack. These values have a >> mirrored value of lval_type lval_memory which reside on the inferior >> stack. They reside on the stack only for the duration for which the >> expression is evaluated. This enables value_address to return the >> address of the stack mirror instead of throwing an error. >> >> Patch 1/2 - Adds new lval_type named lval_mirrored_on_inferior_stack. >> Also adds support for values with this lval_type. >> Patch 2/2 - Enables chained function calls by mirroring values >> returned by inferior functions in the inferior stack. >> >> Patch 2/2 only targets values returned by call_function_by_hand. I >> think similar things can done for call_internal_function and >> call_xmethod. I will extend the idea to these functions as well after >> this patch series is approved (if at all). > > I used global state in patch 2/2. I thought eliminating that would not > be a straightforward task. However, I spent time looking into it and > it turned out to be much simpler than I had anticipated. I have now > updated both 1/2 and 2/2 to not use any global state. I have also > regression tested and found that a known failure now passes. Will > follow up with v2 of 1/2 and 2/2 both. Ping. Links to the other patches in this series: https://sourceware.org/ml/gdb-patches/2014-10/msg00001.html https://sourceware.org/ml/gdb-patches/2014-10/msg00002.html ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/2] Make chained function calls in expressions work 2014-10-09 0:02 ` Siva Chandra @ 2014-10-15 13:43 ` Siva Chandra 0 siblings, 0 replies; 16+ messages in thread From: Siva Chandra @ 2014-10-15 13:43 UTC (permalink / raw) To: gdb-patches On Wed, Oct 8, 2014 at 5:02 PM, Siva Chandra <sivachandra@google.com> wrote: > On Tue, Sep 30, 2014 at 5:42 PM, Siva Chandra <sivachandra@google.com> wrote: >> On Fri, Sep 26, 2014 at 6:29 AM, Siva Chandra <sivachandra@google.com> wrote: >>> This patch series enables having chained function calls in >>> expressions. An example of a chained function call is shown in PR >>> c++/11606. It has an example of a chain of two function calls. This >>> patch series enables chains of any number of function calls. >>> >>> Currently, an inferior function call is handled via >>> call_function_by_hand. The value returned by the inferior function is >>> copied into a GDB value whose lval_type is not_lval. Its contents are >>> stored within the value irrespective of whether the return value is in >>> inferior memory or in a register. Consequently, any subsequent >>> function call in the expression which requires this value's address as >>> an argument throws an error as the value is not in inferior memory. >>> >>> This patch series keeps most of the current flow intact, except that >>> the value returned by the inferior function is made to be a new >>> lval_type called lval_mirrored_on_inferior_stack. These values have a >>> mirrored value of lval_type lval_memory which reside on the inferior >>> stack. They reside on the stack only for the duration for which the >>> expression is evaluated. This enables value_address to return the >>> address of the stack mirror instead of throwing an error. >>> >>> Patch 1/2 - Adds new lval_type named lval_mirrored_on_inferior_stack. >>> Also adds support for values with this lval_type. >>> Patch 2/2 - Enables chained function calls by mirroring values >>> returned by inferior functions in the inferior stack. >>> >>> Patch 2/2 only targets values returned by call_function_by_hand. I >>> think similar things can done for call_internal_function and >>> call_xmethod. I will extend the idea to these functions as well after >>> this patch series is approved (if at all). >> >> I used global state in patch 2/2. I thought eliminating that would not >> be a straightforward task. However, I spent time looking into it and >> it turned out to be much simpler than I had anticipated. I have now >> updated both 1/2 and 2/2 to not use any global state. I have also >> regression tested and found that a known failure now passes. Will >> follow up with v2 of 1/2 and 2/2 both. > > Ping. Links to the other patches in this series: > > https://sourceware.org/ml/gdb-patches/2014-10/msg00001.html > https://sourceware.org/ml/gdb-patches/2014-10/msg00002.html Ping. ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2014-10-23 23:31 UTC | newest] Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-09-26 13:29 [PATCH 0/2] Make chained function calls in expressions work Siva Chandra 2014-10-01 0:42 ` Siva Chandra 2014-10-01 13:15 ` Ulrich Weigand 2014-10-01 18:05 ` Siva Chandra 2014-10-01 18:26 ` Siva Chandra 2014-10-20 16:01 ` Ulrich Weigand 2014-10-20 19:56 ` Siva Chandra 2014-10-21 11:15 ` Ulrich Weigand 2014-10-21 20:30 ` Siva Chandra 2014-10-21 21:07 ` Siva Chandra 2014-10-22 17:00 ` Ulrich Weigand 2014-10-23 15:07 ` Siva Chandra 2014-10-23 16:09 ` Ulrich Weigand 2014-10-23 23:31 ` Siva Chandra 2014-10-09 0:02 ` Siva Chandra 2014-10-15 13:43 ` Siva Chandra
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).