Matthew James Briggs
Matthew James Briggs

Reputation: 2265

LLDB sometimes displays vector data and other times does not

In most cases when debugging, if I have a vector (in Xcode 9), I am shown a list of indices representing the values in the vector.

Desired enter image description here

Other times, I get this unhelpful representation:

Undesired enter image description here

I am unable to figure out what conditions cause LLDB to display vectors in the undesirable way.

Question
What is causing the undesired behavior? Can it be fixed without re-writing the code? Is this a bug in LLDB?

Here is a short code example that reproduces the undesired behavior:

#include <iostream>
#include <vector>

std::vector<int> createVector()
{
    std::vector<int> v = { 1, 2, 3 };
    return v;
}

int main(int argc, const char * argv[])
{
    const auto& v = createVector();
    std::cout << v.front() << std::endl;
    return 0;
}


Here is a link to the Xcode project:
http://s000.tinyupload.com/?file_id=21020556485232357417

Upvotes: 6

Views: 1165

Answers (2)

Jim Ingham
Jim Ingham

Reputation: 27148

This is a known bug in how the std::vector data summary & formatters work for reference variables. Note that in the expr v the expression parser actually considers v to be a straight vector, not a reference to a vector... That's why that printing works.

Upvotes: 4

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38773

Sorry, I add my comment here in the answers, since Stack Overflow comments do not support formatting.

It is definitely the lldb's issue. Your pictures do not contain the full v description:

v = (const std::__1::vector<int, std::__1::allocator<int> > &) size=1

The size=1 is incorrect. Besides the print command in the lldb console prints v correctly:

(lldb) p v
(const std::__1::vector<int, std::__1::allocator<int> >) $1 = size=3 {
  [0] = 1
  [1] = 2
  [2] = 3
}

It seems Xcode uses the lldb frame var command to display variables. This displays exactly the same output that is displayed by Xcode:

(lldb) frame variable -T
(int) argc = 1
(const char **) argv = 0x00007fff5fbff710
(const std::__1::vector<int, std::__1::allocator<int> > &) v = size=1: {
  (std::__1::__vector_base<int, std::__1::allocator<int> >) std::__1::__vector_base<int, std::__1::allocator<int> > = {
    (std::__1::__vector_base<int, std::__1::allocator<int> >::pointer) __begin_ = 0x000000010103fa40
    (std::__1::__vector_base<int, std::__1::allocator<int> >::pointer) __end_ = 0x000000010103fa4c
    (std::__1::__compressed_pair<int *, std::__1::allocator<int> >) __end_cap_ = {
      (std::__1::__libcpp_compressed_pair_imp<int *, std::__1::allocator<int>, 2>) std::__1::__libcpp_compressed_pair_imp<int *, std::__1::allocator<int>, 2> = {
        (int *) __first_ = 0x000000010103fa4c
      }
    }
  }
}

I think the issue comes from the fact that the variable v was initially created and initialised in another stack frame, thus some information about the vector is unknown in the lower stack frame when the initial vector was passed as a result of the function call.

Upvotes: 4

Related Questions