Skip to content

Commit

Permalink
Merge branch 'topic/vadim/gdbpp' into 'master'
Browse files Browse the repository at this point in the history
Update GDB pretty-printer

Closes #247

See merge request eng/ide/VSS!330
  • Loading branch information
godunko committed Jul 3, 2024
2 parents 988f93c + c88d96b commit 6b808d5
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 40 deletions.
1 change: 1 addition & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ build_and_test_dev:
stage: build_and_test
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
when: manual
- if: $CI_COMMIT_BRANCH == 'master' && $CI_COMMIT_TITLE =~ /Merge branch.*/
- if: $CI_COMMIT_BRANCH == 'edge' && $CI_COMMIT_TITLE =~ /Merge branch.*/
script:
Expand Down
89 changes: 51 additions & 38 deletions gdb/vss_pp.py
Original file line number Diff line number Diff line change
@@ -1,74 +1,87 @@
from gnatdbg.tagged import reinterpret_tagged

def decode_utf8(val):
result = ''

def decode_utf8(bytes, size):
result = ""
i = 0

while i < val["size"]:
if val["storage"][i] <= 0x7F:
c = val["storage"][i]
while i < size:
if bytes[i] <= 0x7F:
c = bytes[i]
i = i + 1

elif val["storage"][i] <= 0xDF:
u1 = (val["storage"][i] & 0x1F) << 6
u2 = val["storage"][i + 1] & 0x3F
elif bytes[i] <= 0xDF:
u1 = (bytes[i] & 0x1F) << 6
u2 = bytes[i + 1] & 0x3F
c = u1 | u2
i = i + 2

elif val["storage"][i] <= 0xEF:
u1 = (val["storage"][i] & 0x1F) << 12
u2 = (val["storage"][i + 1] & 0x3F) << 6
u3 = val["storage"][i + 2] & 0x3F
elif bytes[i] <= 0xEF:
u1 = (bytes[i] & 0x1F) << 12
u2 = (bytes[i + 1] & 0x3F) << 6
u3 = bytes[i + 2] & 0x3F
c = u1 | u2 | u3
i = i + 3

elif val["storage"][i] <= 0xF4:
u1 = (val["storage"][i] & 0x1F) << 18
u2 = (val["storage"][i + 1] & 0x3F) << 12
u3 = (val["storage"][i + 2] & 0x3F) << 6
u4 = val["storage"][i + 3] & 0x3F
elif bytes[i] <= 0xF4:
u1 = (bytes[i] & 0x1F) << 18
u2 = (bytes[i + 1] & 0x3F) << 12
u3 = (bytes[i + 2] & 0x3F) << 6
u4 = bytes[i + 3] & 0x3F
c = u1 | u2 | u3 | u4
i = i + 4

result += chr(c)

return result

def utf8_pp(val):
data_type = gdb.lookup_type("vss.implementation.utf8_string_handlers.utf8_string_data").pointer()
data = val.cast(data_type).dereference()

return decode_utf8(data)

def utf8ip_pp(val):
data_type = gdb.lookup_type("vss.implementation.utf8_string_handlers.utf8_in_place_data")
data = val.cast(data_type)

return decode_utf8(data)

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

def to_string(self):
data = self.val["data"]
text_type = gdb.lookup_type(
"vss.implementation.text_handlers.abstract_text_handler"
)
utf8static_type = gdb.lookup_type(
"vss.implementation.text_handlers.utf8.static.static_utf8_handler"
)
utf8dynamic_type = gdb.lookup_type(
"vss.implementation.text_handlers.utf8.dynamic.dynamic_utf8_handler"
)

storage = self.val["data"]["storage"]

if all(byte == 0 for byte in storage.bytes):
# "null" string

if data["in_place"]:
return utf8ip_pp(data["storage"])
return None

text = reinterpret_tagged(storage.cast(text_type))

if text.type == utf8static_type:
# GDB is unable to resolve "storage" component of the record,
# so skip first implicit component of 8 bytes and decode.
return decode_utf8(text.bytes[8:], text["size"])

