Mind Chasers Inc.
Mind Chasers Inc.

Build, Test, and Debug cgit on Ubuntu Linux 18.04

A brief summary of getting started with cgit on Ubuntu Linux along with debugging a segfault we encountered



We recently started using cgit to host our development Git repositories on our local web server and are considering moving away from Github and hosting our public repos on mindchasers.com. If you're not already familiar with it, cgit is a popular Common Gateway Interface (CGI) web interface written in the C language. We interact with it externally on a daily basis with sites like The Yocto Project. cgit is highly customizable, provides an intuitive web interface, and allows developers to continue working with their Git repos directly using a shell (as opposed to Github) regardless of whether the repo is bare or has a working directory.

One of the great things about the cgit CGI application is that it can be tested and debugged on a command line independent of how it is deployed (e.g., Apache), and we show this below while also building cgit from its own repo. The cgit README includes the easy build instructions, but we'll include them below for the sake of completeness.

Clone and build cgit:

$ cd /build
$ git clone https://git.zx2c4.com/cgit/ cgit
Cloning into 'cgit'...

$ cd cgit

$ git submodule init 
Submodule 'git' (https://git.kernel.org/pub/scm/git/git.git) registered for path 'git'

$ git submodule update
Cloning into '/build/cgit/git'...

Before building the code, we're going to create a cgit.conf file to customize the installation (install into /opt/cgit):

CGIT_SCRIPT_PATH = /opt/cgit/bin
CGIT_CONFIG = /opt/cgit/etc/cgitrc
CACHE_ROOT = /opt/cgit/cache/cgit
prefix = /opt/cgit/local
$ make
$ make install

$ tree /opt/cgit
├── bin
│   ├── cgit.cgi
│   ├── cgit.css
│   ├── cgit.png
│   ├── favicon.ico
│   └── robots.txt
└── local
    └── lib
        └── cgit
            └── filters
                ├── about-formatting.sh
                ├── commit-links.sh
                ├── email-gravatar.lua
                ├── email-gravatar.py
                ├── email-libravatar.lua
                ├── file-authentication.lua
                ├── gentoo-ldap-authentication.lua
                ├── html-converters
                │   ├── man2html
                │   ├── md2html
                │   ├── rst2html
                │   └── txt2html
                ├── owner-example.lua
                ├── simple-authentication.lua
                ├── syntax-highlighting.py
                └── syntax-highlighting.sh

Now create a simple test repo for the purpose of verifying cgit operation and add the repo to the etc/cgitrc file:

$ mkdir /opt/tst-git; cd /opt/tst-git
$ touch a
$ git init
Initialized empty Git repository in /opt/tst-git/.git/

$ git add .
$ git commit -m 'initial commit'
[master (root-commit) 7891040] initial commit

$ mkdir -p /opt/cgit/etc
$ touch /opt/cgit/etc/cgitrc

Add the following lines to etc/cgitrc:


Now try running cgit.cgi from the command line:

$ cd /opt/cgit/bin
$ ./cgit.cgi

Content-Type: text/html; charset=UTF-8
Last-Modified: Sun, 03 Mar 2019 20:21:24 GMT
Expires: Sun, 03 Mar 2019 20:26:24 GMT

<!DOCTYPE html>
<html lang='en'>
<title>Git repository browser</title>
<meta name='generator' content='cgit v1.2.1-18-gbd029'/>
<meta name='robots' content='index, nofollow'/>
<link rel='stylesheet' type='text/css' href='/cgit.css'/>
<link rel='shortcut icon' href='/favicon.ico'/>
<div id='cgit'><table id='header'>
<td class='logo' rowspan='2'><a href='cgit.cgi/'><img src='/cgit.png' alt='cgit logo'/></a></td>
<td class='main'>Git repository browser</td></tr>
<tr><td class='sub'>a fast webinterface for the git dscm</td></tr></table>
<table class='tabs'><tr><td>
<a class='active' href='cgit.cgi/'>index</a></td><td class='form'><form method='get' action='cgit.cgi/'>
<input type='search' name='q' size='10' value=''/>
<input type='submit' value='search'/>
<div class='content'><table summary='repository list' class='list nowrap'><tr class='nohover'><th class='left'><a href='cgit.cgi/?s=name'>Name</a></th><th class='left'><a href='cgit.cgi/?s=desc'>Description</a></th><th class='left'><a href='cgit.cgi/?s=owner'>Owner</a></th><th class='left'><a href='cgit.cgi/?s=idle'>Idle</a></th></tr>
<tr><td class='toplevel-repo'><a title='tst-git' href='cgit.cgi/tst-git/'>tst-git</a></td><td><a href='cgit.cgi/tst-git/'>[no description]</a></td><td><a href='cgit.cgi/?q='></a></td><td><span class='age-mins' title='2019-03-03 20:18:57 +0000'>2 min.</span></td></tr>
</table></div> <!-- class=content -->
<div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.1-18-gbd029</a> (<a href='https://git-scm.com/'>git 2.20.0</a>) at 2019-03-03 20:21:24 +0000</div>
</div> <!-- id=cgit -->

Next, you can test that cgit returns the repo's contents when passing the tst-git url to it:

$ QUERY_STRING="url=tst-git" ./cgit.cgi 

Below is how this looks when served up from our local Apache web server:

cgit web interface

Debugging cgit

When we first started testing cgit, we were getting a segfault due to a typo in our cgitrc file. Instead of "repo.path", we had "reo.path". Here's how we debugged / discovered it:

$ QUERY_STRING="url=tst-git" ./cgit.cgi 
Segmentation fault (core dumped)

Run it again, but this time with gdb and generate a backtrace:

$ QUERY_STRING="url=tst-git" gdb ./cgit.cgi 
GNU gdb (Ubuntu 8.1-0ubuntu3)
(gdb) run
Starting program: /opt/cgit/bin/cgit.cgi 
Program received signal SIGSEGV, Segmentation fault.
__strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
120	../sysdeps/x86_64/multiarch/../strlen.S: No such file or directory.
(gdb) backtrace
#0  __strlen_sse2 () at ../sysdeps/x86_64/multiarch/../strlen.S:120
#1  0x00007ffff73e2aa9 in __add_to_environ (name=name@entry=0x55555569acef "GIT_DIR", value=0x0, combined=combined@entry=0x0, 
    replace=replace@entry=1) at setenv.c:131
