Assertion !is_empty() failed - yet again

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

Assertion !is_empty() failed - yet again

Andrew Bernard
Lilypond 2.19.83. Yet again I see this error:

Drawing systems...
Finding the ideal number of pages...
Fitting music on 15 or 16 pages...
Drawing systems...lilypond:
/home/gub/NewGub/gub/target/linux-64/src/lilypond-git.sv.gnu.org--lilypond.git-stable-test/flower/include/interval.hh:227:
T Interval_t<T>::center() const [with T = double]: Assertion `!is_empty ()'
failed.
Aborted (core dumped)
make: *** [Makefile:57: sq1-215.pdf] Error 134

After only about 30 pages of dense string quartet music, now happens when I
just add one more note. This came up for me before with tuplets, but now a
plain note triggers this.

How do we move forward on solving this? Once more, irritatingly for me and
for all, I don;t know how to make an MWE to stimulate this.

Perhaps resort to gdb backtrace again?

Andrew
_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

David Kastrup
Andrew Bernard <[hidden email]> writes:

> Lilypond 2.19.83. Yet again I see this error:
>
> Drawing systems...
> Finding the ideal number of pages...
> Fitting music on 15 or 16 pages...
> Drawing systems...lilypond:
> /home/gub/NewGub/gub/target/linux-64/src/lilypond-git.sv.gnu.org--lilypond.git-stable-test/flower/include/interval.hh:227:
> T Interval_t<T>::center() const [with T = double]: Assertion `!is_empty ()'
> failed.
> Aborted (core dumped)
> make: *** [Makefile:57: sq1-215.pdf] Error 134
>
> After only about 30 pages of dense string quartet music, now happens when I
> just add one more note. This came up for me before with tuplets, but now a
> plain note triggers this.
>
> How do we move forward on solving this? Once more, irritatingly for me and
> for all, I don;t know how to make an MWE to stimulate this.
>
> Perhaps resort to gdb backtrace again?

Yes?  That's what the "core dumped" triggered by assertion failures is
good for.  Which is why "abort" should not be marked "noreturn" in
gcclib so that gcc maintains a stack state useful for backtrace analysis
rather than saying "what the heck, I won't return anyway".  But you tell
that to Drepper and you'll get derided from here to Westborough.

But most of the time, a backtrace will be useful for failed assertions
(I debugged around for days for a case where gcc decided to just fold
all abort calls in some function to the same place but that happens
rarely).

--
David Kastrup

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

Andrew Bernard
Thanks David.

I built 2.21.0 on Ubuntu 19.04. Running gdb, sure enough, it's the familiar
tuple bracket issue:

