unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
blob 4efb5ccc6693a8b90e0e898395cad1d51b27e900 4334 bytes (raw)
name: admin/notes/bisecting 	 # note: path name is non-authoritative(*)

  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
 
HOW TO USE GIT BISECT TO PINPOINT EMACS BUGS  -*- outline -*-

This documents explains how to use git bisect to find the commit that
introduced an Emacs bug.  Bisecting works best if the bug is easy and
relatively quick to reproduce in a clean ‘emacs -Q’ instance.

For general information about bisecting, use ‘M-x man git-bisect’.
This document contains quick-start instructions and Emacs-specific
tips.

* Bisecting Emacs bugs

First, find a recipe that reproduces the bug in emacs -Q.  Then use
this recipe to locate a revision in which the bug doesn't happen.  If
it's a new bug, a not-too-recent revision could do; otherwise,
checking for the bug previous releases of Emacs works well.

Then, run the following command to start bisecting

    git bisect start <buggy-revision> <good-revision>

<buggy-revision> is usually HEAD in practice.

Git will then check out revisions between these two bounds,; at each
step, you need to run ‘git bisect good’ or ‘git bisect bad’ to inform
git of the status of the current revision: ‘bad’ if it has the bug;
good if it doesn't.

If Emacs' build is broken in the current revision, use ‘git bisect
skip’ to move to a neighboring revision.

** Automating ‘git bisect’

You can also write ‘git bisect run <some-shell-script>’ to automate
the process.  ‘<some-shell-script>’ should build Emacs, run your bug
reproduction test, and return 0 if the current revision is good, and 1
otherwise.  Returning 125 is equivalent to doing ‘git bisect skip’.

Concretely, ‘<some-shell-script>’ usually looks like this:

    #!/usr/bin/env bash

    # Remove leftovers from previous runs
    git clean -xfd > /dev/null
    # Build Emacs and skip commit if build fails
    (./autogen.sh && ./configure --cache-file=/tmp/emacs.config.cache && make -j4) || exit 125

    # Reproduce the bug, writing output somewhere
    src/emacs -Q -l "../reproduce-the-bug.el" || exit 125
    # Remove leftovers again
    git clean -xfd > /dev/null
    # Analyze output and produce exit code
    cmp ../reference-output current-output

Some caveats:

- This script cleans Emacs' source directory with ‘git clean -xfd’, so
  make sure your uncommitted changes are saved somewhere else.

- You should produce the ‘../reproduce-your-bug.el’ script on your own
  (it should check if the bug exists, and save a different output to a
  file named ‘current-output’ based on the result of that check), as
  well as a file ‘../reference-output’ containing the expected output
  in the good case.

** Using ‘git bisect’ to find display-related bugs

Most bugs that manifest graphically can be checked for by
programmatically inspecting text properties, but some are only
apparent through visual inspection.  Since building Emacs takes a long
time, it can be a pain to debug these manually.

Fortunately, it's relatively easy to bisect such bugs automatically.
Use the following template for ‘../reproduce-the-bug.el’:

    (defun take-screenshot-and-exit (fname x y w h)
      "Save a screenshot of Emacs as FNAME, then exit.
    X and Y are the coordinates of the top-left point of the area of interest.
    W, and H are its dimensions."
      (let ((window-id (frame-parameter nil 'outer-window-id)))
        (call-process "xwd" nil nil nil "-silent" "-id" window-id "-out" fname))
      (call-process "mogrify" nil nil nil fname "-crop" (format "%dx%d+%d+%d" w h x y))
      (kill-emacs))

    (defun main ()
      ;; Reproduce your bug here
      …
      ;; Force a redisplay
      (redisplay t)
      ;; Insert rough X, Y, W, H values below
      (run-with-timer 0 nil #'take-screenshot-and-exit "screenshot.xwd" … … … …))

    (main)

This script makes a screenshot of Emacs after reproducing your bug (if
‘xwd’ isn't available, you can use ImageMagick's ‘import’ tool,
passing it a ‘-window’ argument where ‘xwd’ wants ‘id’).  Cropping the
image is useful to weed out unrelated display changes; try to include
only a small portion of the screen containing your bug.

Then to produce the right exit code use ImageMagick's ‘identify’ tool:

    cmp <(identify -quiet -format "%#" "../screenshot.xwd") <(identify -quiet -format "%#" "../good.xwd")

‘good.xwd’ should be the image produced by your script in the good state.

debug log:

solving 4efb5cc ...
found 4efb5cc in https://yhetil.org/emacs-devel/5782E073.6000505@gmail.com/

applying [1/1] https://yhetil.org/emacs-devel/5782E073.6000505@gmail.com/
diff --git a/admin/notes/bisecting b/admin/notes/bisecting
new file mode 100644
index 0000000..4efb5cc

Checking patch admin/notes/bisecting...
Applied patch admin/notes/bisecting cleanly.

index at:
100644 4efb5ccc6693a8b90e0e898395cad1d51b27e900	admin/notes/bisecting

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).