<div dir="ltr"><div>On Tue, Jan 8, 2019 at 8:27 AM Frédéric Riss <<a href="mailto:friss@apple.com">friss@apple.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><br>
<br>
> On Jan 8, 2019, at 1:25 AM, Pavel Labath <<a href="mailto:pavel@labath.sk" target="_blank">pavel@labath.sk</a>> wrote:<br>
> <br>
> On 07/01/2019 22:45, Frédéric Riss wrote:<br>
>>> On Jan 7, 2019, at 11:31 AM, Pavel Labath via lldb-dev <<a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a> <mailto:<a href="mailto:lldb-dev@lists.llvm.org" target="_blank">lldb-dev@lists.llvm.org</a>>> wrote:<br>
>>> <br>
>>> On 07/01/2019 19:26, Jonas Devlieghere wrote:<br>
>>>> On Mon, Jan 7, 2019 at 1:40 AM Pavel Labath <<a href="mailto:pavel@labath.sk" target="_blank">pavel@labath.sk</a> <mailto:<a href="mailto:pavel@labath.sk" target="_blank">pavel@labath.sk</a>><mailto:<a href="mailto:pavel@labath.sk" target="_blank">pavel@labath.sk</a>>> wrote:<br>
>>>>    I've been thinking about how could this be done better, and the best<br>
>>>>    (though not ideal) way I came up with is using the functions address as<br>
>>>>    the key. That's guaranteed to be unique everywhere. Of course, you<br>
>>>>    cannot serialize that to a file, but since you already have a central<br>
>>>>    place where you list all intercepted functions (to register their<br>
>>>>    replayers), that place can be also used to assign unique integer IDs to<br>
>>>>    these functions. So then the idea would be that the SB_RECORD macro<br>
>>>>    takes the address of the current function, that gets converted to an ID<br>
>>>>    in the lookup table, and the ID gets serialized.<br>
>>>> It sound like you would generate the indices at run-time. How would that work with regards to the the reverse mapping?<br>
>>> In the current implementation, SBReplayer::Init contains a list of all intercepted methods, right? Each of the SB_REGISTER calls takes two arguments: The method name, and the replay implementation.<br>
>>> <br>
>>> I would change that so that this macro takes three arguments:<br>
>>> - the function address (the "runtime" ID)<br>
>>> - an integer (the "serialized" ID)<br>
>>> - the replay implementation<br>
>>> <br>
>>> This creates a link between the function address and the serialized ID. So when, during capture, a method calls SB_RECORD_ENTRY and passes in the function address, that address can be looked up and translated to an ID for serialization.<br>
>>> <br>
>>> The only thing that would need to be changed is to have SBReplayer::Init execute during record too (which probably means it shouldn't be called SBReplayer, but whatever..), so that the ID mapping is also available when capturing.<br>
>>> <br>
>>> Does that make sense?<br>
>> I think I understand what you’re explaining, and the mapping side of things makes sense. But I’m concerned about the size and complexity of the SB_RECORD macro that will need to be written. IIUC, those would need to take the address of the current function and the prototype, which is a lot of cumbersome text to type. It seems like having a specialized tool to generate those would be nice, but once you have a tool you also don’t need all this complexity, do you?<br>
>> Fred<br>
> <br>
> Yes, if the tool generates the IDs for you and checks that the macro invocations are correct, then you don't need the function prototype. However, that tool also doesn't come for free: Somebody has to write it, and it adds complexity in the form of an extra step in the build process.<br>
<br>
Definitely agreed, the complexity has to be somewhere.<br>
<br>
> My point is that this extended macro could provide all the error-checking benefits of this tool. It's a tradeoff, of course, and the cost here is a more complex macro invocation. I think the choice here is mostly down to personal preference of whoever implements this. However, if I was implementing this, I'd go for an extended macro, because I don't find the extra macro complexity to be too much. For example, this should be the macro invocation for SBData::SetDataFromDoubleArray:<br>
> <br>
> SB_RECORD(bool, SBData, SetDataFromDoubleArray, (double *, size_t),<br>
>    array, array_len);<br>
<br>
Yeah, this doesn’t seem so bad. For some reason I imagined it much more verbose. Note that a verification tool that checks that every SB method is instrumented correctly would still be nice (but it can come as a follow-up).<br></blockquote><div><br></div><div>It sounds like this should work but we should try it out to be sure. I'll rework the prototype to use the function address and update the thread with my findings. I also like the idea of using templates to generate the parsers so I'll try that as well. </div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
> It's a bit long, but it's not that hard to type, and all of this information should be present on the previous line, where SBData::SetDataFromDoubleArray is defined (I deliberately made the macro argument order match the function definition syntax).<br>
> <br>
> And this approach can be further tweaked. For instance, if we're willing to take the hit of having "weird" function definitions, then we can avoid the repetition altogether, and make the macro define the function too:<br>
> <br>
> SB_METHOD2(bool, SBData, SetDataFromDoubleArray, double *, array,<br>
>    size_t, array_len, {<br>
>  // Method body<br>
> })<br>
<br>
I personally don’t like this.<br>
<br>
Fred<br>
<br>
> This would also enable you to automatically capture method return value for the "object" results.<br>
> <br>
> pl<br>
<br>
</blockquote></div></div>