Bug 156256 - Inspecting an object in the Watch panel freezes / crashes
Summary: Inspecting an object in the Watch panel freezes / crashes
Status: NEW
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: BASIC (show other bugs)
Version:
(earliest affected)
Inherited From OOo
Hardware: All All
: medium normal
Assignee: Not Assigned
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: BASIC-IDE
  Show dependency treegraph
 
Reported: 2023-07-12 14:34 UTC by Albrecht Müller
Modified: 2023-09-24 13:14 UTC (History)
4 users (show)

See Also:
Crash report or crash signature:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Albrecht Müller 2023-07-12 14:34:49 UTC
Observed with:
Version: 7.0.4.2 (x64)
Build ID: dcf040e67528d9187c66b2379df5ea4407429775
CPU threads: 4; OS: Windows 6.1 Service Pack 1 Build 7601; UI render: Skia/Raster; VCL: win
Locale: de-DE (de_DE); UI: de-DE
Calc: threaded


The problem I am going to describe requires me to power off the computer during heavy disk activities. So far Windows seems to have successfully repaired the resulting file system corruption. Thus the damage was limited. But I fear that I am not always that lucky. Therefore I do not want to do additional experiments and hope that someone has a computing environment that allows to investigate this problem safely.

I run into this problem when I tried to write a macro that searches through a complete spreadsheet document. If you want to search a text document you can use the fact that a text document implements the XSearchable interface. Spreadsheet documents don’t implement this interface. (See
https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1text_1_1GenericTextDocument.html ,
https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1sheet_1_1SpreadsheetDocument.html 
https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1sheet_1_1SheetCellRanges.html 
and 
https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1util_1_1XSearchable.html ).

Therefore I needed a workaround. An obvious one is to create a SheetCellRanges object that contains all spreadsheets of the document. I used something like the following lines of code to create this object:

document = ThisComponent
rangeToSearch = document.createInstance("com.sun.star.sheet.SheetCellRanges")
With document.Sheets 
   For I = 0 To .Count - 1
      rangeToSearch.insertByName("", .getByIndex(I))
   Next I
End With

The code seemed to work. rangeToSearch.AbsoluteName contained something that looked reasonable.

The problem started when I tried to inspect the object in the Watch Window of the Basic IDE. Nothing bad happened when I placed the variable rangeToSearch into the Watch Window. Problems started when I tried to click on the plus sign left of the variable. This should expand the content tree and display the attributes.

This never happened. Instead the machine started heavy disk activities and became irresponsive. As I was not able to bring up the task manager using Ctrl+Alt+Del I had to power off the machine to make it usable again.

I observed a similar effect when I tried to inspect the variable using MRI.

One time I had a resource monitor window open when this happened. In the resource monitor I could see that memory usage increased quickly before all physical memory was exhausted and the machine froze.

Thus my current hypothesis is that the inspection of this variable tries to create data arrays that contain an entry for each cell in the document. As a spreadsheet has 2^10 columns and 2^20 rows there are 2^30 cells per spreadsheet. Assuming 8 bytes per entry for a double value this is about 80 GiB per spreadsheet. This is a lot more than the available physical memory, and a couple of spreadsheets may fill a complete hard disk. The operation system has to swap physical memory to disk. Due to the amount of memory this operation may take quite some time and may lead to other errors, maybe disk full. As swapping memory is a very basic operation probably the only way to stop it is to power off the machine.

Expected behavior:
a) Spreadsheet documents should implement the XSearchable interface. This would avoid the need for this workaround in the first place.

