https://bugs.documentfoundation.org/show_bug.cgi?id=173163

            Bug ID: 173163
           Summary: LibreOffice infinite layout loop on DOCX with
                    footnotes
           Product: LibreOffice
           Version: 26.2.0.3 release
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Severity: normal
          Priority: medium
         Component: LibreOffice
          Assignee: [email protected]
          Reporter: [email protected]

Description:
Converting a .docx with footnotes to PDF with LibreOffice 26.2.1.2 never
terminates. The process pins at ~99% CPU indefinitely and produces no output.
The same document converts successfully in 25.8.7.3.

This is not a deadlock — it is an unbounded loop in the Writer layout engine.
The process remains responsive to signals but never converges, so it has to be
killed externally.

This affects headless server-side conversion in particular, where there is no
user to cancel the operation: a single such document occupies a worker at 100%
CPU until an external timeout kills it.

Steps to Reproduce:
1.Take a .docx containing footnotes, some of which are anchored inside table
rows
(characteristics of the failing document are given below).

2.Run:
soffice --headless --invisible --norestore \
        --convert-to pdf --outdir /tmp /path/to/document.docx

Actual Results:
The command never returns. soffice.bin sits at ~99% CPU indefinitely. No PDF is
written. Killed manually after 90 seconds; also confirmed to still be spinning
at 180 seconds.

Expected Results:
The document converts to PDF and the process exits, as it does in 25.8.7.3 (34
seconds on the same document, 2.4 MB PDF produced).


Reproducible: Always


User Profile Reset: No

Additional Info:
Sampling the spinning process (sample <pid> 5) gives a call graph that is
dominated by a single cycle in the layout engine. Abridged, with sample counts,
out of 4093 samples over 5 seconds — i.e. essentially 100% of run time:

4093  SwEditShell::CalcLayout()
4093   SwViewShell::CalcLayout()
4093    SwLayAction::FormatContent(SwPageFrame*)
4093     SwFrame::OptPrepareMake()
4093      SwFrame::PrepareMake(OutputDevice*)
2208       SwTabFrame::MakeAll(OutputDevice*)
2157        lcl_RecalcRow(SwRowFrame&, long)
2104         SwContentFrame::CalcLowers(SwLayoutFrame&, SwLayoutFrame const&,
long, bool)
2104          SwFrame::PrepareMake(OutputDevice*)
2026           SwContentFrame::MakeAll(OutputDevice*)
1560            SwTextFrame::Format(OutputDevice*, SwBorderAttrs const*)
1466             SwTextFrame::FormatImpl(...)
1421              SwTextFrame::Format_(SwTextFormatter&, SwTextFormatInfo&,
bool)
1417               SwTextFrame::FormatLine(SwTextFormatter&, bool)
 608                SwTextFormatter::NewFootnotePortion(SwTextFormatInfo&,
SwTextAttr*)
 541                 SwTextFrame::ConnectFootnote(SwTextFootnote*, long)
 527                  SwFootnoteBossFrame::AppendFootnote(SwContentFrame*,
SwTextFootnote*)
 488                   SwFrame::PrepareMake(OutputDevice*)
 438                    SwContentFrame::MakeAll(OutputDevice*)
 428                     SwTextFrame::Format(OutputDevice*, SwBorderAttrs
const*)
 406                      SwTextFrame::FormatImpl(...)
 237                       SwTextFrame::Format_(SwTextFormatter&,
SwTextFormatInfo&, bool)
 209                        SwTextFrame::FormatAdjust(SwTextFormatter&,
WidowsAndOrphans&, ...)
 151                         SwTextFrame::AdjustFollow_(SwTextFormatter&, ...)
 149                          SwTextFrame::CalcFollow(...)
 149                           SwFrame::PrepareMake(OutputDevice*)
 100                            SwContentFrame::MakeAll(OutputDevice*)   <--
recurses
The cycle appears to be: formatting a row's content reaches a footnote anchor →
ConnectFootnote → AppendFootnote → which formats the footnote frame → which
invalidates the row → lcl_RecalcRow reformats the row content → reaches the
same footnote anchor again. It never reaches a fixed point.

A visible sub-cost inside the loop is lcl_GetPageNumber →
SwFrame::GetVirtPageNum() → lcl_FindStartOfVirtualPages(), which walks the page
chain on each iteration. That is presumably a symptom rather than the cause,
but it may be why this particular document degrades so sharply rather than
merely being slow.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to