#2  0x00007ffff73e2c8a in __setenv (name=name@entry=0x55555569acef "GIT_DIR", value=, replace=replace@entry=1)
    at setenv.c:259
#3  0x0000555555561dc5 in prepare_repo_env (nongit=0x7fffffffcfdc) at ../cgit.c:564
#4  process_request () at ../cgit.c:718
#5  0x00005555555636bc in cache_process (size=, path=, key=, ttl=, 
    fn=fn@entry=0x555555561d70 ) at ../cache.c:370
#6  0x0000555555562ad7 in cmd_main (argc=, argv=) at ../cgit.c:1096
#7  0x000055555555f6af in main (argc=1, argv=0x7fffffffe438) at common-main.c:45

From here, we started stepping through the code in prepare_repo_env and soon realized that repo.path was set to null and causing the segfault.

Instead of stepping through the code in gdb on the command line, we created a quick C project for it in Eclipse inside our /build/cgit directory, set the CGIT_CONFIG and QUERY_STRING environment variables, and found the problem by stepping through the /build/cgit application in the Eclipse IDE.

We'll continue updating this article as we become more familiar with cgit.

Additional References

Didn't find an answer to your question? Post your issue below or in our new FORUM, and we'll try our best to help you find a solution.

And please note that we update our site daily with new content related to our open source approach to network security and system design. If you would like to be notified about these changes, then please follow us on Twitter and join our mailing list.

Related articles on this site:

subscribe to mailing list:

Please help us improve this article by adding your comment or question:

For enhanced features and capabilities, please sign in or authenticate using a popular third party

your email address will be kept private

to upload an image

previous month
next month