b) Inspecting a variable in the Basic IDE should be a safe operation. Maybe this would require LibreOffice to enforce some limits on memory usage. This would be useful in other situations too, e.g. when a memory leak lets LibreOffice consume all available physical memory. Maybe LibreOffice could use some kind of lazy evaluation of sparse objects to avoid excessive but unnecessary memory usage.
Comment 1 Stéphane Guillou (stragu) 2023-07-28 16:48:06 UTC
Thank you for the report.
Could you please test a currently-supported version of LibreOffice?
Please test version 7.5 and let us know if you see the same issue: https://www.libreoffice.org/download/download-libreoffice/
Comment 2 Albrecht Müller 2023-07-29 16:21:07 UTC
Maybe you agree with me that switching off a machine during heavy disk operations is not a good idea. Unfortunately I have no spare machine that I can risk to ruin by doing further experiments. Thus I do my best trying to avoid repeating the situation I described. Hopefully there is someone else who can try your proposal in a more safe environment.
Comment 3 Buovjaga 2023-09-07 15:44:40 UTC
(In reply to Albrecht Müller from comment #0)
> The problem started when I tried to inspect the object in the Watch Window
> of the Basic IDE. Nothing bad happened when I placed the variable
> rangeToSearch into the Watch Window. Problems started when I tried to click
> on the plus sign left of the variable. This should expand the content tree
> and display the attributes.

I added rangeToSearch into the Watch area. Can you say what I need to do in order to see the plus sign?
Comment 4 Albrecht Müller 2023-09-07 16:26:30 UTC
(In reply to Buovjaga from comment #3)
> 
> I added rangeToSearch into the Watch area. Can you say what I need to do in
> order to see the plus sign?

The plus sign should appear at the left side of any variable that is not a scalar value. I don't know if another symbol is used in other environments.

As there is no plus sign I suspect that the variable has an empty value because you did not run the code fragment that creates the value of this variable. Is that correct?

Be careful: Can you risk to damage your machine? This may happen if you succeed to reproduce my problem.
Comment 5 Buovjaga 2023-09-07 17:30:05 UTC
(In reply to Albrecht Müller from comment #4)
> (In reply to Buovjaga from comment #3)
> > 
> > I added rangeToSearch into the Watch area. Can you say what I need to do in
> > order to see the plus sign?
> 
> The plus sign should appear at the left side of any variable that is not a
> scalar value. I don't know if another symbol is used in other environments.
> 
> As there is no plus sign I suspect that the variable has an empty value
> because you did not run the code fragment that creates the value of this
> variable. Is that correct?

I did run the code, but I did not have any data in the document.

> Be careful: Can you risk to damage your machine? This may happen if you
> succeed to reproduce my problem.

I was running in a virtual machine, which I imagine would allow me to forcefully stop the machine rather than my physical one.
Comment 6 Albrecht Müller 2023-09-08 10:16:20 UTC
(In reply to Buovjaga from comment #5)
> 
> I did run the code, but I did not have any data in the document.
> 
What value and type did the watch window show for the rangeToSearch variable?

As I did not try the code with an empty document I cannot say how it behaves in this case. I don't remember the exact document I used but I guess it was more than 100 kB in size and probably contained about 20 tables, text, formatting and calculations that referred to values in other tables.
Comment 7 Buovjaga 2023-09-08 12:09:58 UTC
(In reply to Albrecht Müller from comment #6)
> (In reply to Buovjaga from comment #5)
> > 
> > I did run the code, but I did not have any data in the document.
> > 
> What value and type did the watch window show for the rangeToSearch variable?
> 
> As I did not try the code with an empty document I cannot say how it behaves
> in this case. I don't remember the exact document I used but I guess it was
> more than 100 kB in size and probably contained about 20 tables, text,
> formatting and calculations that referred to values in other tables.

Value and type remain empty.

I also tried inputting some dummy data.
Comment 8 Stéphane Guillou (stragu) 2023-09-08 12:55:33 UTC
I could reproduce the freeze with:

1. create new ODS, add a second sheet
2. create Basic macro stored in this file:

Sub Main
document = ThisComponent
rangeToSearch = document.createInstance("com.sun.star.sheet.SheetCellRanges")
With document.Sheets 
   For I = 0 To .Count - 1
      rangeToSearch.insertByName("", .getByIndex(I))
   Next I
End With
Print rangeToSearch
End Sub

3. add breakpoint at Print line
4. add rangeToSearch to the Watch panel
5. run macro (it stops at breakpoint)
6. click expand button next to rangeToSearch in the Watch panel

Result: freeze at 100% of one core, or crash in more recent versions.
Does not freeze if there is one single empty sheet.

Reproduced in:

OOo 3.3

Version: 7.6.1.1 (X86_64) / LibreOffice Community
Build ID: c7cda394c5de06de37d8109c310df89a4d4c3a98
CPU threads: 8; OS: Linux 5.15; UI render: default; VCL: gtk3
Locale: en-AU (en_AU.UTF-8); UI: en-US
Calc: threaded

Version: 24.2.0.0.alpha0+ (X86_64) / LibreOffice Community
Build ID: beaea2e992912b4747d790070b26371f557b1f57
CPU threads: 8; OS: Linux 5.15; UI render: default; VCL: gtk3
Locale: en-AU (en_AU.UTF-8); UI: en-US
Calc: threaded

Sounds similar to bug 156091.
Comment 9 Rafael Lima 2023-09-08 17:42:47 UTC
It is getting stuck in basctl/source/basicide/baside2b.cxx in method WatchWindow::ImplGetSBXForEntry.

More specifically, when it is searching for the "Data" property, it gets stuck in:

pVar->Get( aRes );

And never comes out of this Get call.

I still haven't figured out why =/
Comment 10 Albrecht Müller 2023-09-10 15:26:43 UTC
(In reply to Rafael Lima from comment #9)
> It is getting stuck in basctl/source/basicide/baside2b.cxx in method
> WatchWindow::ImplGetSBXForEntry.
> 
> More specifically, when it is searching for the "Data" property, it gets
> stuck in:
> 
> pVar->Get( aRes );
> 
> And never comes out of this Get call.
> 
> I still haven't figured out why =/

Your observation may point to a severe issue in the design of the Watch panel. I suspect this for the following reasons:

a) The “pVar->Get( aRes )” call probably creates contents of the tree that will be displayed in the Watch panel.

and 

b) The code of the Watch panel expects that this call will never fail.

The problem is that “pVar->Get( aRes )” will have to execute code in the aRes object, e.g. getter functions. As aRes may be a buggy object of unknown origin you cannot assume that it behaves correctly. A getter function may run into an endless loop, wait for an event that never happens, allocate excessive amounts of memory etc. This way a single broken and otherwise unused method of the aRes object may cause a machine freeze.

Thus there may be two separate issues:

- The Watch panel should provide some safeguard against misbehaving objects, e.g. execute the “pVar->Get( aRes )” statement in some kind of sandbox and provide some user interface that allows to deal with situations where the object to inspect does not work properly.

- The com.sun.star.sheet.SheetCellRanges object created by the Basic code may have some unexpected features that make it impossible for the Get call to return. My guess is that it somehow creates one or several data arrays that contain an entry for each possible cell in the document.
Comment 11 Albrecht Müller 2023-09-24 13:14:46 UTC
(In reply to Rafael Lima from comment #9)
> It is getting stuck in basctl/source/basicide/baside2b.cxx in method
> WatchWindow::ImplGetSBXForEntry.
> 
> More specifically, when it is searching for the "Data" property, it gets
> stuck in:
> 
> pVar->Get( aRes );
> 
> And never comes out of this Get call.
> 
> I still haven't figured out why =/

I changed the program given in comment 8 a little bit:


Sub Main
Const NumberOfRows = 23 ' 1 ... 1048576
Const NumberOfColumns = 5 ' 1 ... 1024
document = ThisComponent
rangeToSearch = document.createInstance("com.sun.star.sheet.SheetCellRanges")
With document.Sheets 
   For I = 0 To .Count - 1
      rangeToSearch.insertByName("", .getByIndex(I).getCellRangeByPosition(0,0,NumberOfColumns-1,NumberOfRows-1))
   Next I
End With
Print rangeToSearch
End Sub



The change essentially is that the program does not add complete sheets but only parts of them. If you use the maximum values for NumberOfRows and NumberOfColums, this program should be equivalent to the original for our purposes. I could inspect the rangeToSearch object without problems. But I did not dare to increase the values for NumberOfRows and NumberOfColums to critical values.

The content of the Data property suggests that it does not come out of the Get call because this call tries to allocate memory for 1048576 * 1024 * document.Sheets.Count (i.e. roughly a billion for each sheet) double values and to initialize this memory with NotANumber values (2,2250738585072E-308). At best this may take a while ...