On Wed, Jan 9, 2019 at 5:05 AM Pavel Labath <pa...@labath.sk> wrote: > On 08/01/2019 21:57, Jonas Devlieghere wrote: > > Before I got around to coding this up I realized you can't take the > > address of constructors in C++, so the function address won't work as an > > identifier. > > > > You gave up way too easily. :P >
I counted on you having something in mind, it sounded too obvious for you to have missed. ;-) I realized that constructors are going to be tricky, but I didn't want > to dive into those details until I knew if you liked the general idea. > The most important thing to realize here is that for the identifier > thingy to work, you don't actually need to use the address of that > method/constructor as the identifier. It is sufficient to have something > that can be deterministically computed from the function. Then you can > use the address of *that* as the identifier. > I was thinking about that yesterday. I still feel like it would be better to have this mapping all done at compile time. I was considering some kind of constexpr hashing but that sounded overkill. > I've created a very simple prototype <https://godbolt.org/z/_xDt5r>, > where I do just that. The way I handle constructors there is that I > create a special class template (construct), whose instantiations are > going to be unique for each constructor (I achieve that by making the > class name and the constructor argument types the template parameters of > that function). Then I can take the address of the static member > function inside this class (&construct<class, arguments...>::doit), and > use *that* as the ID. Clever! As a nice side-effect, the "doit" method actually does invoke the > constructor in question, so I can also use that in the replay code to > treat constructors like any other method that returns an object. > This is really neat. > I also do the same thing for (non-static) member functions via the > "invoke" template, because even though it is possible to take the > address of those, it is very hard to do anything else with the retrieved > pointer. So the effect of this that in the rest of the code, I only have > to work with free functions, as both constructors and member functions > are converted into equivalent free functions. I haven't tried to handle > destructors yet, but I don't think those should pose any problems that > we haven't encountered already. > > The example also show how you can use templates to automatically > generate replay code for "simple" (i.e. those where you can > (de)serialize each argument independently) functions, and then uses that > to record/replay a very simple API. > > You can see it in action like this: > $ g++ a.cc # compile > $ ./a.out 2>/tmp/recording # generate the recording > SBFoo 47 42 > Method 1 2 > Static 10 11 > $ cat /tmp/recording > 0 # ID of the constructor > 47 # constructor arg 1 > 42 # constructor arg 2 > 0x7ffd74d9a0f7 # constructor result > 1 # id of SBFoo::Method > 0x7ffd74d9a0f7 # this > 1 # arg 1 > 2 # arg 2 > 2 # id of SBFoo::Static > 10 # arg 1 > 11 # arg 2 > $ ./a.out 1 < /tmp/recording # replay the recording > SBFoo 47 42 > SBFoo 42 47 > Method 1 2 > Static 10 11 > > Note that when replaying the SBFoo constructor is called twice. This is > because this code does not attempt to track the object instances in any > way... it just creates a new one each time. This obviously needs to be > fixed, but that's independent of the function ID issue. > > hope you find that useful, > pl > Definitely, thank you for taking the time to code up a prototype. Cheers, Jonas
_______________________________________________ lldb-dev mailing list lldb-dev@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev