1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
|
# Contributing
- [Introduction](#introduction)
- [Reporting issues and bugs](#reporting-issues-and-bugs)
- [Debugging](#debugging)
- [Upversion](#upversion)
- [Add new config variables](#add-new-config-variables)
- [Testing](#testing)
- [Architecture](#architecture)
- [Grammar and Language](#grammar-and-language)
- [Git](#git)
- [Overview of src/ files](#overview-of-src-files)
- [Stack Traces](#stack-traces)
## Introduction
First of all, thanks for contributing or considering to contribute.
We have two high level development rules:
- Friendship, ideas and code are valued in said order
- There are no deadlines
## Reporting issues and bugs
Reporting issues and bugs is a very helpful contribution. The preferred route
for reporting these is to raise github issues, but we are happy with any method
including forums threads and e-mails. If you are able to help resolve them,
that is also greatly appreciated.
It would be useful if you could simply start by describing what you did and
what happened. It may help if you could also do the following:
1. Run jgmenu from the terminal and copy/paste any output
2. Provide the output of `jgmenu --version`
3. Provide the output of `type jgmenu` (i.e. the location of the binary)
4. Provide the command you used to run jgmenu
5. Provide the config file
6. Provide some basic information about your system (e.g. distribution, window
manager, composite manager)
7. Run `jgmenu_run init -i` then choose 'check' and report any warnings
## Debugging
This list is by no means exhaustive, but may provide some ideas for
things to try.
1. Make use of the modular design of jgmenu to isolate the root cause.
For example, if you are using jgmenu with the 'lx' module, run
`jgmenu_run lx > foo` and analyse the output. Then try `jgmenu
--csv-file=foo`. This approach might help find the root cause of the
issue.
2. If the menu data is causing the issue (e.g. foo above), try to
comment out a section at a time or write a script to cycle through
individual items. The command line option --die-when-loaded can be
useful for this.
3. If using the 'pmenu' module, `jgmenu_run pmenu` will output the
.desktop file corresponding to each menu item. This can be useul to
analyse specific items.
4. strace can be used to understand what what system calls are made.
For example, to analyse which .desktop files were opened, try:
`strace -f -o foo jgmenu_run lx ; grep '.desktop' foo`
If you experience a crash, `strace` can also be particularly useful
for analysing which system calls were made, including their return
values.
5. Revert to a default configuration file and gradually change options
until the bug occurs.
6. The file ./scripts/enable-error-messages.sh contains a number of
environment variables which can be set for verbose output relating to
specific topics.
## Upversion
- update `default_version` in scripts/version-gen.sh
- run `dch` and update debian/changelog
- create docs/relnotes/X.Y.txt
- update NEWS.md
- add and commit the above files
- git tag -a 'vX.Y' (using the release notes as the commit message)
## Add new config variables
Any new config variables need to be added to the following:
- config.c
- config.h
- src/jgmenu-config.c
- docs/manual/jgmenu.1.md
## Testing
- `make ex` to launch a few menus specifically designed to test various
features.
- `make check` to check coding style and perform some static analysis on all
files in `src/`. Files can be checked on an individual basis by running
`./scripts/check <file>`
- `make test` to run unit tests
## Architecture
`jgmenu_run <command>` is a wrapper script which calls `jgmenu-<command>`.
This architecture is inspired by git and has a number of advantages over
putting all `jgmenu-<command>` in `$prefix/bin`:
- It ensures that the correct module is called if multiple version of jgmenu
are installed on the system.
- It avoids putting programs, that are not meant to be called by the user, in
`$prefix/bin`.
- It saves the user having to remember script file extensions whilst making
it simple for the developer to know which are binary, shell, python, etc.
## Grammar and Language
jgmenu is always written with a lowercase "j". It should be obvious from
the context if we refer to the entire application or just the binary
file.
The language used in documentation shall follow British English rules.
Although, for variable names and configuration options, US spelling is
used (e.g. color and center)
## Git
Keep commit messages lines to 74 characters.
## Overview of src/ files
jgmenu.c
- x11-ui.c - interface with X11
- icon.c - load icons
* cache.c - manage icon cache on harddisk
* icon-find.c - find icons
* xpm-loader.c - load xpm icons (png/svg use cairo)
- config.c - read config file
- geometry.c - calculate positions and dimensions
- filter.c - search support
- theme.c + font.c - set icon theme and font from xsettings, tint2rc, etc
* xsettings-helper.c - read xsettings variables
* gtkconf.c - read gtk3.0 config file variables
jgmenu-apps.c
- desktop.c - parse desktopp files
jgmenu-ob.c
## Stack traces
If jgmenu crashes with the message 'Segmentation fault' or 'Abort', a stack
trace (also known as backtrace) is often the most useful starting point. A
stack trace tells us where the program stopped and how that point was reached
through all the functions up to main(). A useful stack trace provides filenames
and line numbers.
You can provide a stack trace using one of the methods listed below.
<b>Method 1 - ASAN</b>
AddressSanitizer (ASAN) is a tool that detects memory error bugs and has
been implemented in GCC since v4.8. It is invoked by simply compiling
and linking with `--fsanitize=address` flag.
This method is the easiest if you are prepared to compile jgmenu. You
might balk at this, but jgmenu is very fast and simple to build,
compared to many other software packages. See INSTALL.md for details of
build dependencies and then take the following steps and report the
output.
git clone https://github.com/johanmalm/jgmenu
cd jgmenu
make ASAN=1
./jgmenu
The `ASAN=1` variable enables ASAN and sets some flags for a useful stack
trace. Upon a crash, you will see something like this:
#0 0x4a1ad2 in build_tree /home/johan/src/jgmenu/jgmenu.c:1099
#1 0x4aa077 in main /home/johan/src/jgmenu/jgmenu.c:2441
#2 0xb686d285 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18285)
#3 0x499a70 (/home/johan/src/jgmenu/jgmenu+0xba70)
<b>Method 2 - gdb</b>
In order to get a useful stack trace with gdb, you need binaries with
debug symbols. Release packages have generally been 'stripped' of these,
so you have two options:
- Install a package with debug symbols (e.g. jgmenu-dbgsym on
BunsenLabs Linux). This option has the advantage of not needing to
build the binaries.
- Compile with `-g` and `-Og' flags as a minimum.
jgmenu CFLAGS are set in `Makefile.inc`
There are two ways of producing a stack trace with gdb. Either run the
programme in gdb and trigger the crash;
gdb jgmenu
(gdb) handle SIG64 noprint nostop # or similar
(gdb) run
# wait for crash
(gdb) backtrace
or analyse a core dump after a crash.
gdb <exec> <core>
(gdb) backtrace
When using the `gdb jgmenu` approach, be aware that jgmenu grabs the
keyboard and pointer, so interaction with gdb is not straight forward.
If you get it wrong, you may need to log into a different tty (e.g.
ctrl+alt+F2) and `killall jgmenu ; killall xterm` (or whatever terminal
you use).
With both approaches, remember that the jgmenu package contains many
binary files, so it's important to run gdb on the one with the issue.
For example, if the 'ob' modules caused a segfault and core dump, you
need to run
gdb jgmenu-ob <core>
In order to use the `gdb <exec> <core>` method, your system needs to be
configured to core dump and you need the filename and location of the
core dump file. Consult your OS/distribution documentation for details
on this.
The segfault/abort error message will indicate if the core has been
dumped, e.g: `Segmentation fault (core dumped)`.
If you system has not been setup to core dump, you can use the command
`ulimit -c unlimited` to force a core dump in a specific shell session.
In this scenario, the core will be dumped in the current working
directory.
<b>Method 3 - coredumpctl</b>
If your system is set up to core dump and you have coredumpctl installed,
you can run the following and include the output in your bug report.
sudo coredumpctl info jgmenu
|