<div dir="ltr">Hi Greg<div><br></div><div>My comments are inlined.<br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 26, 2016 at 7:03 PM, Greg Clayton <span dir="ltr"><<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class=""><br>
> On Apr 26, 2016, at 1:50 AM, Abhishek Aggarwal via lldb-dev <<a href="mailto:lldb-dev@lists.llvm.org">lldb-dev@lists.llvm.org</a>> wrote:<br>
><br>
> Hi everyone<br>
><br>
> There has been previous discussions in this mailing list regarding Enabling Intel(R) Processor Trace collection in LLDB. A new APIs are being developed to be added to SB APIs that will provide raw traces (collected on lldb-server side). These APIs are Trace technology independent and hence can work for other Tracing technologies also. The decoding of the raw traces can be done outside LLDB. For details you can refer to the thread with the subject "Review of API and remote packets" started on March 31, 2016.<br>
><br>
> I am working on developing a Plugin that will use these new APIs to enable Intel(R) Processor Trace technology and collect raw trace data for the inferior being debugged by LLDB. The plugin will perform decoding on the trace data to present it as a meaningful information to the user of LLDB Debugger. I want to use this plugin through LLDB CLI. I have few questions regarding development of this plugin:<br>
><br>
> 1. What is the best way to develop this plugin? Should it be done as shown in "examples/plugins/commands/fooplugin.cpp" ( i.e. a C++ based solution and using 'plugin load <path_of_shared_lib>' command) or should I go for Python based solution to add new commands using Python functions?<br>
<br>
</span>I personally would add a new folder for all trace plug-ins:<br>
<br>
$(trunk)/source/Plugins/Trace<br>
<br>
Then add one for the Intel trace:<br>
<br>
$(trunk)/source/Plugins/Trace/Intel<br>
<br>
We should then add a new "trace" multi-word command into that would get added into our commands in CommandInterpreter::LoadCommandDictionary():<br>
<br>
    m_command_dict["trace"] = CommandObjectSP (new CommandObjectMultiwordTrace (*this));<br>
<br>
This command would then have sub commands like "start", "stop", and any other commands we would need in order to display trace data.<br>
<span class=""><br></span></blockquote><div><br></div><div>Probably, I shouldn't have used the word 'Plugin'. I want to develop an external 'tool' that will link to liblldb.so just to extract the raw trace data using SB API of LLDB (SBProcess::StartTrace (SBTraceOptions &options)) for the debugged inferior. The tool will then process this raw data to convert and show it as a meaningful information to the user. I am planning to keep it external without compiling it into LLDB (the decision of keeping it external resulted in from the previous discussions on this mailing list as people were skeptical of compiling it into LLDB because of its dependency on Intel(R) 'Processor Trace Decoding Library'). Making this tool as a part of LLDB repository but not compiling into LLDB will enable users of this tool to compile it separately and use it without affecting anyone who doesn't want to use it.</div><div><br></div><div>I want to enable the user of this tool to use it through LLDB CLI. For this purpose, I will have to provide some user-defined commands once this tool is loaded in LLDB externally via 'plugin load <shared_lib_path>' command. I am referring to $(trunk)/examples/plugins/commands/fooplugin.cpp file for the implementation.</div><div><br></div><div>The function lldb::PluginInitialize (lldb::SBDebugger debugger) will look something like this:</div><div>{        </div><div>    lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();</div><div><div>    lldb::SBCommand processor-trace = interpreter.AddMultiwordCommand("processor-trace",NULL);    // replaced 'foo' by 'processor-trace' in fooplugin.cpp</div></div><div>    processor-trace.AddCommand ("start", new StartCommand (), "configures intel processor trace & start tracing the inferior");   // replaced 'child' by 'start'</div><div>}</div><div><br></div><div>interpreter.AddMultiwordCommand("processor-trace",NULL) will add 'processor-trace' multiword Command Object via CommandInterpreter::AddUserCommand() in<br></div><div>'m_user_dict' data member like this:    m_user_dict ["processor-trace"] = cmd_sp;</div><div><br></div><div>In order to load this tool externally (as a shared library) in LLDB, I believe the user-defined commands will go to 'm_user_dict' and not 'm_command_dict' as m_command_dict represents basic built-in commands of LLDB.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span class="">
> 2. I am planning to upstream this developed plugin in LLDB public repository once the development is finished. Any user that wants to use Intel(R) Processor Trace will be able to do so by compiling this plugin and loading it via LLDB CLI as an external library. What should be the ideal location to place this plugin in LLDB repository? I could think of the 'tools' folder.<br>
<br>
</span>All plug-ins right now are all internal to LLDB and are currently developed in the "$(trunk)/source/Plugins" and compiled into LLDB right now. We don't currently have a model where plug-ins can be externally loaded into LLDB as most of the plug-ins use the lldb_private APIs. This is mostly due to C++ and the fragility of exporting classes that could be inherited from. Our public API (anything in the "lldb" namespace is designed to be exported from the LLDB shared library) follows some rules:<br>
1 - No inheritance<br>
2 - No virtual functions<br>
3 - Fixed instance variables that never change (usually a single shared_ptr, unique_ptr or just plain pointer)<br>
<br></blockquote><div><br></div><div>If the above approach is followed then we don't have to compile the tool into LLDB. Also, the tool will not use any lldb_private APIs. It will purely use SB APIs of LLDB.</div><div>e.g. lldb::SBCommandPluginInterface class will be inherited to define StartCommand class in above example:</div><div><br></div><div>class StartCommand : public lldb::SBCommandPluginInterface {</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
This isn't to say we can't start to develop a way to do external plug-ins, but if we do, this will be new work and will involve a lot of thought to ensure that plug-ins will be able to be loaded by current and future versions of LLDB.<br>
<br>
The Intel trace plug-in is going to require very close integration with the ProcessGDBRemote if the pluig-in design stays on the course of adding packets to a GDB server so I don't see how you would make a plug-in that can live on the public API and be external.</blockquote><div><br></div><div>I hope the above explanation answers this question. It is possible to develop this tool using only public APIs of LLDB and be kept external at the same time without compiling it into LLDB. In my opinion, the best place to keep this tool will be $(trunk)/tools/trace/intel-pt folder.<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">If you go the route of using expressions in order to enable the gathering and do everything by just using what is available in the public API, this can work as a plug-in, but it then loses the ability to add functions to the public LLDB API like we spoke about ( lldb::SBTrace lldb::SBProcess::StartTrace(lldb::SBTraceOptions &options) ).<br>
<span class=""><font color="#888888"><br>
Greg Clayton<br><br>
</font></span></blockquote></div><br></div></div><div class="gmail_extra">Please let me know if I couldn't explain myself properly or I missed some crucial points here. Thanks for your feedback.</div><div class="gmail_extra"><br></div><div class="gmail_extra">- Abhishek Aggarwal</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div></div>