[Lldb-commits] [lldb] r247852 - Add an OperatingSystem plugin to support goroutines

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Thu Jul 13 20:58:12 PDT 2017

Hi Ryan, we're having a tiny problem with the Go OperatingSystem plugin at Apple.  I know it's been a while since you've worked on this, but I wanted to see if you had an opinion about how we should address this.

Some iPhone app developers download static libraries (aka ranlib archives aka collection of .o files) to build into their projects, and we've seen a few static libraries that are written in Go.  I have no idea what compilers were used to generate these object files.  

We go through the OperatingSystemGo::Init and find 

 ValueObjectSP allgs_sp = FindGlobal(target_sp, "runtime.allgs");
  if (allgs_sp) {
    m_allg_sp = allgs_sp->GetChildMemberWithName(ConstString("array"), true);
    m_allglen_sp = allgs_sp->GetChildMemberWithName(ConstString("len"), true);

Then when we're working on threads (and the plugin.os.goroutines.enable setting is enabled), OperatingSystemGo::UpdateThreadList is called to add extra threads ("goroutines"?  sorry I haven't had a chance to play with the language yet, I'm not familiar with the terminology) into lldb's thread list.  It starts by getting the runtime.allgs.len:

  uint64_t allglen = m_allglen_sp->GetValueAsUnsigned(0);

and then iterates over that many goroutines:

 Error err;
  for (uint64_t i = 0; i < allglen; ++i) {
    goroutines.push_back(CreateGoroutineAtIndex(i, err));
    if (err.Fail()) {
      err.PutToLog(log, "OperatingSystemGo::UpdateThreadList");
      return new_thread_list.GetSize(false) > 0;

and in OperatingSystemGo::CreateGoroutineAtIndex we do

  ValueObjectSP g =
      m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err);

and this is where we're crashing.  For some reason the runtime.allgs.len says it has 8 but m_allg_sp->GetSyntheticArrayMember(0, true) returns an empty ValueObjectSP (shared pointer) so we crash when we dereference it.

Of course the real question is why does m_allg_sp->GetSyntheticArrayMember(0, true) not return a child -- it should have 8 of them according to runtime.allgs.len -- but I'm not super interested in this, the people who are developing/debugging these apps are unaware that they have go code in their program and are not going to be debugging into it.

I can avoid the crash by checking to see if we were able to fetch the child.  If not, set the error object and return.  UpdateThreadList() detects the error and doesn't add any goroutines to the lldb thread list.  e.g.

diff --git i/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp w/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
index c5a3ddee484..97875c7266d 100644
--- i/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
+++ w/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
@@ -451,8 +451,14 @@ OperatingSystemGo::Goroutine
 OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err) {
   Goroutine result = {};
-  ValueObjectSP g =
-      m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err);
+  ValueObjectSP child_sp = m_allg_sp->GetSyntheticArrayMember(idx, true);
+  if (!child_sp) {
+    err.SetErrorToGenericError();
+    err.SetErrorString("unable to find goroutines in array");
+    return result;
+  }
+  ValueObjectSP g = child_sp->Dereference(err);
   if (err.Fail()) {
     return result;

I could also just disable goroutines in the lldb that we ship in Xcode.  I'd rather not do that because it means people working in go on macos/ios need to re-enable it in their .lldbinit files before they get the expected debug experience.

If you have a chance to look at this, could you let me know what you think is best here?



> On Sep 16, 2015, at 2:20 PM, Ryan Brown via lldb-commits <lldb-commits at lists.llvm.org> wrote:
> Author: ribrdb
> Date: Wed Sep 16 16:20:44 2015
> New Revision: 247852
> URL: http://llvm.org/viewvc/llvm-project?rev=247852&view=rev
> Log:
> Add an OperatingSystem plugin to support goroutines
> The Go runtime schedules user level threads (goroutines) across real threads.
> This adds an OS plugin to create memory threads for goroutines.
> It supports the 1.4 and 1.5 go runtime.
> Differential Revision: http://reviews.llvm.org/D5871
> Added:
>    lldb/trunk/source/Plugins/OperatingSystem/Go/
>    lldb/trunk/source/Plugins/OperatingSystem/Go/CMakeLists.txt
>    lldb/trunk/source/Plugins/OperatingSystem/Go/Makefile
>    lldb/trunk/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
>    lldb/trunk/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h
>    lldb/trunk/test/lang/go/goroutines/
>    lldb/trunk/test/lang/go/goroutines/TestGoroutines.py
>    lldb/trunk/test/lang/go/goroutines/main.go
> Modified:
>    lldb/trunk/cmake/LLDBDependencies.cmake
>    lldb/trunk/include/lldb/Core/PluginManager.h
>    lldb/trunk/include/lldb/lldb-enumerations.h
>    lldb/trunk/lib/Makefile
>    lldb/trunk/lldb.xcodeproj/project.pbxproj
>    lldb/trunk/source/Core/PluginManager.cpp
>    lldb/trunk/source/Initialization/SystemInitializerCommon.cpp
>    lldb/trunk/source/Plugins/Makefile
>    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
>    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
>    lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
>    lldb/trunk/source/Plugins/OperatingSystem/CMakeLists.txt
>    lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
>    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
>    lldb/trunk/source/Symbol/ObjectFile.cpp
>    lldb/trunk/source/Target/Process.cpp
>    lldb/trunk/source/Target/StackFrameList.cpp
>    lldb/trunk/source/Target/ThreadList.cpp
>    lldb/trunk/source/Utility/ConvertEnum.cpp

More information about the lldb-commits mailing list