elif text.type == utf8dynamic_type:
data = text["pointer"].dereference()
return decode_utf8(data["storage"].bytes, data["size"])

else:
if data["handler"] == 0:
return None
print("<UNKNOWN TYPE>")

else:
if data["handler"] == gdb.parse_and_eval("vss.implementation.utf8_string_handlers.global_utf8_string_handler'address"):
return utf8_pp(data["pointer"])
return None


# def display_hint(self):
# return 'string'
# return "string"


def vss_pp_func(val):
if str(val.type) == 'vss.strings.virtual_string':
if str(val.type) == "vss.strings.virtual_string":
return Virtual_String_Printer(val)


gdb.pretty_printers.append(vss_pp_func)
31 changes: 31 additions & 0 deletions testsuite/gdbpp/gdbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
set logging redirect on
set logging file /dev/null
set logging enabled on
# Redirecting of the output to file and enable logging send all GDB's output
# into the file. Logging is disabled a bit later when output of the
# 'output'/'echo' commands need to be output to the standard output to check
# with expected results.

source vss_pp.py

start
set charset UTF-8
next
next
next
next
next

set logging enabled off
output ss1
echo \n
output us1
echo \n
output vsn
echo \n
output vs1
echo \n
output vs2
echo \n
output vi1
echo \n
16 changes: 16 additions & 0 deletions testsuite/gdbpp/main.adb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
with Ada.Strings.Unbounded;
with VSS.Strings;

procedure Main is

SS1 : String := "standard string";
US1 : Ada.Strings.Unbounded.Unbounded_String := Ada.Strings.Unbounded.To_Unbounded_String ("unbounded string");

VSN : VSS.Strings.Virtual_String;
VS1 : VSS.Strings.Virtual_String := "short text";
VS2 : VSS.Strings.Virtual_String := "very long text that should not be stored in-place";
VI1 : VSS.Strings.Virtual_String := "Привет! Это тоже длинная строка";

begin
null;
end Main;
10 changes: 10 additions & 0 deletions testsuite/gdbpp/test.gpr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
with "vss_text.gpr";

project Test is
for Object_Dir use ".objs";
for Main use ("main.adb");

package Compiler is
for Switches ("Ada") use ("-g", "-gnatW8");
end Compiler;
end Test;
6 changes: 6 additions & 0 deletions testsuite/gdbpp/test.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"standard string"
"unbounded string"

short text
very long text that should not be stored in-place
Привет! Это тоже длинная строка
2 changes: 2 additions & 0 deletions testsuite/gdbpp/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
gprbuild -q -P test.gpr
gdb --batch --command=gdbinit --directory=$VSS_GDBPP .objs/main
1 change: 1 addition & 0 deletions testsuite/gdbpp/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
driver: gdbpp
23 changes: 21 additions & 2 deletions testsuite/testsuite.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/usr/bin/env python

from os.path import abspath, dirname
from os import environ
from os.path import abspath, dirname, join
import sys

from e3.testsuite import Testsuite
from e3.testsuite.driver.classic import ClassicTestDriver
from e3.testsuite.driver.diff import DiffTestDriver


class VSSLegacyDriver(ClassicTestDriver):
Expand All @@ -16,10 +18,27 @@ def run(self):
self.shell(args=["make", "check"], cwd=root_dir, analyze_output=True)


class VSSGDBPPDriver(DiffTestDriver):
"""Driver to run tests of the GDB pretty printer."""

def set_up(self):
super().set_up()

self.test_environment = environ
self.test_environment["VSS_GDBPP"] = join(
dirname(dirname(self.test_env["test_dir"])), "gdb"
)

def run(self):
script_path = join(self.test_env["test_dir"], "test.sh")

self.shell(args=["bash", script_path], env=self.test_environment)


class VSSTestsuite(Testsuite):
"""Testsuite for the VSS library"""

test_driver_map = {"legacy": VSSLegacyDriver}
test_driver_map = {"legacy": VSSLegacyDriver, "gdbpp": VSSGDBPPDriver}
default_driver = "legacy"


Expand Down

0 comments on commit 6b808d5

Please sign in to comment.