unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
blob 3a335a467bca73e4497f2a202ff608b88dd48da4 4232 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 automate git bisect to find the commit
that introduced an Emacs bug.  Bisecting automatically works best if
the bug is easy and quick to reproduce in a clean ‘emacs -Q’ instance.

For an Emacs-independent tutorial on bisecting, run ‘git help bisect’.

* Automating ‘git bisect’

Use ‘git bisect run <some-shell-script>’ to automate the bisecting
process.  ‘<some-shell-script>’ should build Emacs, run your bug
reproduction test, and return 0 if the current revision is good, 1 if
it's bad, and 125 to skip the current revision.

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

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 return the right error code
  using ‘(kill-emacs EXIT-CODE)’).

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

** Ways to programmatically detect display bugs

Most bugs that manifest graphically can be checked for by
programmatically inspecting the following elements:

- text properties
- window-start and window-end
- posn-at-point
- pos-visible-in-window-p
- frame-geometry
- window--dump-frame
- frame--size-history
- display-monitor-attributes-list
- C-u C-x =
- trace-redisplay and trace-to-stderr
- dump-glyph-matrix and dump-frame-glyph-matrix

** When the above fails

Some bugs are only apparent through visual inspection.  Since building
Emacs takes a long time, it can be a pain to debug these manually.

If your display bug has a clear manifestation in a screenshot of a
particular portion of Emacs display, and you have a program, like
'xwd', that can capture the content of the Emacs frame, and also have
ImageMagick installed, you can automate the comparison of the
redisplay results to make the bisection process fully automatic.

Use the following template for ‘../reproduce-the-bug.el’: it requires
ImageMagick (mogrify and identify) and xwd (if ‘xwd’ isn't available,
you can use ImageMagick's ‘import’ tool, passing it a ‘-window’
argument where ‘xwd’ wants ‘id’).

    (defun image-checksum (img-fname)
      "Compute a checksum of IMG-FNAME's image data."
      (car (process-lines "identify" "-quiet" "-format" "%#" img-fname)))

    (defun take-screenshot-and-exit (fname x y w h reference-fname)
      "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.  This function sets
    Emacs' return code to 0 if the resulting screenshot matches
    REFERENCE-FNAME, and 1 otherwise."
      (let ((wid (frame-parameter nil 'outer-window-id))
            (crop-spec (format "%dx%d+%d+%d" w h x y)))
        (call-process "xwd" nil nil nil "-silent" "-id" wid "-out" fname)
        (call-process "mogrify" nil nil nil fname "-crop" crop-spec))
      (let ((same-picture (equal (image-checksum fname)
                                 (image-checksum reference-fname))))
        (kill-emacs (if same-picture 0 1))))

    (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" … … … … "reference-screenshot.xwd"))

    (main)

This script takes and crops a screenshot of Emacs after reproducing
your bug, then compares the result to a reference (cropped)
screenshot, and returns 0 if they match, and 1 otherwise.  Cropping is
useful to weed out unrelated display changes; try to include only a
small portion of the screen containing your bug.

debug log:

solving 3a335a4 ...
found 3a335a4 in https://yhetil.org/emacs-devel/20f2bf0b-8805-103d-9aeb-648317b270d6@gmail.com/

applying [1/1] https://yhetil.org/emacs-devel/20f2bf0b-8805-103d-9aeb-648317b270d6@gmail.com/
diff --git a/admin/notes/bisecting b/admin/notes/bisecting
new file mode 100644
index 0000000..3a335a4

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

index at:
100644 3a335a467bca73e4497f2a202ff608b88dd48da4	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).