attachコマンドが失敗する

# attachコマンドが失敗する
gdbでattachコマンドを実行したときに権限の問題で実行できないことがあります. Ubuntu のデフォルトではそういう設定になっています.
```bash
(gdb) attach 32174
Attaching to program: /usr/lib/libreoffice/program/soffice.bin, process 32174
Could not attach to process.  If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user.  For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
```

これがおきたら端末で以下を実行して直します.
```bash
$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
## または以下でも同じこと
## sudo sysctl -w kernel.yama.ptrace_scope=0
```
この設定を恒久化したい(Linuxを立ち上げたときに毎回この設定を実行したくない) 場合は,
/etc/sysctl.d/10-ptrace.conf を編集して直してください(編集にはroot権限が必要).
```bash
$ sudo vi /etc/sysctl.d/10-ptrace.conf
修正前)kernel.yama.ptrace_scope = 1
修正後)kernel.yama.ptrace_scope = 0
```

### launch.json
```json
{
	// IntelliSense を使用して利用可能な属性を学べます。
	// 既存の属性の説明をホバーして表示します。
	// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach_lldb",
			"type": "lldb",
            "request": "attach",
			"pid": "${command:pickProcess}",
        },
        {
            // "name": "(gdb) build and debug active file on Linux",
            // "type": "cppdbg",
            // "request": "launch",
            // "program": "${workspaceFolder}/build/main",
            // "args": [],
            // "stopAtEntry": true,
            // "cwd": "${workspaceFolder}",
            // "environment": [],
            // "externalConsole": false,
            // "MIMode": "gdb",
            // "miDebuggerPath": "/usr/bin/gdb",
            // "setupCommands": [
            //     {
            //         "description": "Enable pretty-printing for gdb",
            //         "text": "-enable-pretty-printing",
            //         "ignoreFailures": true
            //     }
            // ],
            // "preLaunchTask": "C/C++: build project on Linux (debug)"
            // "preLaunchTask": "C/C++: g++.exe build active file"


            "type": "lldb",
			"request": "launch",
            "name": "Debug",
            "program": "${workspaceFolder}/build/main",
            "args": [],
            "cwd": "${workspaceFolder}",
			"env": 
			{
				// "LD_LIBRARY_PATH" : "${workspaceFolder}/libsimpletrace.so"
                "LD_PRELOAD" : "/home/kita/work/getenv/build/test/libsimpletrace.so"
			},
            "preLaunchTask": "C/C++: build project on Linux (debug)"
        }
    ]
}
```
### tasks.json
```json
{
    "version": "2.0.0",
    "tasks": [
		{
			"type": "shell",
			"label": "C/C++: build project on Linux (debug)",
            "command": "sh",
			"args": [
				"doDebugBuild.sh"
			],
			"options": {
				"cwd": "${workspaceFolder}"
			},
			"problemMatcher": [
				"$gcc"
			],
			"group": {
				"kind": "build",
				"isDefault": true
			},
			"detail": "Build project with debug configuration."
		}
	]
}
```
### CMakeLists.txt
```bash
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)

# if (UNIX)
    set(CMAKE_C_COMPILER "gcc")
# elseif (WIN32)
#     set(CMAKE_C_COMPILER "g++")
# endif ()
# set(CMAKE_C_STANDARD 20)
set(CMAKE_C_FLAGS "-Wall -Wfatal-errors -Wundef")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
# set(CMAKE_C_FLAGS_RELEASE "-O3")

# Set the project name and language.
project(example C)
add_executable(main main.c)

# cmake_minimum_required(VERSION 3.5)

# set(SOURCE_FILES
#     ${CMAKE_CURRENT_SOURCE_DIR}/main.c
#     )

# add_executable(Hello ${SOURCE_FILES})
```
### doDebugBuild.sh
```bash
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build
```
### main.c
```c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

#define FLAG_FILE "flag.txt"

int getFlag(void)
{
	char buf[256];
	FILE *fp;
	int flag;

	// FLAG_FILEの中身をreturn
	fp = fopen(FLAG_FILE, "r");
	if (fp == NULL) {
		printf("fopen error");
		return 0;
	}
	fread(buf, 1, 256, fp);
	fclose(fp);

	flag = atoi(buf);

	return flag;
}

void initFlag(void)
{
	FILE *fp;

	// FLAG_FILEの中身を"1"にセット
	fp = fopen(FLAG_FILE, "w");
	if (fp == NULL) {
		printf("fopen error");
	}
	fprintf(fp, "1");
	fclose(fp);
}

int main(void)
{

	// フラグを1にセット
	initFlag();

	printf("Process ID : %d\n", getpid());

	// フラグが0になるまで待ち状態
	while (getFlag()) {
		sleep(1);
	}

	// ここからプログラムの通常処理
	int sum = 0;
	for (int i = 0; i < 100; i++) {
		sum += i;
	}

	printf("%d\n", sum);
}
```