Drawing systems...lilypond:
/home/andro/lilypond-git/flower/include/interval.hh:227: T
Interval_t<T>::center() const [with T = double]: Assertion `!is_empty ()'
failed.

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50    ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) backtrace
#0  0x00007ffff76bfed7 in __GI_raise (sig=sig@entry=6) at
../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff76a1535 in __GI_abort () at abort.c:79
#2  0x00007ffff76a140f in __assert_fail_base
    (fmt=0x7ffff782f588 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=0x55555594ab94 "!is_empty ()", file=0x55555594abb8
"/home/andro/lilypond-git/flower/include/interval.hh", line=227,
function=<optimised out>) at assert.c:92
#3  0x00007ffff76b1012 in __GI___assert_fail
    (assertion=assertion@entry=0x55555594ab94 "!is_empty ()",
file=file@entry=0x55555594abb8
"/home/andro/lilypond-git/flower/include/interval.hh", line=line@entry=227,
function=function@entry=0x55555595c560 <Interval_t<double>::center()
const::__PRETTY_FUNCTION__> "T Interval_t<T>::center() const [with T =
double]") at assert.c:101
#4  0x00005555556d93c7 in Interval_t<double>::center() const
(this=<optimised out>) at
/home/andro/lilypond-git/lily/include/lily-guile-macros.hh:70
#5  0x00005555556d93c7 in Tuplet_number::calc_x_offset(scm_unused_struct*)
(smob=<optimised out>) at /home/andro/lilypond-git/lily/tuplet-number.cc:293

Last time this arose Aaron provided this code for me:

    \override TupletBracket.X-positions = #(lambda (grob)
   (let ((xpos (ly:tuplet-bracket::calc-x-positions grob)))
     (if (> (car xpos) (cdr xpos))
       (let ((mid (/ (+ (car xpos) (cdr xpos)) 2)))
         (format #t "\nwarning: Fixing invalid X-positions ~a" xpos)
         (cons mid mid))
       xpos)))

Adding that prints a warning, and works around the issue, and I can,
thankfully go on.

But since this keeps coming up, is it something that should be reported as
a bug, so as to eventually get fixed?

Andrew





On Fri, 26 Apr 2019 at 22:47, David Kastrup <[hidden email]> wrote:

> Andrew Bernard <[hidden email]> writes:
>
> > Lilypond 2.19.83. Yet again I see this error:
> >
> > Drawing systems...
> > Finding the ideal number of pages...
> > Fitting music on 15 or 16 pages...
> > Drawing systems...lilypond:
> > /home/gub/NewGub/gub/target/linux-64/src/lilypond-git.sv
> .gnu.org--lilypond.git-stable-test/flower/include/interval.hh:227:
> > T Interval_t<T>::center() const [with T = double]: Assertion `!is_empty
> ()'
> > failed.
> > Aborted (core dumped)
> > make: *** [Makefile:57: sq1-215.pdf] Error 134
> >
> > After only about 30 pages of dense string quartet music, now happens
> when I
> > just add one more note. This came up for me before with tuplets, but now
> a
> > plain note triggers this.
> >
> > How do we move forward on solving this? Once more, irritatingly for me
> and
> > for all, I don;t know how to make an MWE to stimulate this.
> >
> > Perhaps resort to gdb backtrace again?
>
> Yes?  That's what the "core dumped" triggered by assertion failures is
> good for.  Which is why "abort" should not be marked "noreturn" in
> gcclib so that gcc maintains a stack state useful for backtrace analysis
> rather than saying "what the heck, I won't return anyway".  But you tell
> that to Drepper and you'll get derided from here to Westborough.
>
> But most of the time, a backtrace will be useful for failed assertions
> (I debugged around for days for a case where gcc decided to just fold
> all abort calls in some function to the same place but that happens
> rarely).
>
> --
> David Kastrup
>
> _______________________________________________
> bug-lilypond mailing list
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/bug-lilypond
>
_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

David Kastrup
In reply to this post by Andrew Bernard
Andrew Bernard <[hidden email]> writes:

> Lilypond 2.19.83.

That one or current master?  In the latter, it may be fixed.

> Yet again I see this error:
>
> Drawing systems...
> Finding the ideal number of pages...
> Fitting music on 15 or 16 pages...
> Drawing systems...lilypond:
> /home/gub/NewGub/gub/target/linux-64/src/lilypond-git.sv.gnu.org--lilypond.git-stable-test/flower/include/interval.hh:227:
> T Interval_t<T>::center() const [with T = double]: Assertion `!is_empty ()'
> failed.
> Aborted (core dumped)
> make: *** [Makefile:57: sq1-215.pdf] Error 134
>
> After only about 30 pages of dense string quartet music, now happens when I
> just add one more note. This came up for me before with tuplets, but now a
> plain note triggers this.
>
> How do we move forward on solving this? Once more, irritatingly for me and
> for all, I don;t know how to make an MWE to stimulate this.
>
> Perhaps resort to gdb backtrace again?
>
> Andrew

--
David Kastrup

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

Andrew Bernard
Hi David,

The reported error was from 2.19.83. But I built 2.21.0 last night, and the
error persists.

Andrew


On Sat, 27 Apr 2019 at 00:56, David Kastrup <[hidden email]> wrote:

> Andrew Bernard <[hidden email]> writes:
>
> > Lilypond 2.19.83.
>
> That one or current master?  In the latter, it may be fixed.
>
>
_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

David Kastrup
In reply to this post by Andrew Bernard
Andrew Bernard <[hidden email]> writes:

> Thanks David.
>
> I built 2.21.0 on Ubuntu 19.04. Running gdb, sure enough, it's the familiar
> tuple bracket issue:
>
> Drawing systems...lilypond:
> /home/andro/lilypond-git/flower/include/interval.hh:227: T
> Interval_t<T>::center() const [with T = double]: Assertion `!is_empty ()'
> failed.
>
> Program received signal SIGABRT, Aborted.
> __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
> 50    ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
> (gdb) backtrace
> #0  0x00007ffff76bfed7 in __GI_raise (sig=sig@entry=6) at
> ../sysdeps/unix/sysv/linux/raise.c:50
> #1  0x00007ffff76a1535 in __GI_abort () at abort.c:79
> #2  0x00007ffff76a140f in __assert_fail_base
>     (fmt=0x7ffff782f588 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
> assertion=0x55555594ab94 "!is_empty ()", file=0x55555594abb8
> "/home/andro/lilypond-git/flower/include/interval.hh", line=227,
> function=<optimised out>) at assert.c:92
> #3  0x00007ffff76b1012 in __GI___assert_fail
>     (assertion=assertion@entry=0x55555594ab94 "!is_empty ()",
> file=file@entry=0x55555594abb8
> "/home/andro/lilypond-git/flower/include/interval.hh", line=line@entry=227,
> function=function@entry=0x55555595c560 <Interval_t<double>::center()
> const::__PRETTY_FUNCTION__> "T Interval_t<T>::center() const [with T =
> double]") at assert.c:101
> #4  0x00005555556d93c7 in Interval_t<double>::center() const
> (this=<optimised out>) at
> /home/andro/lilypond-git/lily/include/lily-guile-macros.hh:70
> #5  0x00005555556d93c7 in Tuplet_number::calc_x_offset(scm_unused_struct*)
> (smob=<optimised out>) at /home/andro/lilypond-git/lily/tuplet-number.cc:293
>
> Last time this arose Aaron provided this code for me:
>
>     \override TupletBracket.X-positions = #(lambda (grob)
>    (let ((xpos (ly:tuplet-bracket::calc-x-positions grob)))
>      (if (> (car xpos) (cdr xpos))
>        (let ((mid (/ (+ (car xpos) (cdr xpos)) 2)))
>          (format #t "\nwarning: Fixing invalid X-positions ~a" xpos)
>          (cons mid mid))
>        xpos)))
>
> Adding that prints a warning, and works around the issue, and I can,
> thankfully go on.
>
> But since this keeps coming up, is it something that should be reported as
> a bug, so as to eventually get fixed?

