_GLIBCXX_DEBUG利用時、LLDBでg++のstd::vector等がうまく表示されない


# 環境

```bash
$ sw_vers
ProductName:		macOS
ProductVersion:		13.3.1
BuildVersion:		22E261

$ sysctl machdep.cpu.brand_string
machdep.cpu.brand_string: Apple M1

$ g++ --version
g++ (Homebrew GCC 13.1.0) 13.1.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ lldb --version
lldb version 16.0.6

$ which lldb
/opt/homebrew/opt/llvm/bin/lldb

```

見ての通り、M1 Macです。g++とlldbはHomebrewでインストールしています。

Q: なぜg++とlldbなんですか? gdb使ったほうが...
A: [gdbはM1に対応してません。](https://github.com/Homebrew/homebrew-core/issues/108309)

Q: ならclang++を使ったらどう?
A: `#include <bits/stdc++.h>`を使いたいのでg++を使ってます。

Q: stdc++.hを自分で作ればいいじゃん
A: g++用のファイルをclang++で使うの、なんか嫌じゃない?

# 発生している現象

こんなふうなコードを書きます。

```cpp:main.cpp
#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;

int main() {
  int H, W;
  cin >> H >> W;
  vector<vector<int>> dp(H, vector<int>(W, -1));
}
```

コンパイル&デバッグします
```bash
$ g++ -g -O0 -std=gnu++17 main.cpp

$ lldb a.out
(lldb) target create "a.out"
Current executable set to '..../a.out' (arm64).
(lldb) b main.cpp:8
Breakpoint 1: where = a.out`main + 52 at main.cpp:8:47, address = 0x00000001000036b0
(lldb) r
Process 12043 launched: '..../a.out' (arm64)
2 3 1
Process 12043 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x00000001000036b0 a.out`main at main.cpp:8:47
   5   	int main() {
   6   	  int H, W;
   7   	  cin >> H >> W;
-> 8   	  vector<vector<int>> dp(H, vector<int>(W, -1));
   9   	}
(lldb) s
Process 12043 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x0000000100003734 a.out`main at main.cpp:9:1
   6   	  int H, W;
   7   	  cin >> H >> W;
   8   	  vector<vector<int>> dp(H, vector<int>(W, -1));
-> 9   	}
(lldb) var
(int) H = 2
(int) W = 3
(std::__debug::vector<std::__debug::vector<int, std::allocator<int> >, std::allocator<std::__debug::vector<int, std::allocator<int> > > >) dp = size=0 {}
(lldb)
```

このように、sizeが0と表示されてしまいます。

# 対処法

問題は1行目の`#define _GLIBCXX_DEBUG`です。
これは、`std::vector<>`を`std::__debug::vector<>`に置き換え、いろいろ裏でデバッグしてくれる便利なマクロです。

しかし、LLDBはそんなこと知らないので、「`std::__debug::vector<>`...? 誰だお前」となってうまく表示できません。

そのため、`std::__debug::vector<>`に対しても整形コマンドを紐づければよいです。

LLDBは、`~/.lldbinit`に書かれたコマンドを起動時に読み込みます。
あとは[StackOverflowの質問](https://stackoverflow.com/questions/67980745/lldb-not-printing-contents-of-stdvector-on-code-compiled-with-gcc-g)や[公式レポジトリのファイル](https://github.com/llvm/llvm-project/blob/main/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp)の1000行目あたりを参考に、以下のように書きます。

```text:~/.lldbinit
type synthetic add --regex '^std::__debug::vector<.+>(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider -C true
type synthetic add --regex '^std::__debug::map<.+> >(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider -C true
type synthetic add --regex '^std::__debug::deque<.+>(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdDequeSynthProvider -C true
type synthetic add --regex '^std::__debug::set<.+> >(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider -C true
type synthetic add --regex '^std::__debug::multimap<.+> >(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider -C true
type synthetic add --regex '^std::__debug::multiset<.+> >(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdMapLikeSynthProvider -C true
type synthetic add --regex '^std::__debug::unordered_(multi)?(map|set)<.+> >$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdUnorderedMapSynthProvider -C true
type synthetic add --regex '^std::__debug::(__cxx11::)?list<.+>(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider -C true
type synthetic add --regex '^std::__debug::(__cxx11::)?forward_list<.+>(( )?&)?$' --python-class lldb.formatters.cpp.gnu_libstdcpp.StdForwardListSynthProvider -C true
```

これでうまく表示されます。めでたしめでたし。