How to get function name without arguments type/value/name?

Hi,

I call SBFrame.name to get function name and display in our debugger callstack window. However, this seems to include arguments types sometimes.(Btw: why it includes arguments types for subFunction but not main() in screenshot?)

Screen Shot 2016-04-21 at 1.40.55 PM.png

This is fine for small function, but can be really long if the function has a lot of arguments and the arguments are of template type.

Is there any way to only get the function name without arguments types?

I have tried "“settings set frame-format […]” " which seems to only apply to “bt” command.
I have tried SBFrame.function.name the same result.

Did I miss anything?
Jeffrey

The difference is how the debug info is emitted in the DWARF. Functions that come from C++ will have mangled names. These mangled names contain the arguments. If a function has a mangled name we will demangle it and display that. You can easily strip this if you want to by looking for the first "(" character and stripping the contents. We don't do anything like this. The main issue you will run into is if you have code like:

int foo(int f)
{
    return f*2; // Break here...
}

float foo(float d)
{
    return (float)foo((int)d);
}

int main(int argc, const char **argv)
{
    float f = float(2.3);
    return 0;
}

If you set a breakpoint at "Break here" and run you will currently get:

foo(int) + 16
foo(float) + 23
main + 25

But you are saying you would rather see:

foo + 16
foo + 23
main + 25

Or:

foo(...) + 16
foo(...) + 23
main + 25

"main" is funny because C++ compilers will often 'extern "C"' the function auto magically. This will stop it from getting a mangled name and stop us from showing "main(int, const char **)" as the function name.

The other reason you might not want to strip anything from the actual name is what happens when you are debugging another language? If you strip any text between "(" and ")", you might ruin a stack frame for the "q" language that has a function name like "foo.bar.baz{int (hello)}" and display this as "foo.bar.baz{int ()}". So any stripping you do, you will want to only do this for specific languages. We do have "const char * SBFunction::GetDisplayName()", but we currently only do something different for Swift (the new Apple language). You can't change the output of that for C++.

Personally I like to see all of the arguments that uniquely identify each function, but that is me. So anything you do in your debugger, you will want to make that configurable.

Greg

Hi Greg,

Thanks for the explanation. Even we strip the arguments we definitely will provide a UI for users to toggle arguments type/name/values. It’s just, with argument types, the function name can be really long and hard to read:

I was surprised that I need to strip out arguments manually because in command line I can do “settings set frame-format […%{function.name-without-args}]” telling lldb to print callstack(using bt command) without arguments. My understanding is that the get function name without arguments exists because may not be exposed in python API yet. Is this not true?

// bt command output after settings set frame-format […%{function.name-without-args}…]

  • frame #0: 0x0000000000403372 min`main + 586 at minimal.cpp:46

frame #1: 0x00007f9a44c050f6 libc.so.6__libc_start_main + 246 frame #2: 0x0000000000402fb8 min_start + 41 at start.S:122

Jeffrey

Hi Greg,

Thanks for the explanation. Even we strip the arguments we definitely will provide a UI for users to toggle arguments type/name/values. It's just, with argument types, the function name can be really long and hard to read:
<Screen Shot 2016-04-19 at 23.13.43.png>

You should probably not wrap the stack frame view IMHO and have it be scrollable horizontally. That might help.

I was surprised that I need to strip out arguments manually because in command line I can do "settings set frame-format [...%{function.name-without-args}]" telling lldb to print callstack(using bt command) without arguments. My understanding is that the get function name without arguments exists because may not be exposed in python API yet. Is this not true?

Yes, this isn't in the API yet. You might want to add a function to SBCommandInterpreter like:

We could also add a new "SBFormat" class that can wrap up a parsed format string:

class FormatImpl;
typedef std::shared_ptr<FormatImpl> FormatImplSP;

namespace lldb
{
  class SBFormat
  {
  public:
    SBFormat();
    
    lldb::SBError ParseFormat (const char *format);
    lldb::SBExecutionContext GetExecutionContext();
    lldb::SBAddress GetAddress();
    lldb::SBValue SetValue();
    void SetExecutionContext(lldb::SBExecutionContext &exe_ctx);
    void SetAddress(lldb::SBAddress &addr);
    void SetValue(lldb::SBValue &value);
    void ApplyFormat(lldb::SBStream &strm);
  protected:
    FormatImplSP m_opaque_sp;
  };
}

Then FormatImpl would contain be defined in SBFormat.cpp only:

class FormatImpl
{
protected:
    FormatEntity::Entry m_format;
    ExecutionContextRef m_exe_ctx_ref;
    Address m_address;
    ValueObjectSP m_value_sp;
};

This would allow you to make format objects that would stay around and already be precompiled so evaluating a format would be quick and be able to set the execution context, address, or value as needed.