debugging 为什么gdb在'absl::flat_hash_map'中找不到元素访问函数?

puruo6ea  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(298)

问题

我试着调试一个使用absl::flat_hash_map的程序。但是,由于某种原因,gdb找不到operator[].find()。为什么它找不到这些方法?有什么解决办法吗?
我用-O0 -ggdb

> gdb --version
GNU gdb (GDB) Fedora Linux 12.1-6.fc37

示例

test.cpp

#include "absl/container/flat_hash_map.h"

absl::flat_hash_map<uint64_t, uint64_t> myMap;

int main() {
    myMap[1] = 1;
}

调试:

Temporary breakpoint 1, main () at test.cpp:6
6           myMap[1] = 1;
(gdb) p myMap[1]
No symbol "operator[]" in current context.
(gdb) p myMap.find(1)
Couldn't find method absl::flat_hash_map<unsigned long, unsigned long, absl::hash_internal::Hash<unsigned long>, std::equal_to<unsigned long>, std::allocator<std::pair<unsigned long const, unsigned long> > >::find
(gdb)

生殖

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)

project(abseil_test)

# Abseil requires C++14
set(CMAKE_CXX_STANDARD 14)
add_compile_options(-ggdb -O0)

# Process Abseil's CMake build system
add_subdirectory(abseil-cpp)

add_executable(test test.cpp)

target_link_libraries(test absl::base absl::raw_hash_set absl::hash)

将test.cpp和CMakeLists.txt放入一个文件夹并运行:

git clone https://github.com/abseil/abseil-cpp.git
mkdir build
cd build
cmake ..
cmake --build . --target test
gdb ./test -ex start -ex 'print myMap[1]'
o2g1uqev

o2g1uqev1#

原因是gdb不是一个C编译器。计算一个C表达式可能涉及到比gdb所能做的更多的事情。例如,absl散列Map的operator[]实际上是一个模板,调用myMap[1]需要示例化它并执行重载解析。
原因不止于此,因为在更简单的情况下,用户可以编写类似myMap.'operator[]<uint64_t>'(1)(可以说是手动示例化)的代码,但是,这个特定的类可能对糟糕的gdb来说太多了,所以它不起作用。
通常的(烦人的)解决方法是在要调用的函数中编译,作为独立的(非成员)非模板函数,这样语法就足够简单,gdb也能理解。

uint64_t myGet(absl::flat_hash_map<uint64_t, uint64_t>& table,
               uint64_t key)
{
   return table[key];
}

相关问题