Bug 67579 - assertion failure on "print option": too much trust in printer settings/data saved in the .odt file
Summary: assertion failure on "print option": too much trust in printer settings/data ...
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Printing and PDF export (show other bugs)
(earliest affected) Master
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Not Assigned
Depends on:
Blocks: Print-Dialog Crash-Assert
  Show dependency treegraph
Reported: 2013-07-31 12:52 UTC by Lionel Elie Mamane
Modified: 2018-03-02 10:06 UTC (History)
3 users (show)

See Also:
Crash report or crash signature:

gdb backtrace (100.93 KB, text/plain)
2013-07-31 12:52 UTC, Lionel Elie Mamane

Note You need to log in before you can comment on or make changes to this bug.
Description Lionel Elie Mamane 2013-07-31 12:52:21 UTC
Created attachment 83360 [details]
gdb backtrace

@caolan: this is your assert. An opinion? Something I should try?

1) Using a *dbgutil* build of master
2) Open writer document
3) Open print dialog
4) click on "options"

Result: assertion failure


 soffice.bin: /home/master/src/libreoffice/workdirs/libreoffice-4.2/padmin/source/prtsetup.cxx:364: padmin::RTSDevicePage::RTSDevicePage(padmin::RTSDialog*): Assertion `nLevelEntryData != 0 || bAutoIsPDF == m_pParent->m_aJobData.m_nPDFDevice' failed.

Backtrace attached. The interesting frame is frame 9 or 55? The stack is a bit weird; the abort signal handler seems to indirectly call the same code again...

Here's the code around that:

    sal_uLong nLevelEntryData = 0; //automatic
    if( m_pParent->m_aJobData.m_nPDFDevice == 2 ) //explicitly PDF
        nLevelEntryData = 10;
    else if (m_pParent->m_aJobData.m_nPSLevel > 0) //explicit PS Level
        nLevelEntryData = m_pParent->m_aJobData.m_nPSLevel+1;
    else if (m_pParent->m_aJobData.m_nPDFDevice == 1) //automatically PDF
        nLevelEntryData = 0;
    else if (m_pParent->m_aJobData.m_nPDFDevice == -1) //explicitly PS from driver
        nLevelEntryData = 1;

    bool bAutoIsPDF = officecfg::Office::Common::Print::Option::Printer::PDFAsStandardPrintJobFormat::get();

    assert(nLevelEntryData != 0 || bAutoIsPDF == m_pParent->m_aJobData.m_nPDFDevice);


(gdb) print nLevelEntryData
$1 = 0
(gdb) print bAutoIsPDF
$2 = true
(gdb) print m_pParent->m_aJobData.m_nPDFDevice
$3 = 0
(gdb) print m_pParent->m_aJobData.m_nPSLevel
$4 = 0
Comment 1 Lionel Elie Mamane 2013-07-31 16:08:55 UTC
So, using gdb I skipped that assert *once* and then ran again in gdb.

Now that assert succeeds because m_Parent->m_aJobData.m_nPDFDevice==1.

However, when I dismiss the properties page (click "OK"), I ultimately get into this code:


        if( m_pDevicePage )
            m_aJobData.m_nColorDepth    = m_pDevicePage->getDepth();
            m_aJobData.m_nColorDevice   = m_pDevicePage->getColorDevice();
            m_aJobData.m_nPSLevel       = m_pDevicePage->getLevel();
            m_aJobData.m_nPDFDevice     = m_pDevicePage->getPDFDevice();

This sets m_aJobData.m_nPDFDevice to 0, but well after the assert. So in a nutshell, I cannot reproduce anymore.

Let's look at the .odt file... settings.xml contains:

        <config:config-item-set config:name="ooo:configuration-settings">
            <config:config-item config:name="PrinterSetup" config:type="base64Binary">

And (decoded), this contains:


Aha. So let's try to restart the LibreOffice process on the same file...

More analysis / notes:

m_pParent->m_aJobData seems to be essentially constructed in PspSalInfoPrinter::Setup (file vcl/generic/print/genprnpsp.cxx).

In this case, since pJobSetup->mpDriverData is not NULL, we go into SetData( ~0, pJobSetup ), which calls JobData::constructFromStreamBuffer.

JobData::constructFromStreamBuffer *does* set m_nPDFDevice to 1.

SetData then goes on to create a new StreamBuffer from the information, and returns to PspSalInfoPrinter::Setup, which calls ... JobData::constructFromStreamBuffer again on the StreamBuffer with same contents as the one that SetData worked on, which thus *also* sets m_nPDFDevice to 1.

So we enter Sal_SetupPrinterDriver (file padmin/source/prtsetup.cxx) with a rJobData that has m_nPDFDevice==1, which creates a padmin::RTSDialog passing it the same rJobData; that class copies it into its m_aJobData.
Comment 2 Lionel Elie Mamane 2013-07-31 16:14:37 UTC
Yup, if I restart LibreOffice, I get the assertion failure again. So it seems that LibreOffice trusts settings.xml "too much".
Comment 3 Lionel Elie Mamane 2013-07-31 16:28:45 UTC
In a run where the assert happens:

In PspSalInfoPrinter::Setup, before the call to SetData:

gdb) print (char*)pJobSetup->mpDriverData
$95 = 
    0x299e9b0 "JobData 1\nprinter=C353\norientation=Portrait\ncopies=1\nmargindajustment=0,0,0,0\ncolordepth=24\npslevel=0\npdfdevice=0\ncolordevice=0\nPPDContexData\nInputSlot:Tray1"

So, the pdfdevice=0 from settings.xml somehow gets there. Not sure why / how; that setting seems like it is printer-dependent to me. Why would it be trusted from an .odt (and why it is saved there in the first place), I'm not completely sure, since the printer environment may have changed since the file was saved. It may even be a different printer.

From there, it trickles down to RTSDialog's m_aJobData and triggers the assert.
Comment 4 Lionel Elie Mamane 2013-07-31 16:54:19 UTC
When creating a new file, I cannot reproduce the "pdfdevice=0" setting being included. It must have been inherited from a save with an older version of LibreOffice.

Manually emptying PrinterSetup in settings.xml fixes the crash.

The assert-failure-inducing "pdfdevice=0" survives:

 - file / save as
 - 'print directly' from toolbar then file / save
 - 'print' (dialog) / OK, then file / save

It does not survive:

 - print (dialog), select other printer, select default printer again,
   OK (it prints), then file / save
Comment 5 Lionel Elie Mamane 2013-07-31 17:08:37 UTC
Hmmm... This seems extremely related to the situation / scenario described in bug 58080. My guess:

In bug 58080, the "Generic Printer" business pollutes the "pdfdevice" setting (in memory) and puts 0 there. Then I save the file (in bug 58080, the assert fails only the second time the print dialog is opened).

After printing the file *once* in the "Generic Printer" situation, I saved the file, which saved the bad "pdfdevice=0" in the file, leading to this bug.
Comment 6 QA Administrators 2015-04-01 14:42:03 UTC Comment hidden (obsolete)
Comment 7 tommy27 2016-04-16 07:24:51 UTC Comment hidden (obsolete)
Comment 8 QA Administrators 2017-05-22 13:26:02 UTC Comment hidden (obsolete)
Comment 9 Xisco Faulí 2017-07-25 20:47:12 UTC
Hi Lionel,
Could you please check if it's still asserting ?
Comment 10 QA Administrators 2018-01-29 10:27:46 UTC Comment hidden (obsolete)
Comment 11 QA Administrators 2018-03-02 10:06:02 UTC
Dear Bug Submitter,

Please read this message in its entirety before proceeding.

Your bug report is being closed as INSUFFICIENTDATA due to inactivity and
a lack of information which is needed in order to accurately
reproduce and confirm the problem. We encourage you to retest
your bug against the latest release. If the issue is still
present in the latest stable release, we need the following
information (please ignore any that you've already provided):

a) Provide details of your system including your operating
   system and the latest version of LibreOffice that you have
   confirmed the bug to be present

b) Provide easy to reproduce steps – the simpler the better

c) Provide any test case(s) which will help us confirm the problem

d) Provide screenshots of the problem if you think it might help

e) Read all comments and provide any requested information

Once all of this is done, please set the bug back to UNCONFIRMED
and we will attempt to reproduce the issue. Please do not:

a) respond via email 

b) update the version field in the bug or any of the other details
   on the top section of our bug tracker

Warm Regards,
QA Team