How To Debug Apache AGE using GDB
Tags: postgres, apacheage
Published: 2023-05-03 10:28:36

This blog post assumes you have already installed postgresql (with debugging flag enabled) and Apache AGE extension,  otherwise you can follow this [blog](https://dev.to/mghrabi/explaining-in-detail-how-to-install-postgresql-from-source-code-on-windows-with-a-full-understanding-3jk7) for installation process. 

## Loading Apache AGE

1- first we need to run a postgres instance by using `psql` but make sure to run the server first, you can do that by the following two commands:

```
pg_ctl start -l log
psql postgres
```

2- Load `age` and set the search path to `ag_catalog`:

```
LOAD age;
SET search_path = ag_catalog, "$user", public;
```

3- Now you should be ready to debug AGE, but first we need to know the process of where the backend process of postgres is running, so that we can attach it to the gdb process, we can know the process by the following commands:

```
SELECT pg_backend_pid();
```
this should show you an output similar to this:

```
postgres=# select pg_backend_pid();
 pg_backend_pid
----------------
            439
(1 row)
```

4- Now open another terminal and `cd` to where age project exits on your machine, and run `gdb` to attach it to that process:

```
yourmachine:/mnt/d/bitnine_work/age_project/age$ gdb -p 439 
```

you should get an output similar to this: 

```
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 439
Reading symbols from /usr/local/pgsql-12/bin/postgres...
Reading symbols from /lib/x86_64-linux-gnu/libpthread.so.0...
Reading symbols from /usr/lib/debug/.build-id/7b/4536f41cdaa5888408e82d0836e33dcf436466.debug...
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Reading symbols from /lib/x86_64-linux-gnu/librt.so.1...
Reading symbols from /usr/lib/debug/.build-id/ce/016c975d94bc4770ed8c62d45dea6b71405a2c.debug...
Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...
Reading symbols from /usr/lib/debug/.build-id/c0/f40155b3f8bf8c494fa800f9ab197ebe20ed6e.debug...
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...
Reading symbols from /usr/lib/debug/.build-id/fe/91b4090ea04c1559ff71dd9290062776618891.debug...
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
Reading symbols from /usr/lib/debug/.build-id/18/78e6b475720c7c51969e69ab2d276fae6d1dee.debug...
--Type <RET> for more, q to quit, c to continue without paging--
```

5- Let's set a breakpoint to a function that exists in `age/src/backend/parser/cypher_analyze.c` file, which is `analyze_cypher` function:

```
(gdb) b src/backend/parser/cypher_analyze.c:analyze_cypher
Breakpoint 1 at 0x7f83c3da8620: file src/backend/parser/cypher_analyze.c, line 624.
```
6- Now create a cypher query for any graphs you created before, or create a `test` graph, insert some values into it, and then fetch some data, for example: 

```
postgres=# SELECT * FROM cypher('test', $$
MATCH (v:person)
RETURN v.name
$$) as (v agtype);
```
after running that you will notice that nothing has returned from postgres terminal, that's because `gdb` interrupted the process to enable debugging:

7- In **gdb** terminal enter the following:

```
c
```
this will run the code till the breakpoint we set, then enter:

```
layout next
```
you will notice that we reached to `analyze_cypher` function.

We are done!, by using the following basic commands you can print out variables to check their values, or continue the code till the next breakpoint:

`b` for breakpoint, (b )
`c` for continue - continues to the next breakpoint
`n` for next line
`s` for step into
`p` for print, (p *) for pointers
`bt` for call stack
`d` for delete all breakpoints
`list` for context
`q` for quit.

Hope this was helpful.