389ds(ns-slapd)のデバッグ

* **CentOS8** の389dsについて ☞ [詳細](https://qiita.com/bwitch/items/7942ec30e2445acaca49)

## デバッグ情報を使う場合

### 準備
```sh
#"gdb"を入れておく
sudo dnf install gdb -y

#"debuginfo"インストール
sudo dnf debuginfo-install 389-ds-base --enablerepo=base-debuginfo -y
```

### デバッグ
```sh
sudo gdb -p $(pidof ns-slapd)
...
(gdb) b acl_access_allowed
(gdb) c
... continueを止める場合はCtrl-c
```

---

## ソースを使う場合

### 準備
```sh
#開発用ツールを入れておく
sudo dnf groupinstall 'Development Tools' -y

#ソースRPMをダウンロード
#dnf download --source 389-ds-base
#↑何故か見つからない
curl http://ftp.riken.jp/Linux/cern/centos/8.1.1911/AppStream/Source/SPackages/389-ds-base-1.4.1.3-7.module_el8.1.0+234+96aec258.src.rpm -O

#RPMを展開
mkdir 389-ds-base-rpm
cd 389-ds-base-rpm
rpm2cpio ../389-ds-base-1.4.1.3-7.module_el8.1.0+234+96aec258.src.rpm | cpio -id

#ソースを展開
tar jxf 389-ds-base-1.4.1.3.tar.bz2
cd 389-ds-base-1.4.1.3
#パッチ当て
for f in ../*.patch; do patch -p1 <$f; done

#configureスクリプトを作成
autoreconf -fiv

#下の"cracklib-devel"用
sudo dnf config-manager --enable PowerTools
#とにかくconfigureを通すためにいろいろ入れる
sudo dnf install cracklib-devel pam-devel libevent-devel nspr-devel nss-devel -y
sudo dnf install openldap-devel libdb-devel libicu-devel net-snmp-devel pcre-devel -y
sudo dnf install systemd-devel -y #下の"--with-systemd"用

#configure
./configure --prefix=/usr --with-systemd
#"--with-systemd"は起動設定(.service)が「Type=notify」の場合に必要
```

### ビルドとインストール
```sh
#ビルド
make dberrstrs.h ns-slapd $(ls -1 /usr/lib64/dirsrv/plugins/ | sed 's/\.so/.la/' | paste -s -d' ')

#インストール
sudo cp .libs/ns-slapd /usr/sbin/
find /usr/lib64/dirsrv/plugins/* -type f | sed 's,.*/,.libs/,' | xargs -i sudo cp {} /usr/lib64/dirsrv/plugins/
find /usr/lib64/dirsrv/*.so* -type f | sed 's,.*/,.libs/,' | xargs -i sudo cp {} /usr/lib64/dirsrv/
find /usr/lib64/libsvr* -type f | sed 's,.*/,.libs/,' | xargs -i sudo cp {} /usr/lib64/
```

### デバッグ ([同上](#デバッグ))
```sh
sudo gdb -p $(pidof ns-slapd)
...
```


### コアを吐かせる
```sh
sudo -s

#あえて"0"にしてみる
ulimit -c 0

sysctl -w fs.suid_dumpable=1

#... ソースをいじってクラッシュさせる

#圧縮されたコアができる
ll /var/lib/systemd/coredump/

#最新分を確認
coredumpctl gdb -1
```

### VSCodeを使う

#### 前提
* リモート機能拡張
* C/C++機能拡張

#### エディター用の設定
```json:.vscode/c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "/usr/include/**",
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-x64",
            "forcedInclude": [
                "${workspaceFolder}/vscode.h"
            ]
        }
    ],
    "version": 4
}
```
↓ **forcedInclude** のファイル

```c:vscode.h
//何故か未定義になる分
#define NULL         0
#define LONG_MAX     9223372036854775807L
#define LONG_MIN     (-LONG_MAX - 1L)
//makeの引数の分
#define HAVE_CONFIG_H    1
#define BUILD_NUM        "-"
#define VENDOR           "389 Project"
#define BRAND            "389"
#define CAPBRAND          "389"
#define LOCALSTATEDIR     "/var"
#define SYSCONFDIR        "/etc"
#define LIBDIR            "/usr/lib64"
#define BINDIR            "/usr/bin"
#define DATADIR           "/usr/share"
#define DOCDIR            "/usr/share/doc/389-ds-base"
#define SBINDIR           "/usr/sbin"
#define PLUGINDIR         "/usr/lib64/dirsrv/plugins"
#define TEMPLATEDIR       "/usr/share/dirsrv/data"
#define SYSTEMSCHEMADIR   "/usr/share/dirsrv/schema"
```

#### ビルド用の設定
```json:.vscode/tasks.json
{
	"tasks": [
		{
			"type": "shell",
			"label": "vscode-make",
			"command": "/usr/bin/make",
			"args": ["vscode-make"]
		}
	],
	"version": "2.0.0"
}
```
↓ Makefileに **vscode-make** を追加

```makefile
vscode-make: ns-slapd $(serverplugin_LTLIBRARIES)
	sudo cp .libs/ns-slapd /usr/sbin/
	for i in $(serverplugin_LTLIBRARIES); do find .libs -name "$${i%.*}.so*" -type f | xargs -ri sudo cp {} /usr/lib64/dirsrv/plugins/; done
	for i in $(server_LTLIBRARIES); do find .libs -name "$${i%.*}.so*" -type f | xargs -ri sudo cp {} /usr/lib64/dirsrv/; done
	for i in $(lib_LTLIBRARIES); do find .libs -name "$${i%.*}.so*" -type f | xargs -ri sudo cp {} /usr/lib64/; done
	>$@
```

#### デバッグ用の設定
```json:.vscode/launch.json
{
	"version": "0.2.0",
	"configurations": [
		{
			"name": "vscode-gdb",
			"type": "cppdbg",
			"request": "launch",
			"program": "/usr/sbin/ns-slapd",
			"args": ["-D", "/etc/dirsrv/slapd-localhost", "-d", "266354688"],
			"stopAtEntry": false,
			"cwd": "${workspaceFolder}",
			"environment": [],
			"externalConsole": false,
			"MIMode": "gdb",
			"setupCommands": [{"description":"enable-pretty-printing", "text":"-enable-pretty-printing", "ignoreFailures":true}],
			"preLaunchTask": "vscode-make",
			"miDebuggerPath": "${workspaceFolder}/vscode-gdb"
		}
	]
}
```
↓ **miDebuggerPath** のファイル

```sh
echo 'sudo gdb $@' > vscode-gdb
chmod +x vscode-gdb
```