Debugging Apache AGE using Visual Studio Code in Ubuntu

hallixon

Emmanuel Allison

Posted on July 30, 2023

Debugging Apache AGE using Visual Studio Code in Ubuntu

Apache AGE (short for A Graph Extension) is an extension to PostgreSQL, giving it graph database functionality. It is open source, and contributions to the project are welcomed. An invaluable tool for this is being able to debug the AGE project, and that's what we'll be doing today.

This article is specifically written for Ubuntu, but can be applied to other Linux distributions.

Prerequisite

To debug AGE, we'll need the following.

  • PostgreSQL installed from source code.
  • Download and install AGE from the source code.
  • Download and install Visual Studio Code from here.
  • A C compiler. For this article, gcc is used.

Setup

Open the AGE source code in VS Code. You can do that either by opening the folder in VS code or by running the following in the terminal.

cd ~/age
code .
Enter fullscreen mode Exit fullscreen mode

Replace ~/age with the path to your AGE source.

To configure the project for debugging, we create a folder .vscode in the project's root folder, and add the following files:launch.json, settings.json, and c_cpp_properties.json.

launch.json, settings.json, and c_cpp_properties.json files added to the .vscode folder

  • launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(gdb) Attach",
      "type": "cppdbg",
      "request": "attach",
      "program": "/home/hallixon/postgres/bin/postgres",
      "MIMode": "gdb",
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        },
        {
          "description": "Set Disassembly Flavor to Intel",
          "text": "-gdb-set disassembly-flavor intel",
          "ignoreFailures": true
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The configuration above enables attaching VS Code's debugger to the postgres process. Replace /home/hallixon/postgres/bin/postgres with the path to your PostgreSQL installation.

  • settings.json
{
    "files.associations": {
        "postgres.h": "c",
        "genam.h": "c",
        "heapam.h": "c",
        "tableam.h": "c",
        "table.h": "c",
        "htup_details.h": "c",
        "skey.h": "c",
        "pg_operator.h": "c",
        "namespace.h": "c"
    }
}
Enter fullscreen mode Exit fullscreen mode

This associates the header files with C language, and informs VS Code to use the same syntax highlighting for C on those files for this workspace.

  • c_cpp_properties.json
{
  "configurations": [
    {
      "name": "Linux",
      "includePath": [
        "/usr/include/**/**",
        "${workspaceFolder}/**",
        "/usr/include/**",
        "/home/hallixon/postgres/include/**",
        "/home/hallixon/postgres/include/server/**",
        "/home/hallixon/postgresql-13.11/src/**",
        "/home/hallixon/postgresql-13.11/**",
        "/home/hallixon/postgresql-13.11/src/backend/**",
        "/home/hallixon/postgres/lib/**",
        "${workspaceFolder}/src/include/**"
      ],
      "defines": [],
      "compilerPath": "/usr/bin/gcc",
      "cStandard": "c17",
      "cppStandard": "gnu++17",
      "intelliSenseMode": "linux-gcc-x64"
    }
  ],
  "version": 4
}
Enter fullscreen mode Exit fullscreen mode

Replace all /home/hallixon/postgresql-13.11 with the path to your PostgreSQL source code, and /home/hallixon/postgres with the path to your PostgreSQL installation.

You're now set to go.

Running PostgreSQL and Apache AGE

You can check if PostgreSQL is running by running the following command.

ps -e | grep postgres
Enter fullscreen mode Exit fullscreen mode

You should receive an output similar to the following.

18813 ?        00:00:00 postgres
18815 ?        00:00:00 postgres
18816 ?        00:00:00 postgres
18817 ?        00:00:00 postgres
18818 ?        00:00:00 postgres
18819 ?        00:00:00 postgres
18820 ?        00:00:00 postgres
Enter fullscreen mode Exit fullscreen mode

If there was no output, then you can start PostgreSQL by running the code below in the folder containing your PostgreSQL installation.

./pg_ctl -D pgdata -l pg_logfile start
Enter fullscreen mode Exit fullscreen mode

Where pgdata will be the path to PostgreSQL's database configuration files. By default, the environment variable PGDATA is used. pg_logfile is a log file for PostgreSQL to append its logs. If it doesn't exist, PostgreSQL will create it.

Now, create a new database and connect to it.

./createdb age_test
./psql age_test
Enter fullscreen mode Exit fullscreen mode

Now, add the AGE extension to the database.

CREATE EXTENSION IF NOT EXISTS age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
Enter fullscreen mode Exit fullscreen mode

To run cypher commands, we need a graph database. To create one, run the following code:

SELECT create_graph('test_graph');
Enter fullscreen mode Exit fullscreen mode

Attaching the Debugger

We need the ID of the postgres process so we can debug it while it runs. To find the process ID, run the following SQL command in the database.

SELECT pg_backend_pid();
Enter fullscreen mode Exit fullscreen mode

In VS Code, with the AGE project open, press F5. A popup will be opened for you to select the process to attach to. Now, type the process ID of the running postgres backend process, and select the matching process. The integrated terminal in VS Code will open, requiring Superuser access to process.

Image showing the integrated VS Code terminal requiring Superuser access to continue

Enter y and put in your password.

Debugging the Cypher reverse() Method

Open agtype.c in the src/backend/utils/adt folder, and search for age_reverse in the code using Ctrl + F. This is the method that handles the reverse() cypher method.

Add a breakpoint like you see in the picture.

Image showing a breakpoint added in the age_reverse method

Now, go to your terminal and run the SQL query in your database.

SELECT *
FROM cypher('test_graph', $$
    RETURN reverse('everywhere')
$$) AS (reverse agtype);
Enter fullscreen mode Exit fullscreen mode

The breakpoint will be hit.

Image showing that the breakpoint set in the age_reverse method was hit

You can view the values of the local variables by hovering over them, or in the Run and Debug View in VS Code, which is preferable.

The Variables section in the Debug View showing the local variables in the age_reverse method

You can step into the extract_variadic_args method, by pressing F11.

Stepping into the extract_variadic_args method

Now, step out of the method by pressing Shift+F11. Press F11 to move to the next line. In the Run and Debug View, you'll find out that the variable nargs, which is the number of arguments passed into the reverse() cypher method, is changed to 1.

Press F5 to continue running. In the terminal, you should see the result of query displayed.

   reverse    
--------------
 "erehwyreve"
(1 row)
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article, we were able to debug the AGE source code. This step taken will be one the most important in the journey to understanding and contributing to the Apache AGE project.

Please feel free to comment below if you have questions or if this helped you. Thanks!

💖 💪 🙅 🚩
hallixon
Emmanuel Allison

Posted on July 30, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related