简体   繁体   中英

How to access map<std::string, int> element using lldb?

Compile the snippet with clang++ -std=c++17 -g source.cpp

#include <map>
#include <string>
int main()
{
  std::map<std::string, int> m;
  m["foo"] = 23;
}

Try to access the element with key foo , but have errors:

* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x000000010000131e a.out`main at source.cpp:8:3
   5    {
   6      std::map<std::string, int> m;
   7      m["foo"] = 23;
-> 8    }
Target 0: (a.out) stopped.
(lldb) p m["foo"]
error: no viable overloaded operator[] for type 'std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > >'
candidate function not viable: no known conversion from 'const char [4]' to 'const std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > >::key_type' (aka 'const std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >') for 1st argument
candidate function not viable: no known conversion from 'const char [4]' to 'std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<const std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > >::key_type' (aka 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >') for 1st argument
(lldb) p m[std::string("foo")]
error: no member named 'string' in namespace 'std'
(lldb) p m[std::__1::string("foo")]
error: no matching conversion for functional-style cast from 'const char [4]' to 'std::__1::string' (aka 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >')
candidate constructor not viable: no known conversion from 'const char [4]' to 'const std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::allocator_type' (aka 'const std::__1::allocator<char>') for 1st argument
...
candidate constructor not viable: no known conversion from 'const char [4]' to 'std::initializer_list<char>' for 1st argument
candidate constructor not viable: requires 0 arguments, but 1 was provided
...
candidate constructor not viable: requires 4 arguments, but 1 was provided

How to work with string variables in the right way using lldb?

You don't say what versions of clang++ & lldb you are using. Using the tools that ship with Xcode 13, I see:

(lldb) expr m["foo"]
(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::mapped_type) $0 = 23
(lldb) expr m[std::string("foo")]
(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::mapped_type) $1 = 23

which is clearly not what you are getting. These simple seeming C++ expressions actually end up creating a bunch of templated entities behind the scenes, and reconstructing the information needed to instantiate templates from debug information alone is tricky to impossible.

But there has been a bunch of work done recently on the lldb side to support building the clang module for the C++ standard library from which we can extract the necessary information. Either you have an older lldb which doesn't have this work, or for some reason building the clang module is failing. If you are using a current lldb, then you might want to file a bug with http://bugs.llvm.org and see if somebody can help you figure out what's going wrong.

Note, also, lldb doesn't rely on expression evaluation alone for presentation of the common C++ (or ObjC/Swift) containers. It also has a system of "data formatters" which understand the underlying structure of these container classes and can represent the contents w/o having to call the actual language accessors. By default the results of expressions are formatted using the data formatters ( expr --raw -- turns the formatters off). That's why you see:

(lldb) expr m
(std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >) $0 = size=1 {
  [0] = (first = "foo", second = 23)
}

rather than all the actual fields of std::map.

In this case, the data formatter for std::map presents the map as a vector of pairs. Since the keys can be anything, this provides a more convenient way to access the elements...

This syntax can't be fed back into the expression evaluator - which is intended to be as close to the source language as possible, but you can use them to dig into local variables using the frame var command - short alias v :

(lldb) v m[0]
(std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>) [0] = (first = "foo", second = 23)
(lldb) v m[0].first
(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >) m[0].first = "foo"

etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM