How do I report bugs in GPSD?

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

1. Read this whole FAQ first

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

2. Make sure it's not a problem with your toolchain or OS

See our page on upstream bugs.

3. 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.

4. 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."

5. 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.

6. Trim the capture 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.

7. 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.

8. Annotate the capture log and send us a copy

A logfile should consist of an identifying header followed by a straight unencoded dump of GPS data, whether NMEA or binary. The header should consist of text lines beginning with # and ending with LF. Here is the beginning of one log file I already have:

# Name: Magellan eXplorist 210
# Chipset: unknown
# Cycle-time: 1-second
# Start-of-cycle: $GPGLL
# Submitted-by: "Paul B van den Berg" 
# Date: 20 May 2006
# Location: Groningen, NL, 53.2N 6.6E
#
# mode V2.1 GSA
# Lines up to but not including the first GPGLL are
# `cat /dev/ttyACM0` at startup 
# Following lines are
# `cat /dev/ttyACM0` stationary
$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B
$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78
$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79
$PMGNST,01.75,3,F,816,11.1,+00000,20*5E
$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B
$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78
$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79
$PMGNST,01.75,3,F,816,11.1,+00000,20*5E
$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B
$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78
$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79
$PMGNST,01.75,3,F,822,11.2,+00000,20*5A
$GPGSV,3,1,00,,,,,,,,,,,,,,,,*7B
$GPGSV,3,2,00,,,,,,,,,,,,,,,,*78
$GPGSV,3,3,00,,,,,,,,,,,,,,,,*79
$PMGNST,01.75,3,F,822,11.2,+00000,20*5A
$GPGSV,3,1,12,09,76,287,,17,38,073,36,26,34,163,,05,33,230,*72
$GPGSV,3,2,12,29,27,161,,18,24,256,,22,24,299,,28,11,055,*73
$GPGSV,3,3,12,14,08,319,,11,03,017,,30,02,232,,24,00,084,*71
$PMGNST,01.75,3,F,822,11.2,-00673,20*5E
$GPGLL,5313.2228,N,00634.4228,E,200619.295,A*35
$GPGGA,200619.30,5313.2228,N,00634.4228,E,1,05,2.6,00000,M,,,,*2C
$GPRMC,200619.30,A,5313.2228,N,00634.4228,E,00.0,000.0,200506,00,W*59
$GPGSA,A,3,26,05,22,09,18,,,,,,,,05.1,02.6,04.4*03
$GPGSV,3,1,10,09,78,288,39,17,38,071,,05,34,230,45,26,33,163,39*77
$GPGSV,3,2,10,29,26,162,,18,24,255,42,22,24,298,44,28,10,056,*75
$GPGSV,3,3,10,14,09,319,,11,03,016,,136,27,157,,124,28,162,*71

The way to fill in the Name, Cycle-Time, Submitted-by, and Date headers should be pretty obvious.

Chipset should include the name and (if possible) model and/or firmware revision of the chipset in the GPS.

Start-of-cycle should be the name of the NMEA sentence (or, in a packet protocol, the numeric type ID of the packet) that is emitted first in each cycle.

Please also include a Location header giving your city, state/province, country code, and a rough latitude/longitude.

A log file is most useful when it contains (a) some sentences generated when the GPS has no fix, (b) some sentences representing a fix with the GPS stationary, and (c) some sentences representing a fix with the GPS moving.

If you have notes or comments on the logfile or the GPS, or any additional information you think might be helpful, add them as additional # comments (not containing a colon) after these headers. The test machinery that interprets the headers will ignore these and any empty comment lines.

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

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

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

Though it happens seldom (and we haven't had such a report since about mid-2005), 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.

11. 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 bisection search 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.

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

Always include with your bug report the GPS vendor and model. Try to include the firmware version as well. This should be in your xgps display if your GPS device makes it available; in a form field before 2.35, or as the window title in 2.35 and later. If the ID string is too long to fit, let the daemon run for a few minutes and issue an "I" command to it. Alternatively, running the daemon at -D 4 may reveal the version.

Why does the first A,E,O,P,T,U, or V command to a device always return "?"

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 behavior. 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 and libgps 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; they were poorly thought out and are only retained for backward compatibility. You should fix your application to use watcher mode — or better yet, the libgps client library.

Why does my single-shot query fail to return fix data?

This is closely related to the previous item.

The old-style query commands such as P and A are are safe to use with J=1 if you're polling repeatedly, but they're a dicey way to go if you're opening a channel to gpsd, doing a single-shot query, and then hanging up. Even repeating the query a few times won't necessarily work.

The problem is that your queries are in a race with the daemon's logic for assigning and initializing a GPS. It won't try to assign a GPS to your channel until the first command that demands actual device information.

Then the race begins. The daemon will be interleaving reads of whatever packet fragments the GPS is shipping with reads from your client socket. It is entirely possible that the rest of your commands will get processed before the daemon reads and processes enough GPS sentences to get a fix — especially if the serial device is slow and the GPS has a long initialization sequence.

(A similar race existed in gpsd versions before multi-device support was added in 2.21; if you issued a query too soon after device open it would fail in exactly this way.)

The right way to code your client is to set watcher mode and read a couple of O responses before trying to parse one. That way the daemon paces the action, actually telling the client when it receives packets.

To be certain of having full fix data, you'd need to wait for as many O responses as there are sentences that set fix data in the device's normal cycle. For SiRFs, one read will do because normally only one sentence in the cycle ships fix data. For NMEA devices you don't have a full fix before five reads, enough for an entire GPRMC/GPGGA/GPVTG/GPGLL/GPGSV cycle in whatever permutation the device ships it.

In practice, three O reads will always be enough to get you some fix information — worst case is your first O came from a GPGSA and all you get is a mode, and then you get GPVTG, but you'll always get lat/lon on the next O.

Clients that poll P or A repleatedly won't have a problem; the race effects will show up but be limited to noise in the first few seconds of samples.

Why does my receiver report wildly fluctuating speed?

If your problem is wildly fluctuating speed reports on a SiRF, switching on static navigation mode using the 'c' command in sirfmon. Static navigation mode will freeze your position if your speed is below 1.2 m/s for three seconds, and will begin updating your position again when speed exceeds 1.4 m/s. This prevents multipath, weak signals, or poor constellation geometry from dragging your solutions around too much. Other receivers may suffer the same problem and may have a similar solution.

Why do I get implausibly low speeds when using gpsdrive?

This is a gpsdrive bug, as you can verify by running xgps alongside it.

Why does the date field 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.

The -j option of xgps will work around this problem. It sends gpsd an initialization command that causes it not to clear fix data at the beginning of each reporting cycle. This will eliminate the flicker, but means that you may occasionally see stale and invalid data.

Why does xgps flicker between displaying FIX and NOFIX about once a second?

It's the same problem as the previous entry, and can be banished with the -j option.

Other fields may flicker as well; latitude is especially prone to this. Usually the problem only affects NMEA devices, so if you are using something wuith a SiRF or other chipset that reports in a non-NMEA format you will never see it.

Why doesn't gpsd set its J=1 option by default and avoid the flicker problem?

Because that's policy, and policy is really the client's job. We choose to make gpsd report what the GPS tells it as faithfully as it can without making assumptions about how the client wants to use the data.

The design issues here are much thornier than they at first appear. See this extended discussion in the Hacker's Guide.

Why do I get 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.

You can download a shellscript that does this.

Why do I have to restart gpsd whenever I power-cycle my Bluetooth device?

The Bluetooth stack returns 0 for a read from a missing device, rather than -1, and doesn't set errno. This is wrong and needs to be fixed at OS level.

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 use 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.
  8. It took us two years of hard work, but as of late 2006 gpsd dominates its application niche so completely that every competitor we knew of in 2004 has been abandoned by its own maintainers in our favor. The 1.x versions or any fork you use won't be getting any future maintenance.

Why use the 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.

How do I get gpsd data into a web page?

The gpsd source-code distribution now includes a PHP script that makes this easy. The script shows current fix data, a satellite view, and can even incorporate a Google Maps display if you have a Google API key. Look at the end of the file INSTALL for instructions.

Another way is to use a perl CGI script that leverages Net::GPSD like this...

#!/usr/bin/perl -w
use strict;
use Net::GPSD;

my $g=new Net::GPSD;
my $p=$g->get;

print qq{
<?xml version='1.0'?>
<Report xmlns:gml="http://www.opengis.net/gml">
  <items>
    <Item>
      <ID>35643563245</ID>
      <position>
        <gml:Point srsDimension="2"
srsName="urn:ogc:def:crs:EPSG:6.6:4326">
          <gml:pos>}. $p->lat. " ". $p->lon. q{</gml:pos>
        </gml:Point>
      </position>
    </Item>
  </items>
</Report>
};
</code>

This will return something like:

<?xml version='1.0'?>
<Report xmlns:gml="http://www.opengis.net/gml">
  <items>
    <Item>
      <ID>35643563245</ID>
      <position>
        <gml:Point srsDimension="2" srsName="urn:ogc:def:crs:EPSG:6.6:4326">
          <gml:pos>38.865960 -77.108624</gml:pos>
        </gml:Point>
      </position>
    </Item>
  </items>
</Report>