Load fat executable when uncertain about the target process' architecture

I use:
m_target = m_debugger.CreateTarget(fn, archd, NULL, true, m_error);
m_process = m_target.ConnectRemote(SBListener(), target, NULL, m_error);

(fn points to an executable with x86 and x86_64 in it. archd this x86_64-apple-ios)

However the target ends up being a 32bits process. At this point the ABI code loads 64bits and ends up crashing in some 64bits register loading code in ABISysV_x86_64.h:

argument_register_ids[0] = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB];

the problem I'm having is that I don't know what architecture the target will be before connecting. Passing no arch to CreateTarget gives this error:

"'App10' doesn't contain any 'ios-simulator' platform architectures"

I do know GDB has (and gets called for) a command that asks the process architecture, but this doesn't seem to be used to get the abi (and probably more things), what can I do in this case?

Hi Carlo,

Here is how I enumerate the available archs in my code:

SBModuleSpecList specs = SBModuleSpecList::GetModuleSpecifications(Path);
const size_t count = specs.GetSize();
for (size_t i = 0; i < count; ++i)
{
   SBModuleSpec module_spec = specs.GetSpecAtIndex(i);
   const char *triple = module_spec.GetTriple();
   std::vector<nglString> tokens;
   nglString triplestr = triple;
   triplestr.Tokenize(tokens, '-');
   NGL_OUT("%s -> '%s' '%s' '%s'\n", triple, tokens[0].GetChars(), tokens[1].GetChars(), tokens[2].GetChars());
   mArchitectures.push_back(tokens[0]);
   mVendors.push_back(tokens[1]);
   mTargetOSes.push_back(tokens[2]);
}

nglString is a custom string type that I use but I'll get the idea of how it works I guess.

Cheers,

S.

Sebastien Metrot schreef op 10/10/2013 6:22 PM:

Hi Carlo,

Here is how I enumerate the available archs in my code:

  SBModuleSpecList specs = SBModuleSpecList::GetModuleSpecifications(Path);
  const size_t count = specs.GetSize();
  for (size_t i = 0; i < count; ++i)
  {
    SBModuleSpec module_spec = specs.GetSpecAtIndex(i);
    const char *triple = module_spec.GetTriple();
    std::vector<nglString> tokens;
    nglString triplestr = triple;
    triplestr.Tokenize(tokens, '-');
    NGL_OUT("%s -> '%s' '%s' '%s'\n", triple, tokens[0].GetChars(), tokens[1].GetChars(), tokens[2].GetChars());
    mArchitectures.push_back(tokens[0]);
    mVendors.push_back(tokens[1]);
    mTargetOSes.push_back(tokens[2]);
  }

nglString is a custom string type that I use but I'll get the idea of how it works I guess.

Hi Sebastien,

I do know what's in the file (I compile it myself), I don't know whats on the other side where I connect to.

Ah yes, sorry I missed that part. It's true that discovery and introspection is not always an easy task with the current API, particularly when working with remotes.

S.

I use:
m_target = m_debugger.CreateTarget(fn, archd, NULL, true, m_error);
m_process = m_target.ConnectRemote(SBListener(), target, NULL, m_error);

(fn points to an executable with x86 and x86_64 in it. archd this x86_64-apple-ios)

However the target ends up being a 32bits process. At this point the ABI code loads 64bits and ends up crashing in some 64bits register loading code in ABISysV_x86_64.h:

argument_register_ids[0] = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB];

the problem I'm having is that I don't know what architecture the target will be before connecting. Passing no arch to CreateTarget gives this error:

"'App10' doesn't contain any 'ios-simulator' platform architectures"

I do know GDB has (and gets called for) a command that asks the process architecture, but this doesn't seem to be used to get the abi (and probably more things), what can I do in this case?

The key issue that is going wrong here is you are not specifying a platform. If you know you are going to be doing remote macosx debugging, then you can tell the target this when you create it. The 3rd argument (NULL) in CreateTarget is the platform name. Try specifying "remote-macosx".

Greg Clayton schreef op 10/10/2013 7:00 PM:

I use:
m_target = m_debugger.CreateTarget(fn, archd, NULL, true, m_error);
m_process = m_target.ConnectRemote(SBListener(), target, NULL, m_error);

(fn points to an executable with x86 and x86_64 in it. archd this x86_64-apple-ios)

However the target ends up being a 32bits process. At this point the ABI code loads 64bits and ends up crashing in some 64bits register loading code in ABISysV_x86_64.h:

argument_register_ids[0] = reg_ctx->GetRegisterInfoByName("rdi", 0)->kinds[eRegisterKindLLDB];

the problem I'm having is that I don't know what architecture the target will be before connecting. Passing no arch to CreateTarget gives this error:

"'App10' doesn't contain any 'ios-simulator' platform architectures"

I do know GDB has (and gets called for) a command that asks the process architecture, but this doesn't seem to be used to get the abi (and probably more things), what can I do in this case?

The key issue that is going wrong here is you are not specifying a
platform. If you know you are going to be doing remote macosx
debugging, then you can tell the target this when you create it. The
3rd argument (NULL) in CreateTarget is the platform name. Try
specifying "remote-macosx".

I'm targeting iOS-Simulator actually. The x86 vs x86_64 difference is because the simulator starts a different one based on what kind of simulator is running at the moment. Remote-macosx doesn't support the simulator. It works if I run & pass x86_64 or i386, but in this case I don't know what's running (there doesn't seem to be a way to detect it) and I just pass the "best" I compiled (x86_64) but it's running in 32bits mode so runs the i386 side of it, then fails.

I tried ios-remote too (with a null platform) but that makes it just load the i386 part of my fat executable (when reading a fat binary it somehow picks the first one if none was specified and I can't find a way to delay this choice until it's connected).

There is a "ios-simulator" platform. It might not do remote right now, so you might have to modify it.