How do I report bugs in GPSD?

When you have a problem with gpsd, here are some steps you can take to gelp us resolve the bug as quickly as possible.

Read this whole FAQ first

First, read this whole FAQ before reporting apparent misbehavior as a bug. You may find a solution here.

Make sure it's not a problem in your client software

Make sure it is a real gpsd bug and not a problem with your client software. A good way to do this is to run your client and the gpsd test client (xgps) side by side. If xgps seems to report good numbers but your client does not, you have a client problem. If xgps reports the same sort of bad numbers as your client, you have a real gpsd bug.

Check the latest version of gpsd for the bug.

If you are using an old version of gpsd, it is possible your bug has already been fixed. Download the latest public version from the project page and test it. To be really helpful, check out the Subversion head and test that. We don't mind getting bug reports that say "I saw version foo had the following bug, but you've fixed it."

Capture a log that triggers the problem

If we can reproduce your gpsd problem, we can usually fix it very rapidly. If we can't reproduce it, you might get lucky or you might not — and we try hard, but all too often the result is 'not'.

Therefore the most important step you can take is to capture a log of some GPS output that reproduces the bug. If you're using a SiRF chip, the 'l' command of sirfmon will help you. If you're using a GPS that emits NMEA, telnetting to port 2947 and enabling raw mode will do the trick. For non-SiRF binary protocols, you will have to cat direct from the serial device into a file.

Trim the log that reproduces the problem

Your next step should be to feed the log you just captured to a gpsd instance through gpsfake to verify that the log does in fact reproduce the bug.

Once you have the log, trim it to the smallest span of data that reproduces the bug. A systematic way to do this is to cut the log in half at the middle and test each half. If one half doesn't reproduce the bug but the other does, throw away the half that doesn't. Repeat this procedure on each half that tickles the bug until you can't make it any smaller. Then send us that.

If possible, use the -l option of gpsfake to pin down the sentence or packet that produces the bug, and tell us that.

Look at gpsd log output to see if it gives you a clue

You may get a better handle on your problem by running gpsd in foreground (-N option) with the -D option set to a high level (-D 4 is often good). If the transcript has anything that looks like a clue in it, send it along with your bug report. When in doubt about whether it holds a clue, send it.

One of the things this should tell you, if the chip reports it at all, is the firmware version. You will want that for your report.

If it's a dual-mode GPS, see if the problem reproduces in NMEA mode

If you're using a SiRF, Evermore, or iTalk GPS in binary mode (which you can tell from the -D 4 output), switch back to NMEA mode using the N command and see if the bug still reproduces.

If your bug core-dumps gpsd, send us a stack trace.

Though it happens seldom, badly-formed NMEA from a device with poor standards compliance has been known to core-dump gpsd. If your gpsd has core-dumped, try to use gdb or whatever your local symbolic debugger is to generate a stack trace of the crash, and send us that.

Try to determine what release introduced the bug

If you have upgraded from a previous version of gpsd, and the upgrade broke something that was working previously, the most useful thing you can do is pin down the release in which the bug was introduced.

How efficiently you can do this depends on whether or not you have a client for the Subversion version control system. If you don't, all you can do is download and test named releases. If you do, you can pin down the exact change that introduced the bug. The latter is far more helpful to us and will get your bug fixed faster, so we'll describe that procedure here.

  1. Follow these instructions to check out a copy of the software.

  2. Do "svn log *" in the top-level directory of the checked-out tree. Save the results. This is your map of dates to revision levels.

  3. Determine the revision levels of the first known bad release and the last known good release. You can do this by looking for the release dates from gpsd.spec in the log output. Note: pick the first revision matching the known-good date and the last revision matching the known-bad date.

  4. Use the -r option of svn up to check out the revision level in the middle of that range. Thus, if the last known good release was 2502 and the known bad one is 2760, check out release (2760 + 2502) / 2 = 2631. The command you want would be "svn -r 2631 up" in this case.

  5. Build and test the revision. Whether it works or not, you will eliminate half the range. If it works, you know the bug was introduced somewhere in the upper half range. If it doesn't, the bug was introduced in the lower half.

  6. Do the same test on the half-range where the error was introduced; e.g. check out the middle version, test that, and narrow the range by another factor of 2.

  7. Repeat this procedure until you know the exact revision that introduced your bug. This will happen very quickly, as the number of tests required will be the log to the base 2 of the number of revisions in your original span. Even if there are (say) 500 revisions in the span you should only require 9 tests to nail down the exact change in question.

