Bug 31324 - -var-create: slowdown due to children printing
Summary: -var-create: slowdown due to children printing
Status: UNCONFIRMED
Alias: None
Product: gdb
Classification: Unclassified
Component: mi (show other bugs)
Version: 14.1
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-02-01 12:17 UTC by Dmitry Neverov
Modified: 2024-02-02 09:07 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
slow array pretty-printing reproducible (912 bytes, application/x-gzip)
2024-02-02 09:07 UTC, Dmitry Neverov
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Neverov 2024-02-01 12:17:56 UTC
Fix for https://sourceware.org/bugzilla/show_bug.cgi?id=11335
changed the logic of -var-create. Before, if a var had children,
-var-create returned "{...}" as a value. Now, it appends the
pretty printer's to_string result to the printed children.

It looks like there is no way to disable this behavior.

New logic has performance implications. For example, running

  -var-create v1 * "ss"

in the following program:

typedef struct {
  int x, y;
} SlowStruct;

int main() {
  SlowStruct ss[100] = {0};
  return 0; //break
}

will be slow if SlowStruct has a slow pretty-printer:

import gdb
import gdb.printing
import time

class SlowStructPrinter:
    def __init__(self, val):
        self.val = val

    def to_string(self):
        time.sleep(1)
        return ("slow struct")

def slowStructPrinterMatcher(val):
    if "SlowStruct" in str(val.type):
        return SlowStructPrinter(val)

gdb.pretty_printers.append(slowStructPrinterMatcher)

This was fast in 13.2, because children were not printed.
Comment 1 Dmitry Neverov 2024-02-01 12:51:31 UTC
To reproduce, one needs to register a pretty-printer for arrays:

class ArrayPrinter(object):
    def __init__(self, val, type):
        self.val = val
        self.type = type

    def display_hint(self):
        return 'array'

    def to_string(self):
        return None

    def children(self):
        return self.Iterator(self.val, self.type)

    class Iterator:
        def __init__(self, val, type):
            self.val = val
            try:
                (start_index, end_index) = type.range()
                self.index = start_index - 1
                self.end_index = end_index + 1
            except:
                self.index = -1
                self.end_index = untypedef(type).sizeof // untypedef(type).target().sizeof

        def __iter__(self):
            return self

        def __next__(self):
            self.index += 1
            if self.index == self.end_index:
                raise StopIteration
            return ('[{0}]'.format(self.index), self.val[self.index])

        def next(self):
            return self.__next__()

def arrayMatcher(val):
    if val.type.code == gdb.TYPE_CODE_ARRAY:
        return ArrayPrinter(val, type)
    return None

gdb.pretty_printers.append(arrayMatcher)
Comment 2 Tom Tromey 2024-02-01 16:20:40 UTC
(In reply to Dmitry Neverov from comment #1)
> To reproduce, one needs to register a pretty-printer for arrays:

>     def to_string(self):
>         return None

I wouldn't expect this to be slow.

Anyway, an MI feature to support this would be ok, I guess.
Normally it's better to just fix the pretty-printer though,
since if that is slow it's going to impact interactive
use as well.
Comment 3 Dmitry Neverov 2024-02-02 09:07:29 UTC
Created attachment 15348 [details]
slow array pretty-printing reproducible

> I wouldn't expect this to be slow.

It is slow because children's pretty-printing result is included into
the parent value. The attached script is instant with gdb 13.2, but
takes several seconds in gdb 14.1.

> Normally it's better to just fix the pretty-printer though,
> since if that is slow it's going to impact interactive
> use as well.

The pretty-printer can be slow due to slow symbol lookup
(e.g. https://sourceware.org/bugzilla/show_bug.cgi?id=30520). It is
not clear how to fix it.

In an interactive front-end with gdb 13.2 there was a slow-down only
when array is expanded, so users could avoid it if they didn't want to
inspect array elements.