<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">I think I got to the bottom of this and it’s nearly working now.</div><div class=""><br class=""></div><div class="">Your comments were very helpful and stopped me going down many useless paths. Especially the point about the unit tests re-running command line parsing multiple times. Great point!</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">My issue actually came from this line at the start:</div><div class=""><br class=""></div><div class="">extern "C" int llcmain(int argc, char **argv) {<br class="">  InitLLVM X(argc, argv);</div><div class="">…</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Doing a bit of debugging, after reading CommandLine.rst from start to finish (and then realising that at least my copy was out of date because it didn’t mention SubCommands :))… I was able to step into the code just before the assert was triggered and realised somehow there were no command line options in SubCommand…</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">(lldb) e TopLevelSubCommand->OptionsMap</b></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(llvm::StringMap<llvm::cl::Option *, llvm::MallocAllocator>) $10 = {</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  llvm::StringMapImpl = {</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    TheTable = 0x0000000000000000</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    NumBuckets = 0</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    NumItems = 0</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    NumTombstones = 0</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    ItemSize = 16</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  }</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  Allocator = {}</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><br class=""></div><div class="">Since they should all be set up in static variables, and the server program isn’t going away, this is quite odd. The GlobalParser is also dead…</div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><b class="">(lldb) e GlobalParser</b></span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">(llvm::ManagedStatic<(anonymous namespace)::CommandLineParser, llvm::object_creator<(anonymous namespace)::CommandLineParser>, llvm::object_deleter<(anonymous namespace)::CommandLineParser> >) $12 = {</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  llvm::ManagedStaticBase = {</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Ptr = 0x0000000000000000</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    DeleterFn = 0x0000000000000000</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">    Next = 0x0000000000000000</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">  }</span></div><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class="">}</span></div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I realised these managed static global variables had been deleted. This was being done in llvm_shutdown which was called from the destructor of the InitLLVM object.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I made a simple fix/hack:</div><div class=""><br class=""></div><div class="">extern "C" int llcmain(int argc, char **argv) {<br class="">  static InitLLVM X(argc, argv);</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Now the InitLLVM object is only created once, never destroyed and the globals stay in play.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Now I have to clean up the command line after each run. I’m trying ResetAllOptionOccurrences() at the end of llcmain, that removes all options but still seems to leave the positional parameters. I’ll probably figure it out eventually. :)</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Thanks for all your help.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On 18 Nov 2019, at 14:18, LLVM Mailing List via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">Thanks,</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I tried calling ResetAllOptionOccurrences after the run like this…</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">  // Compile the module TimeCompilations times to give better compile time<br class="">  // metrics.<br class="">  for (unsigned I = TimeCompilations; I; --I)<br class="">    if (int RetVal = compileModule(argv, Context))<br class="">      return RetVal;<br class=""><br class="">  if (YamlFile)<br class="">    YamlFile->keep();<br class=""><br class="">  cl::ResetAllOptionOccurrences();<br class=""><br class="">  return 0;<br class="">}</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Unfortunately it is still crashing out when the next build starts. Any other thoughts?</div><br class=""><div class=""><br class=""><blockquote type="cite" class=""><div class="">On 18 Nov 2019, at 10:13, James Henderson via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">I'm not entirely sure what it is that is causing your problem. It's worth noting that the unit tests for CommandLine.cpp can call cl::ParseCommandLineOptions multiple times within a process, although it looks like the options parsed are explicitly removed at the end of each test to avoid polluting the environment of the next test.</div><div class=""><br class=""></div><div class="">Probably the right thing to do is to call the "ResetAllOptionOccurrences" function of the command line parser. This should allow you to use it again cleanly. If you don't call that, you might end up setting options multiple times, which could lead to unexpected behaviour. Note that the comment in this function says that it is explicitly intended to allow parsing different command lines multiple times.</div><div class=""><br class=""></div><div class="">Hope that helps.<br class=""></div><div class=""><br class=""></div><div class="">James<br class=""></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, 17 Nov 2019 at 15:17, Carl Peto via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br class="">
<br class="">
I am running a server that does regular builds using llc. To begin with I was doing a fork/exec to launch llc, passing the files to compile and other switches as command line, etc. then waiting for the subprocess to complete. This was fine but seemed an unnecessary overhead. After all llc is mostly a fairly thin front end over the llc libraries, which do the actual work right?<br class="">
<br class="">
So I took llc.cpp, and the llvm-c and llvm headers and llvm libraries and linked them all into my server program (which is a C based server). I modified llc.cpp to change...<br class="">
<br class="">
int llcmain(int argc, char **argv) {<br class="">
...<br class="">
}<br class="">
<br class="">
...to...<br class="">
<br class="">
extern "C" int llcmain(int argc, char **argv) {<br class="">
...<br class="">
}<br class="">
<br class="">
<br class="">
Now I am calling this function directly from my server code.  This works fine for the first build, however any other builds fail in<br class="">
<br class="">
CommandLine.cpp:1101<br class="">
<br class="">
CommandLineParser::ParseCommandLineOptions<br class="">
<br class="">
assert(hasOptions() && "No options specified!"); <--fails here<br class="">
<br class="">
<br class="">
I'm trying to work out why this is breaking, I am assuming there is some global state left after processing that llc.cpp doesn't normally need to worry about?<br class="">
<br class="">
Is there a way to reset this global state cleanly? I'm assuming there's something about command line processing that is written to only work once, not repeatedly?<br class="">
<br class="">
Thanks for any advice/help.<br class="">
_______________________________________________<br class="">
LLVM Developers mailing list<br class="">
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" class="">llvm-dev@lists.llvm.org</a><br class="">
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank" class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class="">
</blockquote></div>
_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class=""><a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br class=""></div></blockquote></div><br class=""></div>_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:llvm-dev@lists.llvm.org" class="">llvm-dev@lists.llvm.org</a><br class="">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev<br class=""></div></blockquote></div><br class=""></body></html>