Include the vendor, mode, and firmware version in your report.

Always include with your bug report the GPS vendor and model. If your GPS is SiRF-based, include the firmware version as well. You can find out what that is by running at the daemon at -D 4.

The first A,E,O,P,T,U, or V command to a device always returns ?

To understand what's going on, you need to know that gpsd does not immediately assign a client a GPS from its pool of known devices when the client connects. Rather, it waits until the client issues a command that requires GPS information.

The reason for this goes back to when multi-device support was added in 2.21. In a multi-device world, what the client might want to do is list available GPSes (with K) and choose one (with F). There is also at least one other command, L, that doesn't require a GPS. And in general, waiting until a GPS is really needed to wake one up is a good idea — it saves power, which can be important because GPS-equipped computers are more than likely running off a battery.

So gpsd now defers binding the device. Your first request for fix data triggers the action of binding a GPS to your channel, but at that time no GPS is yet bound. The GPS doesn't have a fix, so you get ?. But by the time of your next request gpsd has polled the daemon and has a fix.

Generally only human beings testing gpsd via telnet/ssh ever notice this bug. gpsd-using applications poll the daemon repeatedly; the delay before the second response comes in normally is not noticeable.

We haven't fixed this because the test clients all use watcher mode. In watcher mode, you get 'O' updates whenever the GPS ships a recognized sentence. The old-style individual requests are obsolete, really. You should fix your application to use atcher mode — or better yet, the libgps client library.

Have wildly fluctuating speed? Try static navigation

If your problem is wildly fluctuating speed reports on a SiRF, switching on static navigation mode using the 'c' command in sirfmon.

The date and other fields in xgps flicker to "n/a" part of the time even when there's a fix.

The sentence or packet your GPS uses to report satellite bearing/elevation has no timestamp. The xgps date display flickers to "n/a" when it has just seen this report.

This is a known problem. It's not a bug — or, at least, not a bug in the GPSD code. Blame the idiot protocol designers who saw fit not to timestamp their satellite-data packet. (NMEA and Garmin GPSes don't. SiRF GPSes do. Score one for SiRF.)

gpsd is faithfully reporting the information it is getting from the GPS, including the fact that the Y sentence contains no date. That's its job. The libgps library is doing its bit by passing everything from gpsd on to the client application as it arrives, including the lack of date.

Other fields may flicker as well; latitude is prone to this on NMEA devices. It's the same problem. In theory, a client could accumulate data through an entire send cycle from the GPS, and change the display only once at end of cycle. The problem with this is that there is so much variation in the order GPS sends sentences that there is no no way to spot end-of-cycle — the best you could do would be to wait until a sentence-timestamp change signals the start of a new cycle, at which time the buffered data is by definition obsolete.

It's the client's job to interpret/interpolate/fill in gaps, to do policy. What you're seeing as a bug only looks like one because xgps, as is proper for a test client, has as little policy as possible.

Flaky results when I try to use gpsd with Kismet

Kismet's interface was designed for a much older version of gpsd, and tends to fight with the autobauding code in the newer versions. The Kismet maintainer has promised to fix this. Until he does, the workaround is to start gpsd and make sure it has synced up to a GPS before running Kismet.

My gpsd sometimes stops responding overnight

At one point in the development of gpsd we got a report of the daemon ceasing to respond to queries when run for more than a day or so; the user, quite reasonably, suspected some sort of resource leak in the daemon. On the other hand, other users reported good operation over much longer periods with the same version of the software. That suggests a bug at the level of the user's operating system or local site configuration.

Nevertheless, the possibility of a resource-leak bug alarmed us enough that after 2.26 one of us (ESR) built an entire test framework for auditing the code's dynamic behavior and used it to apply Valgrind. You can look at the resulting script, valgrind-audit, in the source distribution. This turned up a couple of minor leaks, but nothing sufficient to explain the report.

One of our senior developers, Rob Janssen, has seen gpsd interact badly with overnight backups, pushing the system load average through the roof. He says: "when you copy many gigabytes of data from disk to disk, the [Linux] kernel's buffer management goes completely haywire. [...] I think this is caused both by allocation of many buffers for reading files, and by accumulation of many dirty buffers that still have to be written. At some point, programs like gpsd (but also all interactive programs and the X display manager) come to a complete standstill while the system is swapping like mad."