I am looking at this code right now and it is not clear to me that
break-overshoot is used consistently.  Its usual settings are something
like

     (break-overshoot ,number-pair? "How much does a broken spanner
stick out of its bounds?")

Examples of this property are
Documentation/ly-examples/cary-layout.ily:    \override Beam.break-overshoot = #'(-0.5 . 1.0)
input/regression/beam-outside-beamlets.ly:  \override Beam.break-overshoot = #'(-0.5 . 0.5)
input/regression/spanner-break-overshoot.ly:  \override Beam.break-overshoot = #'(1.0 . 2.0)
input/regression/spanner-break-overshoot.ly:  \override TupletBracket.break-overshoot = #'(1.0 . 2.0)

so it's sometimes positive, sometimes negative.  The default code in
lily/tuplet-bracket.cc does

      if (connect_to_other[d])
        {
          Interval overshoot (robust_scm2drul (me->get_property ("break-overshoot"),
                                               Interval (-0.5, 0.0)));

          if (d == RIGHT)
            x_span[d] += d * overshoot[d];
          else
            x_span[d] = (bounds[d]->break_status_dir ()
                         ? Axis_group_interface::generic_bound_extent (bounds[d], commonx, X_AXIS)[-d]
                         : robust_relative_extent (bounds[d], commonx, X_AXIS)[-d])
                        - overshoot[LEFT];
        }

so the default value is negative which moves the left end of the span to
the _right_ since the left overshoot is subtracted.

The comparable code for beams does

                  if (on_line_bound
                      && me->get_bound (event_dir)->break_status_dir ())
                    {
                      current.horizontal_[event_dir]
                        = (Axis_group_interface::generic_bound_extent (me->get_bound (event_dir),
                                                                       commonx, X_AXIS)[RIGHT]
                           + event_dir * break_overshoot[event_dir]);
                    }

which again puts in a factor of -1 for the left bound, also using a
default value of -0.5 .

Is this negative break_overshoot (which reduces the extent on the left
side, possibly until the interval becomes empty) as intended or is this
a consequence of confusion?

--
David Kastrup

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

Rutger Hofman
I was also bitten by this assert, in a score with divisi staves that
appear/disappear depending on the VerticalAxisGroup.remove-layer settings
(see http://lilypond.org/doc/v2.19/input/regression/a6/lily-436997bb.ly)
which makes it nigh impossible to create a minimal example. I wouldn't be
surprised to learn that a suppressed staff might trigger this assert,
erroneously.

I downloaded 2.21 from git, commented out this assertion, and built.
Everything is fine now. No other unexpected or orroneous behaviour which
might have been caught by the assertion, in many projects.

Sincere request: can this assert please be removed? Its validity appears
debatable, and it is a showstopper for me!

Rutger



--
Sent from: http://lilypond.1069038.n5.nabble.com/Bugs-f58488.html

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

Aaron Hill
On 2019-10-30 2:05 am, Rutger Hofman wrote:
> Sincere request: can this assert please be removed? Its validity
> appears
> debatable, and it is a showstopper for me!

If we agree that an empty interval does not have a well-defined center,
then the assertion is quite valid.

But the problematic intervals in question were never intended to ever be
empty, yet their left and right bounds are computed in such a way to
form degenerate, "inside-out" intervals that are treated as empty.  The
assertion properly is pointing out this flaw in computation.  As such,
we should not be removing the assertion, because rather we should ensure
that computations never invert the bounds of an interval.

That said, I feel the hard-fail approach of an assertion is too strong,
and what we need is to simply emit a warning that the function will be
returning the midpoint of the interval's bounds despite the interval
appearing to be invalid (read: empty).


-- Aaron Hill

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

Aaron Hill
On 2019-10-30 2:24 am, Aaron Hill wrote:

> On 2019-10-30 2:05 am, Rutger Hofman wrote:
>> Sincere request: can this assert please be removed? Its validity
>> appears
>> debatable, and it is a showstopper for me!
>
> If we agree that an empty interval does not have a well-defined
> center, then the assertion is quite valid.
>
> But the problematic intervals in question were never intended to ever
> be empty, yet their left and right bounds are computed in such a way
> to form degenerate, "inside-out" intervals that are treated as empty.
> The assertion properly is pointing out this flaw in computation.  As
> such, we should not be removing the assertion, because rather we
> should ensure that computations never invert the bounds of an
> interval.
>
> That said, I feel the hard-fail approach of an assertion is too
> strong, and what we need is to simply emit a warning that the function
> will be returning the midpoint of the interval's bounds despite the
> interval appearing to be invalid (read: empty).

I meant to add that such a tactic would not be unprecedented as the
codebase already has cases where LilyPond warns it is "crossing its
fingers".


-- Aaron Hill

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

David Kastrup
In reply to this post by Aaron Hill
Aaron Hill <[hidden email]> writes:

> On 2019-10-30 2:05 am, Rutger Hofman wrote:
>> Sincere request: can this assert please be removed? Its validity
>> appears
>> debatable, and it is a showstopper for me!
>
> If we agree that an empty interval does not have a well-defined
> center, then the assertion is quite valid.
>
> But the problematic intervals in question were never intended to ever
> be empty, yet their left and right bounds are computed in such a way
> to form degenerate, "inside-out" intervals that are treated as empty.
> The assertion properly is pointing out this flaw in computation.  As
> such, we should not be removing the assertion, because rather we
> should ensure that computations never invert the bounds of an
> interval.
>
> That said, I feel the hard-fail approach of an assertion is too
> strong, and what we need is to simply emit a warning that the function
> will be returning the midpoint of the interval's bounds despite the
> interval appearing to be invalid (read: empty).

There are lots of situations where this assertion may trigger and not
all of them may have a sensible fallback.  So one would need to see what
particular case is triggered here.

--
David Kastrup

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

Aaron Hill-2
On 2019-11-01 1:19 pm, David Kastrup wrote:

> Aaron Hill <[hidden email]> writes:
>> That said, I feel the hard-fail approach of an assertion is too
>> strong, and what we need is to simply emit a warning that the function
>> will be returning the midpoint of the interval's bounds despite the
>> interval appearing to be invalid (read: empty).
>
> There are lots of situations where this assertion may trigger and not
> all of them may have a sensible fallback.  So one would need to see
> what
> particular case is triggered here.

I understand the assertion may be guarding against unexpected behavior.  
This is why I would not propose removing the assertion without putting
something back in place such as a warning.  And to reiterate what I said
in my earlier follow-up, my proposal would not be unprecedented given
the existing "crossing fingers" messages that can appear from
time-to-time.

Given that, what makes this particular function so special as to hold it
to a higher standard?  It is not like computing the center of an
inverted interval is perilous in and of itself.  The caller might not
like the result, but that is their fault for asking a silly question in
the first place.

 From my perspective, it seems all of the reported situations that are
actually failing the assertion involve edge cases where allowing the
function to return a value just so execution can proceed would resolve
the "issue" end users are having.  And by "issue", I only mean the
unexpected and undesired program termination.

Yes, there is an underlying computational error that is producing
inverted intervals.  Yes, the end result of continued execution may not
produce what the user expects or needs.  But, hard failing the process
is only a thorn that punishes the end user.  At the very least, this
should be a *debug* assertion--not a run-time error.


-- Aaron

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

David Kastrup
Aaron Hill <[hidden email]> writes:

> On 2019-11-01 1:19 pm, David Kastrup wrote:
>> Aaron Hill <[hidden email]> writes:
>>> That said, I feel the hard-fail approach of an assertion is too
>>> strong, and what we need is to simply emit a warning that the function
>>> will be returning the midpoint of the interval's bounds despite the
>>> interval appearing to be invalid (read: empty).
>>
>> There are lots of situations where this assertion may trigger and not
>> all of them may have a sensible fallback.  So one would need to see
>> what
>> particular case is triggered here.
>
> I understand the assertion may be guarding against unexpected
> behavior.  This is why I would not propose removing the assertion
> without putting something back in place such as a warning.

An assertion is used if the program cannot be guaranteed to continue
without crashing or internal corruption.  A warning is not the same.

> And to reiterate what I said in my earlier follow-up, my proposal
> would not be unprecedented given the existing "crossing fingers"
> messages that can appear from time-to-time.

"Crossing fingers" messages are appropriate when there is a useful
fallback behavior.

> Given that, what makes this particular function so special as to hold
> it to a higher standard?  It is not like computing the center of an
> inverted interval is perilous in and of itself.  The caller might not
> like the result, but that is their fault for asking a silly question
> in the first place.

The caller may rely on well-defined behavior.

> Yes, there is an underlying computational error that is producing
> inverted intervals.  Yes, the end result of continued execution may
> not produce what the user expects or needs.  But, hard failing the
> process is only a thorn that punishes the end user.  At the very
> least, this should be a *debug* assertion--not a run-time error.

A caller should not call this function if its input can be an empty
interval.  This is clearly a programming error without a sensible
default fallback behavior: any fallbacks need to be implemented by the
caller.

--
David Kastrup

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond
Reply | Threaded
Open this post in threaded view
|

Re: Assertion !is_empty() failed - yet again

Rutger Hofman
How can I help diagnose, so the code can make a better distinction
between false and true assertion circumstances? Is a gdb backtrace from
a core dump helpful? (Although I must think deeply which of my scores
triggered this assert, and then build a lilypond with that assert enabled.)

Rutger

On 11/4/19 1:11 AM, David Kastrup wrote:

> Aaron Hill <[hidden email]> writes:
>
>> On 2019-11-01 1:19 pm, David Kastrup wrote:
>>> Aaron Hill <[hidden email]> writes:
>>>> That said, I feel the hard-fail approach of an assertion is too
>>>> strong, and what we need is to simply emit a warning that the function
>>>> will be returning the midpoint of the interval's bounds despite the
>>>> interval appearing to be invalid (read: empty).
>>>
>>> There are lots of situations where this assertion may trigger and not
>>> all of them may have a sensible fallback.  So one would need to see
>>> what
>>> particular case is triggered here.
>>
>> I understand the assertion may be guarding against unexpected
>> behavior.  This is why I would not propose removing the assertion
>> without putting something back in place such as a warning.
>
> An assertion is used if the program cannot be guaranteed to continue
> without crashing or internal corruption.  A warning is not the same.
>
>> And to reiterate what I said in my earlier follow-up, my proposal
>> would not be unprecedented given the existing "crossing fingers"
>> messages that can appear from time-to-time.
>
> "Crossing fingers" messages are appropriate when there is a useful
> fallback behavior.
>
>> Given that, what makes this particular function so special as to hold
>> it to a higher standard?  It is not like computing the center of an
>> inverted interval is perilous in and of itself.  The caller might not
>> like the result, but that is their fault for asking a silly question
>> in the first place.
>
> The caller may rely on well-defined behavior.
>
>> Yes, there is an underlying computational error that is producing
>> inverted intervals.  Yes, the end result of continued execution may
>> not produce what the user expects or needs.  But, hard failing the
>> process is only a thorn that punishes the end user.  At the very
>> least, this should be a *debug* assertion--not a run-time error.
>
> A caller should not call this function if its input can be an empty
> interval.  This is clearly a programming error without a sensible
> default fallback behavior: any fallbacks need to be implemented by the
> caller.
>

_______________________________________________
bug-lilypond mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/bug-lilypond