This is an archive of the discontinued LLVM Phabricator instance.

SBFile support in SBCommandReturnObject
ClosedPublic

Authored by lawrence_danna on Oct 3 2019, 4:37 PM.

Details

Summary

This patch add SBFile interfaces to SBCommandReturnObject, and
removes the internal callers of its FILE* interfaces.

Event Timeline

lawrence_danna created this revision.Oct 3 2019, 4:37 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 3 2019, 4:37 PM

deserializer hijinks

lawrence_danna marked an inline comment as done.Oct 3 2019, 11:37 PM
lawrence_danna added inline comments.
lldb/source/Utility/ReproducerInstrumentation.cpp
38 ↗(On Diff #223143)

@JDevlieghere advice please.

labath added inline comments.Oct 4 2019, 2:05 AM
lldb/include/lldb/Utility/ReproducerInstrumentation.h
19

This is definitely not right. Utility should never include other lldb libraries. I think this stuff should be defined in the API folder. Either in the SBFile.cpp directly, or some additional cpp file.

lldb/source/Utility/ReproducerInstrumentation.cpp
38 ↗(On Diff #223143)

This is not totally surprising as SBDebugger::SetInputFile ignores the input SBFile when it's in replay mode. However, it still doesn't seem like the right fix. I am guessing that something special needs to happen in the record/replay logic of the SBFile constructor, but off-hand, it's not fully clear to me what would that be.

I think ideally, we'd have the reproducer shadowing that's currently done in SBDebugger::SetInputFileHandle kick in earlier (in the SBFile constructor) so that it covers all SBFiles, and not just those that later become the debugger input handles, but I don't think it should be on you to make all of that work. Maybe the appropriate fix would be to just make sure the SBFile constructor creates empty objects and acknowledge that reproducers won't work for all SBFiles until someone actually implements the appropriate support for them.

JDevlieghere added inline comments.Oct 4 2019, 9:23 AM
lldb/source/Utility/ReproducerInstrumentation.cpp
38 ↗(On Diff #223143)

Thanks for the great explanation Pavel, I share your thoughts on this. So to make this work you'll want to remove the LLDB_REGISTER_CONSTRUCTOR for SBFile that take a file descriptor or a FILE* (which looks like it's currently missing?) and have custom doit implementation (similar to what I did in SBDebugger) that just returns and empty SBFile.

a different deserializer fix for SBFile

lawrence_danna marked 4 inline comments as done.Oct 4 2019, 10:59 AM
lawrence_danna added inline comments.
lldb/source/Utility/ReproducerInstrumentation.cpp
38 ↗(On Diff #223143)

custom doits for the constructor aren't enough. That won't stop the serializer from using reinterpret_cast on SBFiles that are passed by value to other recorder-instrumented functions. I've updated the patch with a somewhat more reasonable solution that doesn't mess up the library dependencies.

labath added inline comments.Oct 4 2019, 11:50 AM
lldb/source/Utility/ReproducerInstrumentation.cpp
38 ↗(On Diff #223143)

That won't stop the serializer from using reinterpret_cast on SBFiles that are passed by value to other recorder-instrumented functions.

I find that surprising. At this level, what makes SBFile different from any other SB class that is passed around by value? I'd expect that the reproducer should be able to copy the (empty) SBFile object just like every other class (once we actually get it to construct an empty SBFile from a FileSP)

lawrence_danna marked an inline comment as done.

rebased

labath added inline comments.Oct 7 2019, 5:04 AM
lldb/include/lldb/Utility/ReproducerInstrumentation.h
255–257

This still doesn't seem right to me. Though you have removed the direct #include, you only managed to do that since you've forward-declared the class manually -- which I'd consider "cheating". If this is indeed the right solution (which I am not convinced of yet), then this specialization should be somewhere in the API folder (SBFile.cpp, most likely)

lldb/source/API/SBFile.cpp
111

I don't think these are right because there nothing here to connect the dummy implementation (used for replay) with the invocation of the actual constructor (happening when recording). (The strings are only used for debugging purposes).

This should be something like: R.Register<SBFile *()>(&construct<SBFile()>::doit, &dummy, ...). Note that the first argument is the same blurb as the thing used in the LLDB_REGISTER_CONSTRUCTOR macro in the constructor, and it's how the reproducer connects the two methods. Maybe after fixing these (you'll need the register FileSP version of the constructor too), you won't need the other changes?

That said, I am surprised you were able to get even this far with this code. Jonas, shouldn't there be some kind of an assertion if you call an unregistered method/constructor during recording?

lawrence_danna marked an inline comment as done.

use is_trivially_copyable

JDevlieghere accepted this revision.Oct 7 2019, 4:34 PM
JDevlieghere added inline comments.
lldb/source/API/SBCommandReturnObject.cpp
312

I'd drop the return.

318

Same here

This revision is now accepted and ready to land.Oct 7 2019, 4:34 PM
lawrence_danna marked an inline comment as done.Oct 7 2019, 4:35 PM
lawrence_danna added inline comments.
lldb/include/lldb/Utility/ReproducerInstrumentation.h
255–257

I figured out how to do it without referring to SBFile at all. What we really want is std::is_trivially_copyable

Objects of trivially-copyable types are the only C++ objects that may be safely copied with std::memcpy or serialized to/from binary files with std::ofstream::write()/std::ifstream::read().

That's exactly what we're doing here.

lawrence_danna marked 5 inline comments as done.

get rid of dummy registrations in SBFile.cpp

lldb/source/API/SBFile.cpp
111

Yea, and furthermore I don't need these dummy registrations at all. None of the SBFile constructors can be replayed in any meaningful way.
I can just get rid of these and record them as LLDB_RECORD_DUMMY

Harbormaster completed remote builds in B39128: Diff 223699.
labath added a comment.Oct 9 2019, 7:12 AM

Some nits inline, otherwise it looks fine to me.

lldb/include/lldb/Utility/ReproducerInstrumentation.h
243

clang-format this

lldb/source/API/SBCommandReturnObject.cpp
118–142

Have these methods delegate to one another (I'm not sure which should be the "base" one TBH).

133

Why not just file_sp->Write(GetOutput(), GetOutputSize()) ? It invoking formatting function for this seems overkill (and ideally I would like to remove formatted output capabilities from the file class completely).

275–284

Here the need isn't as pressing, but I'd probably have these delegate too.

This revision was automatically updated to reflect the committed changes.