If Rob's analysis is correct, gpsd is a canary in a coal mine. If your gpsd locks up after a long period of operation, you should look at your logs and see if you can connect the point at which it stopped responding to some kind of resource crisis brought on by lots of I/O activity.

Another thing to try is running gpsd under Valgrind overnight and seeing if it reports any leaks.

Why this version of gpsd?

If you have written a gpsd-aware application using one of the old 1.x versions, or a fork such as ngpsd or tgpsd, here are some good functional reasons to migrate to 2.0:

  1. Hotplug- and reconnect support. Your application does not have to be aware of GPS device connects and disconnects, but can choose to be by watching for X commands.
  2. Your application can now query whether or not the GPS is online and get an authoritative answer.
  3. Timestamps are now no longer truncated to seconds, but reported to whatever resolution the GPS ships. Often (notably on SiRF-II GPSes) this is milliseconds.
  4. There is a new "watcher" mode. It is like raw mode in that the GPS streams updates at you, but unlike it in that the updates are in the simpler GPSD format rather than the more complex NMEA one.
  5. The daemon now automatically tries to reconnect to the GPS once a second when it is offline but clients are connected.
  6. Writes to clients are nonblocking, so new gpsd cannot be stalled by a wedged client.
  7. The code in the new version has been carefully audited for quality, static-checked using splint, and is regression-tested before every release.

Why use gpsd protocol rather than parsing raw NMEA?

Some applications that use gpsd start raw mode with the 'r' command and parse the NMEA directly. This is not a good idea.

One problem with raw mode is that NMEA is a poorly specified standard. There are, for example, two different and incompatible variants of GPVTG. Another issue is that implementations vary as to whether they leave fields they don't supply empty or fill them in with a special value such as 0.0. Interpretation of the different NMEA status fields is a black art.

It is all too easy to write an NMEA parser that works well on one variant but breaks on another, delivering subtly incorrect results or even crashing your application. Because gpsd specializes in the job, we collect knowledge on all variants and do parsing that is much less likely to get tripped up.

Another issue is that some of the reports your application would like to have are not generated by all GPSes. Estimated position error in meters is the most obvious example; climb/sink is another. When a GPS doesn't supply these, gpsd can fill them in using the same sorts of computation that more capable GPSes use.

How should I interface my application with gpsd?

The gpsd package provides two ways for C code to get data from a GPS. Both go through the libgps.a library, which supports two sets of entry points. The low-level interface talks directly to the GPS. The high-level interface communicates with an instance of gpsd, which uses its own copy of libgps.a to talk to the device.

A third way would be to open a socket to gpsd and interpret gpsd protocol or raw NMEA in your application. Before 2.0, all gpsd-aware applications had to do this because libgps.a didn't exist. Now that it does, the exercise is rather pointless. Using libgps.a will probably simplify your code a lot.

You will almost always want to use the high-level interface and go through the daemon; among other things, this means more than one application will be able to query the GPS without causing confusion. The only exception will be in very space-constrained single-user scenarios, perhaps on embedded systems or PDAs. On those it may be appropriate to use the low-level interface directly, probably with a build from source that conditions out all but one of the drivers.

For Python programmers, there is a gps.py module the high-level interface. It exports a class that encapsulates a GPS session.

How has the gpsd interface changed since 1.x?

There are three minor incompatibilities with gpsd 1.x:

First, gpsd-2's command-line options have been changed and simplified. If your gpsd-using application is starting up gpsd directly you may find you have to modify the invocation. However, we don't recommend this. New gpsd is designed to be started by hotplug scripts when a USB device wakes up, or started at boot time and run continuously just like any normal daemon. It will do nothing, and be swapped out, unless there are clients trying to query the GPS.

Second, gpsd now returns "?" as the contents for a field when it doesn't have valid data for that field (e.g. latitude or longitude before the first fix). This is only an issue if you are interpreting GPSD responses yourself rather than using libgps.a or the gps.py Python module.

Third, the format of the timestamp returned by the D command has changed, from "%m/%d/%Y %H:%M:%S" to ISO-8601: "%Y-%m-%dT%H:%M:%SZ". No more U.S.-centric date-format assumptions! Also, as previously noted, the seconds part may have one or more digits of decimal fractional seconds.