[Lldb-commits] [lldb] [lldb][AArch64] Read fpmr register from core files (PR #110104)
https://github.com/omjavaid approved this pull request. Looks Good. Sorry about delayed review! https://github.com/llvm/llvm-project/pull/110104 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,486 @@ +""" +Specification, compiler, disassembler, and interpreter +for LLDB dataformatter bytecode. + +See formatter-bytecode.md for more details. +""" +from __future__ import annotations + +# Types +type_String = 1 +type_Int = 2 +type_UInt = 3 +type_Object = 4 +type_Type = 5 + +# Opcodes +opcode = dict() + + +def define_opcode(n, mnemonic, name): +globals()["op_" + name] = n +if mnemonic: +opcode[mnemonic] = n +opcode[n] = mnemonic + + +define_opcode(1, "dup", "dup") +define_opcode(2, "drop", "drop") +define_opcode(3, "pick", "pick") +define_opcode(4, "over", "over") +define_opcode(5, "swap", "swap") +define_opcode(6, "rot", "rot") + +define_opcode(0x10, "{", "begin") +define_opcode(0x11, "if", "if") +define_opcode(0x12, "ifelse", "ifelse") + +define_opcode(0x20, None, "lit_uint") +define_opcode(0x21, None, "lit_int") +define_opcode(0x22, None, "lit_string") +define_opcode(0x23, None, "lit_selector") + +define_opcode(0x30, "+", "plus") +define_opcode(0x31, "-", "minus") +define_opcode(0x32, "*", "mul") +define_opcode(0x33, "/", "div") +define_opcode(0x34, "%", "mod") +define_opcode(0x35, "<<", "shl") +define_opcode(0x36, ">>", "shr") +define_opcode(0x37, "shra", "shra") + +define_opcode(0x40, "&", "and") +define_opcode(0x41, "|", "or") +define_opcode(0x42, "^", "xor") +define_opcode(0x43, "~", "not") + +define_opcode(0x50, "=", "eq") +define_opcode(0x51, "!=", "neq") +define_opcode(0x52, "<", "lt") +define_opcode(0x53, ">", "gt") +define_opcode(0x54, "=<", "le") +define_opcode(0x55, ">=", "ge") + +define_opcode(0x60, "call", "call") + +# Function signatures +sig_summary = 0 +sig_init = 1 +sig_get_num_children = 2 +sig_get_child_index = 3 +sig_get_child_at_index = 4 + +# Selectors +selector = dict() DavidSpickett wrote: I'm not familiar with the term "selector" in this context. Is it inspired by an existing thing that I can go read about? It feels like "member function", like I would call "get_type" a "member function" of a value object. https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Allow specifying libcxx builder image. (PR #110303)
https://github.com/EricWF updated https://github.com/llvm/llvm-project/pull/110303 >From 2d0bc95ac75d404493d4c8883e9fc9880675147f Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Thu, 24 Oct 2024 13:30:07 -0400 Subject: [PATCH 1/2] Allow Specifying the builder image. This change attempts to shift the libc++ builders over to new backend infrastructure that allows running an arbitrary container for the libc++ job. This has been a long time in the making, and support from github and gke is finally at the point where it's possible (hopefully). This change should also demonstrate another important property: No Downtime Upgrades. If this goes well, we'll be able to test the upgrade as a part of the PR process, and then commiting it to main should (ideally) not break anything. --- .github/workflows/libcxx-build-and-test.yaml | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml index 184fed2268e818..3521b5d5a3def4 100644 --- a/.github/workflows/libcxx-build-and-test.yaml +++ b/.github/workflows/libcxx-build-and-test.yaml @@ -49,7 +49,8 @@ env: jobs: stage1: if: github.repository_owner == 'llvm' -runs-on: libcxx-runners-8-set +runs-on: libcxx-runners-set +container: ghcr.io/libcxx/actions-builder:testing-2024-09-21 continue-on-error: false strategy: fail-fast: false @@ -84,7 +85,8 @@ jobs: **/crash_diagnostics/* stage2: if: github.repository_owner == 'llvm' -runs-on: libcxx-runners-8-set +runs-on: libcxx-runners-set +container: ghcr.io/libcxx/actions-builder:testing-2024-09-21 needs: [ stage1 ] continue-on-error: false strategy: @@ -160,20 +162,21 @@ jobs: 'benchmarks', 'bootstrapping-build' ] -machine: [ 'libcxx-runners-8-set' ] +machine: [ 'libcxx-runners-set' ] include: - config: 'generic-cxx26' - machine: libcxx-runners-8-set + machine: libcxx-runners-set - config: 'generic-asan' - machine: libcxx-runners-8-set + machine: libcxx-runners-set - config: 'generic-tsan' - machine: libcxx-runners-8-set + machine: libcxx-runners-set - config: 'generic-ubsan' - machine: libcxx-runners-8-set + machine: libcxx-runners-set # Use a larger machine for MSAN to avoid timeout and memory allocation issues. - config: 'generic-msan' - machine: libcxx-runners-8-set + machine: libcxx-runners-set runs-on: ${{ matrix.machine }} +container: ghcr.io/libcxx/actions-builder:testing-2024-09-21 steps: - uses: actions/checkout@v4 - name: ${{ matrix.config }} >From ac41555d4855f65e1d43a6198a2bdaefe0375b0c Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Thu, 24 Oct 2024 13:33:50 -0400 Subject: [PATCH 2/2] Try cherry-picking lldb fix --- .../Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py| 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py index 7e80912be44642..cf30aad6b7f35b 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py @@ -367,7 +367,7 @@ def launch( cwd=None, env=None, stopOnEntry=False, -disableASLR=True, +disableASLR=False, disableSTDIO=False, shellExpandArguments=False, trace=False, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap][test] Set disableASLR to False for tests (PR #113593)
https://github.com/walter-erquinigo approved this pull request. https://github.com/llvm/llvm-project/pull/113593 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap][test] Set disableASLR to False for tests (PR #113593)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) Changes When running in constrained environments like docker, disable ASLR might fail with errors like: ``` AssertionError: False is not true : launch failed (Cannot launch '/__w/.../lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.test_subtleFrames/a.out': personality set failed: Operation not permitted) ``` E.g., https://github.com/llvm/llvm-project/pull/110303 Hence we already run `settings set target.disable-aslr false` as part of the init-commands for the non-DAP tests (see https://github.com/llvm/llvm-project/pull/88312 and https://discourse.llvm.org/t/running-lldb-in-a-container/76801). But we never adjusted it for the DAP tests. Hence we get conflicting test houtput like: ``` { "arguments": { "commandEscapePrefix": null, "disableASLR": true, "initCommands": [ ... "settings set target.disable-aslr false", ``` Disabling ASLR by default in tests isn't useulf (it's only really a debugging aid for users). So this patch sets `disableASLR=False` by default. --- Full diff: https://github.com/llvm/llvm-project/pull/113593.diff 1 Files Affected: - (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py (+1-1) ``diff diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py index 7e80912be44642..cf30aad6b7f35b 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py @@ -367,7 +367,7 @@ def launch( cwd=None, env=None, stopOnEntry=False, -disableASLR=True, +disableASLR=False, disableSTDIO=False, shellExpandArguments=False, trace=False, `` https://github.com/llvm/llvm-project/pull/113593 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove SymbolFilePDB and make the native one the default (PR #113647)
mstorsjo wrote: > Remove `SymbolFilePDB` in favor of always using `SymbolFileNativePDB`. This > effectively makes `LLDB_USE_NATIVE_PDB_READER` the default. The non-native > (DIA based) PDB symbol file implementation was unmaintained and known to have > issues. While this certainly is true, unfortunately the main working testing configuration of LLDB on Windows is with the DIA SDK enabled. In that form, I can run `check-lldb` without any failures. By disabling use of the DIA SDK, I have the following test fallout: ``` Failed Tests (15): lldb-shell :: Driver/TestSingleQuote.test lldb-shell :: Expr/nodefaultlib.cpp lldb-shell :: SymbolFile/DWARF/dwo-static-data-member-access.test lldb-shell :: SymbolFile/PDB/ast-restore.test lldb-shell :: SymbolFile/PDB/calling-conventions-x86.test lldb-shell :: SymbolFile/PDB/class-layout.test lldb-shell :: SymbolFile/PDB/enums-layout.test lldb-shell :: SymbolFile/PDB/expressions.test lldb-shell :: SymbolFile/PDB/func-symbols.test lldb-shell :: SymbolFile/PDB/pointers.test lldb-shell :: SymbolFile/PDB/type-quals.test lldb-shell :: SymbolFile/PDB/typedefs.test lldb-shell :: SymbolFile/PDB/udt-layout.test lldb-shell :: SymbolFile/PDB/variables.test lldb-shell :: Unwind/windows-unaligned-x86_64.test Unexpectedly Passed Tests (1): lldb-shell :: Commands/command-disassemble-mixed.c ``` With this PR in place, we get even more failures: ``` Failed Tests (72): lldb-shell :: Breakpoint/case-insensitive.test lldb-shell :: Breakpoint/dummy-target.test lldb-shell :: Commands/command-disassemble-mixed.test lldb-shell :: Commands/command-process-launch-user-entry.test lldb-shell :: Commands/command-thread-backtrace.test lldb-shell :: Commands/command-thread-select.test lldb-shell :: Driver/TestSingleQuote.test lldb-shell :: Expr/TestIRMemoryMapWindows.test lldb-shell :: Expr/nodefaultlib.cpp lldb-shell :: Process/Windows/process_load.cpp lldb-shell :: Settings/TestFrameFormatColor.test lldb-shell :: Settings/TestFrameFormatNoColor.test lldb-shell :: Settings/TestLineMarkerColor.test lldb-shell :: SymbolFile/DWARF/dwo-debug-file-search-paths-dwoname-absolute-compdir.c lldb-shell :: SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-absolute-compdir.c lldb-shell :: SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-relative-compdir.c lldb-shell :: SymbolFile/DWARF/dwo-debug-file-search-paths-relative-compdir.c lldb-shell :: SymbolFile/DWARF/dwo-relative-filename-only-binary-dir.c lldb-shell :: SymbolFile/DWARF/dwo-static-data-member-access.test lldb-shell :: SymbolFile/NativePDB/ast-functions-msvc.cpp lldb-shell :: SymbolFile/NativePDB/ast-functions.cpp lldb-shell :: SymbolFile/NativePDB/ast-methods.cpp lldb-shell :: SymbolFile/NativePDB/ast-restore.test lldb-shell :: SymbolFile/NativePDB/ast-types.cpp lldb-shell :: SymbolFile/NativePDB/bitfields.cpp lldb-shell :: SymbolFile/NativePDB/blocks.s lldb-shell :: SymbolFile/NativePDB/break-by-function.cpp lldb-shell :: SymbolFile/NativePDB/break-by-line.cpp lldb-shell :: SymbolFile/NativePDB/calling-conventions-x86.test lldb-shell :: SymbolFile/NativePDB/class-layout.test lldb-shell :: SymbolFile/NativePDB/class_layout.cpp lldb-shell :: SymbolFile/NativePDB/compilands.test lldb-shell :: SymbolFile/NativePDB/disassembly.cpp lldb-shell :: SymbolFile/NativePDB/enums-layout.test lldb-shell :: SymbolFile/NativePDB/expressions.test lldb-shell :: SymbolFile/NativePDB/find-functions.cpp lldb-shell :: SymbolFile/NativePDB/func-symbols.test lldb-shell :: SymbolFile/NativePDB/function-level-linking.test lldb-shell :: SymbolFile/NativePDB/function-types-builtins.cpp lldb-shell :: SymbolFile/NativePDB/function-types-calling-conv.cpp lldb-shell :: SymbolFile/NativePDB/function-types-classes.cpp lldb-shell :: SymbolFile/NativePDB/global-classes.cpp lldb-shell :: SymbolFile/NativePDB/global-ctor-dtor.cpp lldb-shell :: SymbolFile/NativePDB/globals-bss.cpp lldb-shell :: SymbolFile/NativePDB/globals-fundamental.cpp lldb-shell :: SymbolFile/NativePDB/icf.cpp lldb-shell :: SymbolFile/NativePDB/incomplete-tag-type.cpp lldb-shell :: SymbolFile/NativePDB/inline_sites.test lldb-shell :: SymbolFile/NativePDB/inline_sites_live.cpp lldb-shell :: SymbolFile/NativePDB/load-pdb.cpp lldb-shell :: SymbolFile/NativePDB/local-variables-registers.s lldb-shell :: SymbolFile/NativePDB/local-variables.cpp lldb-shell :: SymbolFile/NativePDB/locate-pdb.cpp lldb-shell :: SymbolFile/NativePDB/lookup-by-address.cpp lldb-shell :: SymbolFile/NativePDB/lookup-by-types.cpp lldb-shell :: SymbolFile/NativePDB/missing-type.s lldb-shell :: SymbolFile/NativePDB/nested-blocks-same-address.s lldb-shell :: SymbolFile/NativePDB/nested-types.cpp lldb-shell :: SymbolFile/NativePDB/pointers.test lldb-shell :: SymbolFile/NativePDB/s_constant.cpp lldb-shell :: SymbolFile/NativePDB/source-list.cpp lldb-sh
[Lldb-commits] [lldb] [lldb] Remove SymbolFilePDB and make the native one the default (PR #113647)
DavidSpickett wrote: > The non-native (DIA based) PDB symbol file implementation was unmaintained > and known to have issues. FWIW I have seen feedback from users who have no idea what this does or why there would be two things when one is always worse in their experience. Unfortunately I've never been able to adequately explain it to them because I myself don't understand the differences :) What axis do we have here? * Native or non-native? * DIA SDK or not? https://github.com/llvm/llvm-project/pull/113647 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` +- `swap (x y -> y x)` +- `rot (x y z -> z x y)` + +### Control flow + +- `{` pushes a code block address onto the control stack +- `}` (technically not an opcode) denotes the end of a code block +- `if` pops a block from the control stack, if the top of the data stack is nonzero, executes it +- `ifelse` pops two blocks from the control stack, if the top of the data stack is nonzero, executes the first, otherwise the second. + +### Literals for basic types + +- `123u ( -> UInt)` an unsigned 64-bit host integer. +- `123 ( -> Int)` a signed 64-bit host integer. +- `"abc" ( -> String)` a UTF-8 host string. porglezomp wrote: ASCII is a strict subset of UTF-8, all ASCII strings are also UTF-8 strings. https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb] Fix write only file action to truncate the file (PR #112657)
https://github.com/kusmour updated https://github.com/llvm/llvm-project/pull/112657 >From 6ee1560ed4c0c2e77943b90fdf97523309f1e754 Mon Sep 17 00:00:00 2001 From: Wanyi Ye Date: Mon, 14 Oct 2024 22:37:50 -0700 Subject: [PATCH] [lldb] Fix write only file action to truncate the file --- lldb/source/Host/common/FileAction.cpp| 2 +- .../API/commands/settings/TestSettings.py | 53 +++ .../python_api/process/io/TestProcessIO.py| 30 +++ lldb/unittests/Host/FileActionTest.cpp| 25 + llvm/docs/ReleaseNotes.md | 2 + 5 files changed, 111 insertions(+), 1 deletion(-) diff --git a/lldb/source/Host/common/FileAction.cpp b/lldb/source/Host/common/FileAction.cpp index f980d3224640e0..e1c3e14a165ea9 100644 --- a/lldb/source/Host/common/FileAction.cpp +++ b/lldb/source/Host/common/FileAction.cpp @@ -41,7 +41,7 @@ bool FileAction::Open(int fd, const FileSpec &file_spec, bool read, else if (read) m_arg = O_NOCTTY | O_RDONLY; else - m_arg = O_NOCTTY | O_CREAT | O_WRONLY; + m_arg = O_NOCTTY | O_CREAT | O_WRONLY | O_TRUNC; m_file_spec = file_spec; return true; } else { diff --git a/lldb/test/API/commands/settings/TestSettings.py b/lldb/test/API/commands/settings/TestSettings.py index 385acceb7a8b5c..2dd813f6b155b3 100644 --- a/lldb/test/API/commands/settings/TestSettings.py +++ b/lldb/test/API/commands/settings/TestSettings.py @@ -528,6 +528,59 @@ def test_set_error_output_path(self): output, exe=False, startstr="This message should go to standard out." ) +@skipIfDarwinEmbedded # debugserver on ios etc can't write files +def test_same_error_output_path(self): +"""Test that setting target.error and output-path to the same file path for the launched process works.""" +self.build() + +exe = self.getBuildArtifact("a.out") +self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) + +# Set the error-path and output-path and verify both are set. +self.runCmd( +"settings set target.error-path '{0}'".format( +lldbutil.append_to_process_working_directory(self, "output.txt") +) +) +self.runCmd( +"settings set target.output-path '{0}".format( +lldbutil.append_to_process_working_directory(self, "output.txt") +) +) +# And add hooks to restore the original settings during tearDown(). +self.addTearDownHook(lambda: self.runCmd("settings clear target.output-path")) +self.addTearDownHook(lambda: self.runCmd("settings clear target.error-path")) + +self.expect( +"settings show target.error-path", +SETTING_MSG("target.error-path"), +substrs=["target.error-path (file)", 'output.txt"'], +) + +self.expect( +"settings show target.output-path", +SETTING_MSG("target.output-path"), +substrs=["target.output-path (file)", 'output.txt"'], +) + +self.runCmd( +"process launch --working-dir '{0}'".format( +self.get_process_working_directory() +), +RUN_SUCCEEDED, +) + +output = lldbutil.read_file_from_process_wd(self, "output.txt") +err_message = "This message should go to standard error." +out_message = "This message should go to standard out." +# Error msg should get flushed by the output msg +self.expect(output, exe=False, substrs=[out_message]) +self.assertNotIn( +err_message, +output, +"Race condition when both stderr/stdout redirects to the same file", +) + def test_print_dictionary_setting(self): self.runCmd("settings clear target.env-vars") self.runCmd('settings set target.env-vars ["MY_VAR"]=some-value') diff --git a/lldb/test/API/python_api/process/io/TestProcessIO.py b/lldb/test/API/python_api/process/io/TestProcessIO.py index 5bb91d2758312d..3b5c7c48c51f4d 100644 --- a/lldb/test/API/python_api/process/io/TestProcessIO.py +++ b/lldb/test/API/python_api/process/io/TestProcessIO.py @@ -95,6 +95,36 @@ def test_stdout_stderr_redirection(self): error = self.read_error_file_and_delete() self.check_process_output(output, error) +@skipIfWindows # stdio manipulation unsupported on Windows +@expectedFlakeyLinux(bugnumber="llvm.org/pr26437") +@skipIfDarwinEmbedded # debugserver can't create/write files on the device +def test_stdout_stderr_redirection_to_existing_files(self): +"""Exercise SBLaunchInfo::AddOpenFileAction() for STDOUT and STDERR without redirecting STDIN to output files already exist.""" +self.setup_test() +self.build() +self.create_target() +self.write_file_with_placeholder(self.output_file) +self.write_file_with_placeholder(self.error_file) +
[Lldb-commits] [lldb] [lldb] Extend FindTypes to optionally search by mangled type name (PR #113007)
@@ -2758,6 +2758,15 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) { return true; // Keep iterating over index types, language mismatch. } +// Since mangled names are unique, we only need to check if the names are +// the same. +if (query.GetSearchByMangledName()) { + if (die.GetMangledName() == query.GetTypeBasename().GetStringRef()) +if (Type *matching_type = ResolveType(die, true, true)) + results.InsertUnique(matching_type->shared_from_this()); + return !results.Done(query); // Keep iterating if we aren't done. +} clayborg wrote: This logic needs doesn't need to check if results are done if we didn't add anything to the results. Maybe this would be more clear?: ``` if (query.GetSearchByMangledName()) { if (die.GetMangledName() != query.GetTypeBasename().GetStringRef()) return true; // Keep iterating over index types, mangled name mismatch. if (Type *matching_type = ResolveType(die, true, true)) { results.InsertUnique(matching_type->shared_from_this()); return !results.Done(query); // Keep iterating if we aren't done. } return true; // Keep iterating over index types, weren't able to resolve this type } ``` One other issue is that `DWARFDie::GetMangledName()` will return the `DW_AT_name` if there is no mangled name: ``` const char *DWARFDIE::GetMangledName() const { if (IsValid()) return m_die->GetMangledName(m_cu); else return nullptr; } ``` But `const char *DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu, bool substitute_name_allowed)` has a boolean option `substitute_name_allowed` that defaults to true. So we should probably also change: ``` const char *DWARFDIE::GetMangledName() const; ``` To have that same option with a default value: ``` const char *DWARFDIE::GetMangledName(bool substitute_name_allowed = true) const ``` And then change your code to pass in `false` for the `substitute_name_allowed` https://github.com/llvm/llvm-project/pull/113007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add a target.launch-working-dir setting (PR #113521)
https://github.com/walter-erquinigo edited https://github.com/llvm/llvm-project/pull/113521 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
DavidSpickett wrote: Compiling languages into this is intriguing. MLIR noob thinking out loud: if MLIR could lower into this could you write your formatter in Fortran? :rofl: https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
@@ -614,7 +614,7 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const { } bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const { - if (Tag() != DW_TAG_variable) + if (Tag() != DW_TAG_variable && Tag() != DW_TAG_member) Michael137 wrote: This patch is about supporting `DW_TAG_member`s that are static variables right? Wouldn't those be children of `DW_TAG_subprogram`s and thus fail this check anyway? https://github.com/llvm/llvm-project/pull/111859 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix pointer to reference type (PR #113596)
https://github.com/jeffreytan81 updated https://github.com/llvm/llvm-project/pull/113596 >From 65b0349f7b136ffef1ab75a1a47bb3a5f763cf28 Mon Sep 17 00:00:00 2001 From: jeffreytan81 Date: Thu, 24 Oct 2024 10:42:18 -0700 Subject: [PATCH] Fix pointer to reference type --- lldb/source/Core/ValueObject.cpp | 9 .../TestCPPDereferencingReferences.py | 21 +++ .../cpp/dereferencing_references/main.cpp | 2 ++ 3 files changed, 32 insertions(+) diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 5b1c171c01f2db..5e3839b89ce0ec 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -2911,6 +2911,15 @@ ValueObjectSP ValueObject::AddressOf(Status &error) { AddressType address_type = eAddressTypeInvalid; const bool scalar_is_load_address = false; + + // For reference type we need to get the address of the object that + // it refers to. + if (GetCompilerType().IsReferenceType()) { +ValueObjectSP deref_obj = Dereference(error); +if (error.Fail() || !deref_obj) + return ValueObjectSP(); +return deref_obj->AddressOf(error); + } addr_t addr = GetAddressOf(scalar_is_load_address, &address_type); error.Clear(); if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) { diff --git a/lldb/test/API/lang/cpp/dereferencing_references/TestCPPDereferencingReferences.py b/lldb/test/API/lang/cpp/dereferencing_references/TestCPPDereferencingReferences.py index 938fb1a6edf32c..1374d4e1ec67ab 100644 --- a/lldb/test/API/lang/cpp/dereferencing_references/TestCPPDereferencingReferences.py +++ b/lldb/test/API/lang/cpp/dereferencing_references/TestCPPDereferencingReferences.py @@ -25,3 +25,24 @@ def test(self): # Typedef to a reference should dereference to the underlying type. td_val = self.expect_var_path("td_to_ref_type", type="td_int_ref") self.assertEqual(td_val.Dereference().GetType().GetName(), "int") + +def test_take_address_of_reference(self): +"""Tests taking address of lvalue/rvalue references in lldb works correctly.""" +self.build() +lldbutil.run_to_source_breakpoint( +self, "// break here", lldb.SBFileSpec("main.cpp") +) + +plref_val_from_code = self.expect_var_path("pl_ref", type="TTT *") +plref_val_from_expr_path = self.expect_var_path("&l_ref", type="TTT *") +self.assertEqual( +plref_val_from_code.GetValueAsAddress(), +plref_val_from_expr_path.GetValueAsAddress(), +) + +prref_val_from_code = self.expect_var_path("pr_ref", type="TTT *") +prref_val_from_expr_path = self.expect_var_path("&r_ref", type="TTT *") +self.assertEqual( +prref_val_from_code.GetValueAsAddress(), +prref_val_from_expr_path.GetValueAsAddress(), +) diff --git a/lldb/test/API/lang/cpp/dereferencing_references/main.cpp b/lldb/test/API/lang/cpp/dereferencing_references/main.cpp index b64978a9029f81..4ddffd167ddeed 100644 --- a/lldb/test/API/lang/cpp/dereferencing_references/main.cpp +++ b/lldb/test/API/lang/cpp/dereferencing_references/main.cpp @@ -9,5 +9,7 @@ int main() { // typedef of a reference td_int_ref td_to_ref_type = i; + TTT *pl_ref = &l_ref; + TTT *pr_ref = &r_ref; return l_ref; // break here } ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Extend FindTypes to optionally search by mangled type name (PR #113007)
https://github.com/Michael137 approved this pull request. Seems reasonable to me Yea not entirely sure how to test this either. As Greg points out, type mangling isn't really a thing LLDB cared about for C++. Maybe if we had this option exposed somehow (e.g., through `lldb-test`) we could come up with a DWARF yaml that has a type with a linkage name in the accelerator tables? But if that's too much hassle and we have a test on the Apple fork that exercises this API maybe we're ok https://github.com/llvm/llvm-project/pull/113007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove SymbolFilePDB and make the native one the default (PR #113647)
mstorsjo wrote: > Interesting. Based on a conversation at the dev meeting, I was under the > impression that the DIA-based implementation was in worse shape and the > native one in better shape. I also have a memory of bug reports about PDB > parsing where originators were asked to check with > `LLDB_USE_NATIVE_PDB_READER` instead. I don't really know it too closely either, but my understanding was that the DIA SDK based one was more complete. Both probably have their own sets of bugs anyway, so "check with the other implementation" always is a reasonable assumption. I also agree that getting rid of the DIA SDK based one would be the way to go - that also gets us equal functionality across all platforms. In any case - using the DIA SDK is the canonical configuration where tests do pass AFAIK; bringing configurations without it up to the same level would at least be a first step towards resolving this. https://github.com/llvm/llvm-project/pull/113647 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 2d26ef0 - [lldb-dap][test] Set disableASLR to False for tests (#113593)
Author: Michael Buch Date: 2024-10-25T12:06:57+01:00 New Revision: 2d26ef09fc87472cd42ea219c8f9267599872958 URL: https://github.com/llvm/llvm-project/commit/2d26ef09fc87472cd42ea219c8f9267599872958 DIFF: https://github.com/llvm/llvm-project/commit/2d26ef09fc87472cd42ea219c8f9267599872958.diff LOG: [lldb-dap][test] Set disableASLR to False for tests (#113593) When running in constrained environments like docker, disabling ASLR might fail with errors like: ``` AssertionError: False is not true : launch failed (Cannot launch '/__w/.../lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.test_subtleFrames/a.out': personality set failed: Operation not permitted) ``` E.g., https://github.com/llvm/llvm-project/pull/110303 Hence we already run `settings set target.disable-aslr false` as part of the init-commands for the non-DAP tests (see https://github.com/llvm/llvm-project/pull/88312 and https://discourse.llvm.org/t/running-lldb-in-a-container/76801). But we never adjusted it for the DAP tests. As a result we get conflicting test logs like: ``` { "arguments": { "commandEscapePrefix": null, "disableASLR": true, "initCommands": [ ... "settings set target.disable-aslr false", ``` Disabling ASLR by default in tests isn't useulf (it's only really a debugging aid for users). So this patch sets `disableASLR=False` by default. Added: Modified: lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py Removed: diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py index 7e80912be44642..a25466f07fa557 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py @@ -367,7 +367,7 @@ def launch( cwd=None, env=None, stopOnEntry=False, -disableASLR=True, +disableASLR=False, disableSTDIO=False, shellExpandArguments=False, trace=False, @@ -451,7 +451,7 @@ def build_and_launch( cwd=None, env=None, stopOnEntry=False, -disableASLR=True, +disableASLR=False, disableSTDIO=False, shellExpandArguments=False, trace=False, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` +- `swap (x y -> y x)` +- `rot (x y z -> z x y)` + +### Control flow + +- `{` pushes a code block address onto the control stack +- `}` (technically not an opcode) denotes the end of a code block +- `if` pops a block from the control stack, if the top of the data stack is nonzero, executes it +- `ifelse` pops two blocks from the control stack, if the top of the data stack is nonzero, executes the first, otherwise the second. + +### Literals for basic types + +- `123u ( -> UInt)` an unsigned 64-bit host integer. +- `123 ( -> Int)` a signed 64-bit host integer. +- `"abc" ( -> String)` a UTF-8 host string. +- `@strlen ( -> Selector)` one of the predefined functions supported by the VM. + +### Arithmetic, logic, and comparison operations +- `+ (x y -> [x+y])` +- `-` etc ... +- `*` +- `/` +- `%` +- `<<` +- `>>` +- `shra` (arithmetic shift right) +- `~` +- `|` +- `^` +- `=` +- `!=` +- `<` +- `>` +- `=<` +- `>=` + +### Function calls + +For security reasons the list of functions callable with `call` is predefined. The supported functions are either existing methods on `SBValue`, or string formatting operations. + +- `call (Object arg0 ... Selector -> retval)` + +Method is one of a predefined set of _Selectors_ DavidSpickett wrote: Ofc we can make some check that goes the other way, that our allow list of selectors matches the current types in SBValue. https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap][test] Set disableASLR to False for tests (PR #113593)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/113593 >From 135092caf94e69c0aac25bcb73190ea69776d60e Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Thu, 24 Oct 2024 17:50:02 +0100 Subject: [PATCH 1/2] [lldb-dap][test] Set disableASLR to False for tests When running in constrained environments like docker, disable ASLR might fail with errors like: ``` AssertionError: False is not true : launch failed (Cannot launch '/__w/.../lldb-dap/stackTrace/subtleFrames/TestDAP_subtleFrames.test_subtleFrames/a.out': personality set failed: Operation not permitted) ``` E.g., https://github.com/llvm/llvm-project/pull/110303 Hence we already run `settings set target.disable-aslr false` as part of the init-commands for the non-DAP tests (see https://github.com/llvm/llvm-project/pull/88312 and https://discourse.llvm.org/t/running-lldb-in-a-container/76801). But we never adjusted it for the DAP tests. Hence we get conflicting test houtput like: ``` { "arguments": { "commandEscapePrefix": null, "disableASLR": true, "initCommands": [ ... "settings set target.disable-aslr false", ``` Disabling ASLR by default in tests isn't useulf (it's only really a debugging aid for users). So this patch sets `disableASLR=False` by default. --- .../Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py| 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py index 7e80912be44642..cf30aad6b7f35b 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py @@ -367,7 +367,7 @@ def launch( cwd=None, env=None, stopOnEntry=False, -disableASLR=True, +disableASLR=False, disableSTDIO=False, shellExpandArguments=False, trace=False, >From 4a5ac981186af407aa79483bd95d86542ad11172 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Fri, 25 Oct 2024 11:34:25 +0100 Subject: [PATCH 2/2] fixup! also set disableASLR=False in build_and_launch method --- .../Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py| 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py index cf30aad6b7f35b..a25466f07fa557 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py @@ -451,7 +451,7 @@ def build_and_launch( cwd=None, env=None, stopOnEntry=False, -disableASLR=True, +disableASLR=False, disableSTDIO=False, shellExpandArguments=False, trace=False, ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove SymbolFilePDB and make the native one the default (PR #113647)
JDevlieghere wrote: Interesting. Based on a conversation at the dev meeting, I was under the impression that the DIA-based implementation was in worse shape and the native one in better shape. I also have a memory of bug reports about PDB parsing where originators were asked to check with `LLDB_USE_NATIVE_PDB_READER` instead. FWIW I don't have a vested interest in removing this code. This came up in a conversation about understanding what works and doesn't work on Windows. I feel like we're in limbo here and I'd love to get to a point where we can set clear expectations to our users about what does and doesn't work. Having multiple configurations of things (like the symbol file an the process plugin) doesn't make that matrix easier to understand. > What axis do we have here? > > * Native or non-native? > * DIA SDK or not? My understanding of the situation is that `SymbolFilePDB` uses the Microsoft Debug Interface Access (DIA) SDK, which of course is only available on Windows and that `SymbolFileNativePDB` uses LLVM's "native" PDB parser, which should be available on all platforms (similar to how you can parse DWARF on Windows). In other words, if you're on Windows, you can use both. If you're on another platform, you can only use the latter. https://github.com/llvm/llvm-project/pull/113647 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,486 @@ +""" +Specification, compiler, disassembler, and interpreter +for LLDB dataformatter bytecode. + +See formatter-bytecode.md for more details. +""" +from __future__ import annotations + +# Types +type_String = 1 +type_Int = 2 +type_UInt = 3 +type_Object = 4 +type_Type = 5 + +# Opcodes +opcode = dict() + + +def define_opcode(n, mnemonic, name): +globals()["op_" + name] = n +if mnemonic: +opcode[mnemonic] = n +opcode[n] = mnemonic + + +define_opcode(1, "dup", "dup") +define_opcode(2, "drop", "drop") +define_opcode(3, "pick", "pick") +define_opcode(4, "over", "over") +define_opcode(5, "swap", "swap") +define_opcode(6, "rot", "rot") + +define_opcode(0x10, "{", "begin") +define_opcode(0x11, "if", "if") +define_opcode(0x12, "ifelse", "ifelse") + +define_opcode(0x20, None, "lit_uint") +define_opcode(0x21, None, "lit_int") +define_opcode(0x22, None, "lit_string") +define_opcode(0x23, None, "lit_selector") + +define_opcode(0x30, "+", "plus") +define_opcode(0x31, "-", "minus") +define_opcode(0x32, "*", "mul") +define_opcode(0x33, "/", "div") +define_opcode(0x34, "%", "mod") +define_opcode(0x35, "<<", "shl") +define_opcode(0x36, ">>", "shr") +define_opcode(0x37, "shra", "shra") + +define_opcode(0x40, "&", "and") +define_opcode(0x41, "|", "or") +define_opcode(0x42, "^", "xor") +define_opcode(0x43, "~", "not") + +define_opcode(0x50, "=", "eq") +define_opcode(0x51, "!=", "neq") +define_opcode(0x52, "<", "lt") +define_opcode(0x53, ">", "gt") +define_opcode(0x54, "=<", "le") +define_opcode(0x55, ">=", "ge") + +define_opcode(0x60, "call", "call") + +# Function signatures +sig_summary = 0 +sig_init = 1 +sig_get_num_children = 2 +sig_get_child_index = 3 +sig_get_child_at_index = 4 + +# Selectors +selector = dict() + + +def define_selector(n, name): +globals()["sel_" + name] = n +selector["@" + name] = n +selector[n] = "@" + name + + +define_selector(0, "summary") +define_selector(1, "type_summary") + +define_selector(0x10, "get_num_children") +define_selector(0x11, "get_child_at_index") +define_selector(0x12, "get_child_with_name") +define_selector(0x13, "get_child_index") +define_selector(0x15, "get_type") +define_selector(0x16, "get_template_argument_type") +define_selector(0x20, "get_value") +define_selector(0x21, "get_value_as_unsigned") +define_selector(0x22, "get_value_as_signed") +define_selector(0x23, "get_value_as_address") +define_selector(0x24, "cast") + +define_selector(0x40, "read_memory_byte") +define_selector(0x41, "read_memory_uint32") +define_selector(0x42, "read_memory_int32") +define_selector(0x43, "read_memory_unsigned") +define_selector(0x44, "read_memory_signed") +define_selector(0x45, "read_memory_address") +define_selector(0x46, "read_memory") + +define_selector(0x50, "fmt") +define_selector(0x51, "sprintf") +define_selector(0x52, "strlen") + + + +# Compiler. + + + +def compile(assembler: str) -> bytearray: +"""Compile assembler into bytecode""" +# This is a stack of all in-flight/unterminated blocks. +bytecode = [bytearray()] + +def emit(byte): +bytecode[-1].append(byte) + +tokens = list(assembler.split(" ")) +tokens.reverse() +while tokens: +tok = tokens.pop() +if tok == "": +pass +elif tok == "{": +bytecode.append(bytearray()) +elif tok == "}": +block = bytecode.pop() +emit(op_begin) +emit(len(block)) # FIXME: uleb +bytecode[-1].extend(block) +elif tok[0].isdigit(): +if tok[-1] == "u": +emit(op_lit_uint) +emit(int(tok[:-1])) # FIXME +else: +emit(op_lit_int) +emit(int(tok)) # FIXME +elif tok[0] == "@": +emit(op_lit_selector) +emit(selector[tok]) +elif tok[0] == '"': +s = bytearray() +done = False +chrs = tok[1:] +while not done: +quoted = False +for c in chrs: +if quoted: +s.append(ord(c)) # FIXME +quoted = False +elif c == "\\": +quoted = True +elif c == '"': +done = True +break +# FIXME assert this is last in token +else: +s.append(ord(c)) +if not done: +s.append(ord(" ")) +chrs = tokens.pop() + +emit(op_lit_string) +emit(len(s)) +bytecode[-1].extend(s) +else: +emit(opcode[tok]) +assert len(bytecode) == 1 # unterminated { +return bytecode[0] + + +#
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` +- `swap (x y -> y x)` +- `rot (x y z -> z x y)` + +### Control flow + +- `{` pushes a code block address onto the control stack +- `}` (technically not an opcode) denotes the end of a code block DavidSpickett wrote: Ok so this is why "end" is missing in the files above? https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Push down cpython module to the submodule (PR #113066)
https://github.com/dingxiangfei2009 closed https://github.com/llvm/llvm-project/pull/113066 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Extend FindTypes to optionally search by mangled type name (PR #113007)
https://github.com/clayborg requested changes to this pull request. https://github.com/llvm/llvm-project/pull/113007 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Proof of concept data formatter compiler for Python (PR #113734)
https://github.com/kastiglione edited https://github.com/llvm/llvm-project/pull/113734 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove SymbolFilePDB and make the native one the default (PR #113647)
omjavaid wrote: We set DIA SDK as the default symbol provider on windows. So I don think this change is appropriate at this stage without testing the complete fallout. Although I believe we should move in that direction sooner or later. https://github.com/llvm/llvm-project/pull/113647 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove SymbolFilePDB and make the native one the default (PR #113647)
https://github.com/omjavaid requested changes to this pull request. I will test this and may be we can move ahead in case failures are trivial https://github.com/llvm/llvm-project/pull/113647 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap][test] Set disableASLR to False for tests (PR #113593)
https://github.com/Michael137 closed https://github.com/llvm/llvm-project/pull/113593 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb] Fix write only file action to truncate the file (PR #112657)
https://github.com/kusmour edited https://github.com/llvm/llvm-project/pull/112657 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -182,6 +182,9 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile { lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + void ResetDebugInfoParseTime() override; + void ResetDebugInfoIndexTime() override; + clayborg wrote: Switch to single function `ResetStatistics()` https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -789,6 +789,7 @@ void Debugger::Destroy(DebuggerSP &debugger_sp) { (*debugger_sp->GetAsyncErrorStream()) << result.GetErrorData() << '\n'; } + DebuggerStats::ResetStatistics(*debugger_sp, nullptr); clayborg wrote: We probably don't need to call this. Remove https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -236,6 +236,27 @@ void TargetStats::IncreaseSourceRealpathCompatibleCount(uint32_t count) { bool DebuggerStats::g_collecting_stats = false; +void DebuggerStats::ResetStatistics(Debugger &debugger, Target *target) { + const uint64_t num_modules = target != nullptr + ? target->GetImages().GetSize() + : Module::GetNumberAllocatedModules(); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { +Module *module = target != nullptr + ? target->GetImages().GetModuleAtIndex(image_idx).get() + : Module::GetAllocatedModuleAtIndex(image_idx); +if (module == nullptr) + continue; +ModuleStats module_stat; clayborg wrote: remove https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -236,6 +236,27 @@ void TargetStats::IncreaseSourceRealpathCompatibleCount(uint32_t count) { bool DebuggerStats::g_collecting_stats = false; +void DebuggerStats::ResetStatistics(Debugger &debugger, Target *target) { + const uint64_t num_modules = target != nullptr clayborg wrote: Need to lock the `Module::GetAllocationModuleCollectionMutex()` when using the Module static calls for the global module list. https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -555,6 +555,18 @@ StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() { return m_sym_file_impl->GetDebugInfoIndexTime(); } +void SymbolFileOnDemand::ResetDebugInfoParseTime() { + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(), + __FUNCTION__); + return m_sym_file_impl->ResetDebugInfoParseTime(); +} + +void SymbolFileOnDemand::ResetDebugInfoIndexTime() { + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(), + __FUNCTION__); + return m_sym_file_impl->ResetDebugInfoIndexTime(); +} + clayborg wrote: Switch to a single function `ResetStatistics` and fix the log text "is not skipped" seems wrong? https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -83,6 +83,8 @@ class DWARFIndex { StatsDuration::Duration GetIndexTime() { return m_index_time; } + void ResetIndexTime() { m_index_time.reset(); } + clayborg wrote: Switch to `ResetStatistics` and use similar function in all other classes. https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -4464,6 +4464,11 @@ StatsDuration::Duration SymbolFileDWARF::GetDebugInfoIndexTime() { return {}; } +void SymbolFileDWARF::ResetDebugInfoIndexTime() { + if (m_index) +return m_index->ResetIndexTime(); +} + clayborg wrote: Change to `ResetStatistics` https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -236,6 +236,27 @@ void TargetStats::IncreaseSourceRealpathCompatibleCount(uint32_t count) { bool DebuggerStats::g_collecting_stats = false; +void DebuggerStats::ResetStatistics(Debugger &debugger, Target *target) { + const uint64_t num_modules = target != nullptr + ? target->GetImages().GetSize() + : Module::GetNumberAllocatedModules(); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { +Module *module = target != nullptr + ? target->GetImages().GetModuleAtIndex(image_idx).get() + : Module::GetAllocatedModuleAtIndex(image_idx); +if (module == nullptr) + continue; +ModuleStats module_stat; +module->GetSymtabParseTime().reset(); +module->GetSymtabIndexTime().reset(); clayborg wrote: Just call `module->ResetStatistics();` https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -422,6 +422,13 @@ class SymbolFile : public PluginInterface { /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Reset the time taken to parse the debug information. + virtual void ResetDebugInfoParseTime() {} + + /// Reset the time it took to index the debug information in the object + /// file. + virtual void ResetDebugInfoIndexTime() {} clayborg wrote: remove https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` +- `swap (x y -> y x)` +- `rot (x y z -> z x y)` + +### Control flow + +- `{` pushes a code block address onto the control stack +- `}` (technically not an opcode) denotes the end of a code block +- `if` pops a block from the control stack, if the top of the data stack is nonzero, executes it +- `ifelse` pops two blocks from the control stack, if the top of the data stack is nonzero, executes the first, otherwise the second. + +### Literals for basic types + +- `123u ( -> UInt)` an unsigned 64-bit host integer. +- `123 ( -> Int)` a signed 64-bit host integer. +- `"abc" ( -> String)` a UTF-8 host string. +- `@strlen ( -> Selector)` one of the predefined functions supported by the VM. + +### Arithmetic, logic, and comparison operations +- `+ (x y -> [x+y])` +- `-` etc ... +- `*` +- `/` +- `%` +- `<<` +- `>>` +- `shra` (arithmetic shift right) +- `~` +- `|` +- `^` +- `=` +- `!=` +- `<` +- `>` +- `=<` +- `>=` + +### Function calls + +For security reasons the list of functions callable with `call` is predefined. The supported functions are either existing methods on `SBValue`, or string formatting operations. + +- `call (Object arg0 ... Selector -> retval)` + +Method is one of a predefined set of _Selectors_ +- `(Object @summary -> String)` +- `(Object @type_summary -> String)` + +- `(Object @get_num_children -> UInt)` +- `(Object UInt @get_child_at_index -> Object)` +- `(Object String @get_child_index -> UInt)` +- `(Object @get_type -> Type)` +- `(Object UInt @get_template_argument_type -> Type)` +- `(Object @get_value -> Object)` +- `(Object @get_value_as_unsigned -> UInt)` +- `(Object @get_value_as_signed -> Int)` +- `(Object @get_value_as_address -> UInt)` +- `(Object Type @cast -> Object)` + +- `(UInt @read_memory_byte -> UInt)` +- `(UInt @read_memory_uint32 -> UInt)` +- `(UInt @read_memory_int32 -> Int)` +- `(UInt @read_memory_unsigned -> UInt)` +- `(UInt @read_memory_signed -> Int)` +- `(UInt @read_memory_address -> UInt)` +- `(UInt Type @read_memory -> Object)` + +- `(String arg0 ... fmt -> String)` +- `(String arg0 ... sprintf -> String)` +- `(String strlen -> String)` + +## Byte Code + +Most instructions are just a single byte opcode. The only exceptions
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
adrian-prantl wrote: > Compiling languages into this is intriguing. > > MLIR noob thinking out loud: if MLIR could lower into this could you write > your formatter in Fortran? 🤣 It is well known that Fortran is superbly suited to process text: https://en.wikipedia.org/wiki/Colossal_Cave_Adventure ;-) https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
https://github.com/adrian-prantl edited https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` +- `swap (x y -> y x)` +- `rot (x y z -> z x y)` + +### Control flow + +- `{` pushes a code block address onto the control stack +- `}` (technically not an opcode) denotes the end of a code block +- `if` pops a block from the control stack, if the top of the data stack is nonzero, executes it +- `ifelse` pops two blocks from the control stack, if the top of the data stack is nonzero, executes the first, otherwise the second. + +### Literals for basic types + +- `123u ( -> UInt)` an unsigned 64-bit host integer. +- `123 ( -> Int)` a signed 64-bit host integer. +- `"abc" ( -> String)` a UTF-8 host string. +- `@strlen ( -> Selector)` one of the predefined functions supported by the VM. + +### Arithmetic, logic, and comparison operations +- `+ (x y -> [x+y])` +- `-` etc ... +- `*` +- `/` +- `%` +- `<<` +- `>>` +- `shra` (arithmetic shift right) +- `~` +- `|` +- `^` +- `=` +- `!=` +- `<` +- `>` +- `=<` +- `>=` + +### Function calls + +For security reasons the list of functions callable with `call` is predefined. The supported functions are either existing methods on `SBValue`, or string formatting operations. + +- `call (Object arg0 ... Selector -> retval)` + +Method is one of a predefined set of _Selectors_ +- `(Object @summary -> String)` +- `(Object @type_summary -> String)` + +- `(Object @get_num_children -> UInt)` +- `(Object UInt @get_child_at_index -> Object)` +- `(Object String @get_child_index -> UInt)` +- `(Object @get_type -> Type)` +- `(Object UInt @get_template_argument_type -> Type)` +- `(Object @get_value -> Object)` +- `(Object @get_value_as_unsigned -> UInt)` +- `(Object @get_value_as_signed -> Int)` +- `(Object @get_value_as_address -> UInt)` +- `(Object Type @cast -> Object)` + +- `(UInt @read_memory_byte -> UInt)` +- `(UInt @read_memory_uint32 -> UInt)` +- `(UInt @read_memory_int32 -> Int)` +- `(UInt @read_memory_unsigned -> UInt)` +- `(UInt @read_memory_signed -> Int)` +- `(UInt @read_memory_address -> UInt)` +- `(UInt Type @read_memory -> Object)` + +- `(String arg0 ... fmt -> String)` +- `(String arg0 ... sprintf -> String)` +- `(String strlen -> String)` + +## Byte Code + +Most instructions are just a single byte opcode. The only exceptions
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` +- `swap (x y -> y x)` +- `rot (x y z -> z x y)` + +### Control flow + +- `{` pushes a code block address onto the control stack +- `}` (technically not an opcode) denotes the end of a code block +- `if` pops a block from the control stack, if the top of the data stack is nonzero, executes it +- `ifelse` pops two blocks from the control stack, if the top of the data stack is nonzero, executes the first, otherwise the second. + +### Literals for basic types + +- `123u ( -> UInt)` an unsigned 64-bit host integer. +- `123 ( -> Int)` a signed 64-bit host integer. +- `"abc" ( -> String)` a UTF-8 host string. +- `@strlen ( -> Selector)` one of the predefined functions supported by the VM. + +### Arithmetic, logic, and comparison operations +- `+ (x y -> [x+y])` +- `-` etc ... +- `*` +- `/` +- `%` +- `<<` +- `>>` +- `shra` (arithmetic shift right) +- `~` +- `|` +- `^` +- `=` +- `!=` +- `<` +- `>` +- `=<` +- `>=` + +### Function calls + +For security reasons the list of functions callable with `call` is predefined. The supported functions are either existing methods on `SBValue`, or string formatting operations. + +- `call (Object arg0 ... Selector -> retval)` + +Method is one of a predefined set of _Selectors_ +- `(Object @summary -> String)` +- `(Object @type_summary -> String)` + +- `(Object @get_num_children -> UInt)` +- `(Object UInt @get_child_at_index -> Object)` +- `(Object String @get_child_index -> UInt)` +- `(Object @get_type -> Type)` +- `(Object UInt @get_template_argument_type -> Type)` +- `(Object @get_value -> Object)` +- `(Object @get_value_as_unsigned -> UInt)` +- `(Object @get_value_as_signed -> Int)` +- `(Object @get_value_as_address -> UInt)` +- `(Object Type @cast -> Object)` + +- `(UInt @read_memory_byte -> UInt)` +- `(UInt @read_memory_uint32 -> UInt)` +- `(UInt @read_memory_int32 -> Int)` +- `(UInt @read_memory_unsigned -> UInt)` +- `(UInt @read_memory_signed -> Int)` +- `(UInt @read_memory_address -> UInt)` +- `(UInt Type @read_memory -> Object)` + +- `(String arg0 ... fmt -> String)` +- `(String arg0 ... sprintf -> String)` +- `(String strlen -> String)` + +## Byte Code + +Most instructions are just a single byte opcode. The only exceptions
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,486 @@ +""" +Specification, compiler, disassembler, and interpreter +for LLDB dataformatter bytecode. + +See formatter-bytecode.md for more details. +""" +from __future__ import annotations + +# Types +type_String = 1 +type_Int = 2 +type_UInt = 3 +type_Object = 4 +type_Type = 5 + +# Opcodes +opcode = dict() + + +def define_opcode(n, mnemonic, name): +globals()["op_" + name] = n +if mnemonic: +opcode[mnemonic] = n +opcode[n] = mnemonic + + +define_opcode(1, "dup", "dup") +define_opcode(2, "drop", "drop") +define_opcode(3, "pick", "pick") +define_opcode(4, "over", "over") +define_opcode(5, "swap", "swap") +define_opcode(6, "rot", "rot") + +define_opcode(0x10, "{", "begin") +define_opcode(0x11, "if", "if") +define_opcode(0x12, "ifelse", "ifelse") adrian-prantl wrote: The Python code ``` if foo: bar if foo: bar; else: baz; if foo: bar; elsif foobar: baz; ``` would translate to ``` foo { bar } if foo { bar } { baz } ifelse foo { bar } { foobar { baz } if } ifelse ``` https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
kastiglione wrote: > Compiling languages into this is intriguing. @DavidSpickett A minimal example of Python compiling into this assembly for this bytecode: https://github.com/llvm/llvm-project/pull/113734 https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
https://github.com/adrian-prantl updated https://github.com/llvm/llvm-project/pull/113398 >From dcab1a5a65fe5345f9c2de9346b7884f74ab7f4d Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 22 Oct 2024 16:29:50 -0700 Subject: [PATCH] Add a compiler/interpreter of LLDB data formatter bytecode to examples --- lldb/docs/index.rst | 1 + lldb/docs/resources/formatterbytecode.rst | 221 lldb/examples/formatter-bytecode/Makefile | 8 + lldb/examples/formatter-bytecode/compiler.py | 486 ++ .../formatter-bytecode/test/MyOptional.cpp| 23 + .../formatter-bytecode/test/formatter.py | 131 + 6 files changed, 870 insertions(+) create mode 100644 lldb/docs/resources/formatterbytecode.rst create mode 100644 lldb/examples/formatter-bytecode/Makefile create mode 100644 lldb/examples/formatter-bytecode/compiler.py create mode 100644 lldb/examples/formatter-bytecode/test/MyOptional.cpp create mode 100644 lldb/examples/formatter-bytecode/test/formatter.py diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst index e2c15d872b4be2..c3c2fb36eb541a 100644 --- a/lldb/docs/index.rst +++ b/lldb/docs/index.rst @@ -164,6 +164,7 @@ interesting areas to contribute to lldb. resources/fuzzing resources/sbapi resources/dataformatters + resources/formatterbytecode resources/extensions resources/lldbgdbremote resources/lldbplatformpackets diff --git a/lldb/docs/resources/formatterbytecode.rst b/lldb/docs/resources/formatterbytecode.rst new file mode 100644 index 00..a80cff3061fbe2 --- /dev/null +++ b/lldb/docs/resources/formatterbytecode.rst @@ -0,0 +1,221 @@ +Formatter Bytecode +== + +Background +-- + +LLDB provides very rich customization options to display data types (see :doc:`/use/variable/`). To use custom data formatters, developers need to edit the global `~/.lldbinit` file to make sure they are found and loaded. In addition to this rather manual workflow, developers or library authors can ship ship data formatters with their code in a format that allows LLDB automatically find them and run them securely. + +An end-to-end example of such a workflow is the Swift `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +Goals +~ + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +Non-goals +~ + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +Design of the virtual machine +- + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the virtual machine. + +Data types +~~ + +All objects on the data stack must have one of the following data types. These data types are "host" data types, in LLDB parlance. + +* *String* (UTF-8) +* *Int* (64 bit) +* *UInt* (64 bit) +* *Object* (Basically an `SBValue`) +* *Type* (Basically an `SBType`) +* *Selector* (One of the predefine functions) + +*Object* and *Type* are opaque, they can only be used as a parameters of `call`. + +Instruction set +--- + +Stack operations + + +These instructions manipulate the data stack directly. + + == === + OpcodeMnemonicStack effect + -- --- + 0x00 `dup` `(x -> x x)` + 0x01 `drop` `(x y -> x)` + 0x02 `pick` `(x ... UInt -> x ... x)` + 0x03 `over` `(x y -> x y x)` + 0x04 `swap` `(x y -> y x)` + 0x05 `rot` `(x y z -> z x y)` +=== == === + +Control flow + + +These manipulate the control stack and program counter. + + == + OpcodeMnemonicDescription + -- + 0x10 `{`push a code block address onto the control stack + --`}`(technically not an opcode) syntax for end of
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
https://github.com/adrian-prantl updated https://github.com/llvm/llvm-project/pull/113398 >From 0b88de8fe7f5e4ea7f4089be403b271cd7b086d0 Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Tue, 22 Oct 2024 16:29:50 -0700 Subject: [PATCH] Add a compiler/interpreter of LLDB data formatter bytecode to examples --- lldb/docs/index.rst | 1 + lldb/docs/resources/formatterbytecode.rst | 221 lldb/examples/formatter-bytecode/Makefile | 8 + lldb/examples/formatter-bytecode/compiler.py | 486 ++ .../formatter-bytecode/test/MyOptional.cpp| 23 + .../formatter-bytecode/test/formatter.py | 131 + 6 files changed, 870 insertions(+) create mode 100644 lldb/docs/resources/formatterbytecode.rst create mode 100644 lldb/examples/formatter-bytecode/Makefile create mode 100644 lldb/examples/formatter-bytecode/compiler.py create mode 100644 lldb/examples/formatter-bytecode/test/MyOptional.cpp create mode 100644 lldb/examples/formatter-bytecode/test/formatter.py diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst index e2c15d872b4be2..c3c2fb36eb541a 100644 --- a/lldb/docs/index.rst +++ b/lldb/docs/index.rst @@ -164,6 +164,7 @@ interesting areas to contribute to lldb. resources/fuzzing resources/sbapi resources/dataformatters + resources/formatterbytecode resources/extensions resources/lldbgdbremote resources/lldbplatformpackets diff --git a/lldb/docs/resources/formatterbytecode.rst b/lldb/docs/resources/formatterbytecode.rst new file mode 100644 index 00..e6a52a2bdddcdb --- /dev/null +++ b/lldb/docs/resources/formatterbytecode.rst @@ -0,0 +1,221 @@ +Formatter Bytecode +== + +Background +-- + +LLDB provides very rich customization options to display data types (see :doc:`/use/variable/`). To use custom data formatters, developers need to edit the global `~/.lldbinit` file to make sure they are found and loaded. In addition to this rather manual workflow, developers or library authors can ship ship data formatters with their code in a format that allows LLDB automatically find them and run them securely. + +An end-to-end example of such a workflow is the Swift `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +Goals +~ + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +Non-goals +~ + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +Design of the virtual machine +- + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the virtual machine. + +Data types +~~ + +All objects on the data stack must have one of the following data types. These data types are "host" data types, in LLDB parlance. + +* *String* (UTF-8) +* *Int* (64 bit) +* *UInt* (64 bit) +* *Object* (Basically an `SBValue`) +* *Type* (Basically an `SBType`) +* *Selector* (One of the predefine functions) + +*Object* and *Type* are opaque, they can only be used as a parameters of `call`. + +Instruction set +--- + +Stack operations + + +These instructions manipulate the data stack directly. + + == === + OpcodeMnemonicStack effect + -- --- + 0x00 `dup` `(x -> x x)` + 0x01 `drop` `(x y -> x)` + 0x02 `pick` `(x ... UInt -> x ... x)` + 0x03 `over` `(x y -> x y x)` + 0x04 `swap` `(x y -> y x)` + 0x05 `rot` `(x y z -> z x y)` +=== == === + +Control flow + + +These manipulate the control stack and program counter. + + == + OpcodeMnemonicDescription + -- + 0x10 `{`push a code block address onto the control stack + --`}`(technically not an opcode) syntax for end of
[Lldb-commits] [lldb] [lldb] Load embedded type summary section (#7859) (#8040) (PR #113743)
https://github.com/adrian-prantl created https://github.com/llvm/llvm-project/pull/113743 Add support for type summaries embedded into the binary. These embedded summaries will typically be generated by Swift macros, but can also be generated by any other means. rdar://115184658 This upstreams the embedded type summary feature from the swiftlang branch of LLDB, since it shares a lot of the same goals and design points with https://github.com/llvm/llvm-project/pull/113398/ >From c9a4d24f222a70c7c108deebb6c25222893d7159 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 24 Jan 2024 12:42:45 -0800 Subject: [PATCH] [lldb] Load embedded type summary section (#7859) (#8040) Add support for type summaries embedded into the binary. These embedded summaries will typically be generated by Swift macros, but can also be generated by any other means. rdar://115184658 --- lldb/include/lldb/lldb-enumerations.h | 1 + lldb/source/Core/Section.cpp | 3 + .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 1 + .../ObjectFile/Mach-O/ObjectFileMachO.cpp | 4 ++ .../ObjectFile/PECOFF/ObjectFilePECOFF.cpp| 1 + lldb/source/Symbol/ObjectFile.cpp | 1 + lldb/source/Target/Target.cpp | 72 +++ .../data-formatter/embedded-summary/Makefile | 2 + .../TestEmbeddedTypeSummary.py| 12 .../data-formatter/embedded-summary/main.c| 22 ++ 10 files changed, 119 insertions(+) create mode 100644 lldb/test/API/functionalities/data-formatter/embedded-summary/Makefile create mode 100644 lldb/test/API/functionalities/data-formatter/embedded-summary/TestEmbeddedTypeSummary.py create mode 100644 lldb/test/API/functionalities/data-formatter/embedded-summary/main.c diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 938f6e3abe8f2a..1ca4aa62218c09 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -761,6 +761,7 @@ enum SectionType { eSectionTypeDWARFDebugLocListsDwo, eSectionTypeDWARFDebugTuIndex, eSectionTypeCTF, + eSectionTypeLLDBTypeSummaries, eSectionTypeSwiftModules, }; diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp index 0763e88d4608f4..ee01b4ce06ca1e 100644 --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -147,6 +147,8 @@ const char *Section::GetTypeAsCString() const { return "dwarf-gnu-debugaltlink"; case eSectionTypeCTF: return "ctf"; + case eSectionTypeLLDBTypeSummaries: +return "lldb-type-summaries"; case eSectionTypeOther: return "regular"; case eSectionTypeSwiftModules: @@ -457,6 +459,7 @@ bool Section::ContainsOnlyDebugInfo() const { case eSectionTypeDWARFAppleObjC: case eSectionTypeDWARFGNUDebugAltLink: case eSectionTypeCTF: + case eSectionTypeLLDBTypeSummaries: case eSectionTypeSwiftModules: return true; } diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 10d09662c0a47a..ad4a84ef02bf72 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1678,6 +1678,7 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) { .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) .Case(".gosymtab", eSectionTypeGoSymtab) .Case(".text", eSectionTypeCode) + .Case(".lldbsummaries", lldb::eSectionTypeLLDBTypeSummaries) .Case(".swift_ast", eSectionTypeSwiftModules) .Default(eSectionTypeOther); } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index b542e237f023d4..d6bec5d84aea19 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1209,6 +1209,7 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) { case eSectionTypeDWARFAppleObjC: case eSectionTypeDWARFGNUDebugAltLink: case eSectionTypeCTF: +case eSectionTypeLLDBTypeSummaries: case eSectionTypeSwiftModules: return AddressClass::eDebug; @@ -1484,6 +1485,7 @@ static lldb::SectionType GetSectionType(uint32_t flags, static ConstString g_sect_name_data("__data"); static ConstString g_sect_name_go_symtab("__gosymtab"); static ConstString g_sect_name_ctf("__ctf"); + static ConstString g_sect_name_lldb_summaries("__lldbsummaries"); static ConstString g_sect_name_swift_ast("__swift_ast"); if (section_name == g_sect_name_dwarf_debug_abbrev) @@ -1564,6 +1566,8 @@ static lldb::SectionType GetSectionType(uint32_t flags, return eSectionTypeGoSymtab; if (section_name == g_sect_name_ctf) return eSectionTypeCTF; + if (section_name == g_sect_name_lldb_summaries) +return lldb::eSectionTypeLLDBTypeSummar
[Lldb-commits] [lldb] [lldb] Load embedded type summary section (#7859) (#8040) (PR #113743)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Adrian Prantl (adrian-prantl) Changes Add support for type summaries embedded into the binary. These embedded summaries will typically be generated by Swift macros, but can also be generated by any other means. rdar://115184658 This upstreams the embedded type summary feature from the swiftlang branch of LLDB, since it shares a lot of the same goals and design points with https://github.com/llvm/llvm-project/pull/113398/ --- Full diff: https://github.com/llvm/llvm-project/pull/113743.diff 10 Files Affected: - (modified) lldb/include/lldb/lldb-enumerations.h (+1) - (modified) lldb/source/Core/Section.cpp (+3) - (modified) lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (+1) - (modified) lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (+4) - (modified) lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (+1) - (modified) lldb/source/Symbol/ObjectFile.cpp (+1) - (modified) lldb/source/Target/Target.cpp (+72) - (added) lldb/test/API/functionalities/data-formatter/embedded-summary/Makefile (+2) - (added) lldb/test/API/functionalities/data-formatter/embedded-summary/TestEmbeddedTypeSummary.py (+12) - (added) lldb/test/API/functionalities/data-formatter/embedded-summary/main.c (+22) ``diff diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 938f6e3abe8f2a..1ca4aa62218c09 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -761,6 +761,7 @@ enum SectionType { eSectionTypeDWARFDebugLocListsDwo, eSectionTypeDWARFDebugTuIndex, eSectionTypeCTF, + eSectionTypeLLDBTypeSummaries, eSectionTypeSwiftModules, }; diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp index 0763e88d4608f4..ee01b4ce06ca1e 100644 --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -147,6 +147,8 @@ const char *Section::GetTypeAsCString() const { return "dwarf-gnu-debugaltlink"; case eSectionTypeCTF: return "ctf"; + case eSectionTypeLLDBTypeSummaries: +return "lldb-type-summaries"; case eSectionTypeOther: return "regular"; case eSectionTypeSwiftModules: @@ -457,6 +459,7 @@ bool Section::ContainsOnlyDebugInfo() const { case eSectionTypeDWARFAppleObjC: case eSectionTypeDWARFGNUDebugAltLink: case eSectionTypeCTF: + case eSectionTypeLLDBTypeSummaries: case eSectionTypeSwiftModules: return true; } diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 10d09662c0a47a..ad4a84ef02bf72 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1678,6 +1678,7 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) { .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) .Case(".gosymtab", eSectionTypeGoSymtab) .Case(".text", eSectionTypeCode) + .Case(".lldbsummaries", lldb::eSectionTypeLLDBTypeSummaries) .Case(".swift_ast", eSectionTypeSwiftModules) .Default(eSectionTypeOther); } diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index b542e237f023d4..d6bec5d84aea19 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1209,6 +1209,7 @@ AddressClass ObjectFileMachO::GetAddressClass(lldb::addr_t file_addr) { case eSectionTypeDWARFAppleObjC: case eSectionTypeDWARFGNUDebugAltLink: case eSectionTypeCTF: +case eSectionTypeLLDBTypeSummaries: case eSectionTypeSwiftModules: return AddressClass::eDebug; @@ -1484,6 +1485,7 @@ static lldb::SectionType GetSectionType(uint32_t flags, static ConstString g_sect_name_data("__data"); static ConstString g_sect_name_go_symtab("__gosymtab"); static ConstString g_sect_name_ctf("__ctf"); + static ConstString g_sect_name_lldb_summaries("__lldbsummaries"); static ConstString g_sect_name_swift_ast("__swift_ast"); if (section_name == g_sect_name_dwarf_debug_abbrev) @@ -1564,6 +1566,8 @@ static lldb::SectionType GetSectionType(uint32_t flags, return eSectionTypeGoSymtab; if (section_name == g_sect_name_ctf) return eSectionTypeCTF; + if (section_name == g_sect_name_lldb_summaries) +return lldb::eSectionTypeLLDBTypeSummaries; if (section_name == g_sect_name_swift_ast) return eSectionTypeSwiftModules; if (section_name == g_sect_name_objc_data || diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp index 8d9c919bc9b101..bb712da7f6d67d 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp @@ -1010,6 +1010,7 @@
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,486 @@ +""" +Specification, compiler, disassembler, and interpreter +for LLDB dataformatter bytecode. + +See formatter-bytecode.md for more details. +""" +from __future__ import annotations + +# Types +type_String = 1 +type_Int = 2 +type_UInt = 3 +type_Object = 4 +type_Type = 5 + +# Opcodes +opcode = dict() + + +def define_opcode(n, mnemonic, name): +globals()["op_" + name] = n +if mnemonic: +opcode[mnemonic] = n +opcode[n] = mnemonic + + +define_opcode(1, "dup", "dup") +define_opcode(2, "drop", "drop") +define_opcode(3, "pick", "pick") +define_opcode(4, "over", "over") +define_opcode(5, "swap", "swap") +define_opcode(6, "rot", "rot") + +define_opcode(0x10, "{", "begin") +define_opcode(0x11, "if", "if") +define_opcode(0x12, "ifelse", "ifelse") + +define_opcode(0x20, None, "lit_uint") +define_opcode(0x21, None, "lit_int") +define_opcode(0x22, None, "lit_string") +define_opcode(0x23, None, "lit_selector") + +define_opcode(0x30, "+", "plus") +define_opcode(0x31, "-", "minus") +define_opcode(0x32, "*", "mul") +define_opcode(0x33, "/", "div") +define_opcode(0x34, "%", "mod") +define_opcode(0x35, "<<", "shl") +define_opcode(0x36, ">>", "shr") +define_opcode(0x37, "shra", "shra") + +define_opcode(0x40, "&", "and") +define_opcode(0x41, "|", "or") +define_opcode(0x42, "^", "xor") +define_opcode(0x43, "~", "not") + +define_opcode(0x50, "=", "eq") +define_opcode(0x51, "!=", "neq") +define_opcode(0x52, "<", "lt") +define_opcode(0x53, ">", "gt") +define_opcode(0x54, "=<", "le") +define_opcode(0x55, ">=", "ge") + +define_opcode(0x60, "call", "call") + +# Function signatures +sig_summary = 0 +sig_init = 1 +sig_get_num_children = 2 +sig_get_child_index = 3 +sig_get_child_at_index = 4 + +# Selectors +selector = dict() adrian-prantl wrote: I lifted the word _selector_ from Objective-C (https://en.wikipedia.org/wiki/Objective-C#Messages) to describe the concept of an identifier for a method. https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -318,6 +318,9 @@ class SymbolFileDWARF : public SymbolFileCommon { StatsDuration &GetDebugInfoParseTimeRef() { return m_parse_time; } + void ResetDebugInfoParseTime() override { m_parse_time.reset(); } + void ResetDebugInfoIndexTime() override; + clayborg wrote: Change to a a single function `ResetStatistics` https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
@@ -408,6 +408,9 @@ class SymbolFileDWARF : public SymbolFileCommon { bool ParseSupportFiles(DWARFUnit &dwarf_cu, const lldb::ModuleSP &module, SupportFileList &support_files); + lldb::VariableSP ParseStaticConstMemberDIE(const SymbolContext &sc, + const DWARFDIE &die); Michael137 wrote: Unused https://github.com/llvm/llvm-project/pull/111859 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
@@ -362,6 +369,23 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, set.namespaces.Insert(ConstString(name), ref); break; +case DW_TAG_member: { + // In DWARF 4 and earlier `static const` members of a struct, a class or a + // union have an entry tag `DW_TAG_member`, and are also tagged as + // `DW_AT_external` and `DW_AT_declaration`, but otherwise follow the + // same rules as `DW_TAG_variable`. + if (unit.GetVersion() >= 5) +break; + bool parent_is_class_type = false; + if (auto parent = die.GetParent()) { +parent_is_class_type = parent->Tag() == DW_TAG_structure_type || + parent->Tag() == DW_TAG_class_type || + parent->Tag() == DW_TAG_union_type; + } + if (!parent_is_class_type || !is_external || !is_declaration) Michael137 wrote: Wanted to note that we have this block here in `DWARFASTParserClang.cpp`: https://github.com/llvm/llvm-project/blob/d2e7ee77d33e8b3be3b1d4e9bc5bc4c60b62b554/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp#L2824-L2839 Which describes an edge-case with how GCC emits static data members (i.e., it doesn't consistently emit the `DW_AT_external` flag). Not sure we want to account for that, but also, it would be nice if we had a single place where we did the "isPreDWARFv5StaticDataMember` check. But feel free to ignore https://github.com/llvm/llvm-project/pull/111859 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
@@ -0,0 +1,12 @@ +class Vars { Michael137 wrote: Lets remove this new test given we adjusted the existing ones https://github.com/llvm/llvm-project/pull/111859 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
@@ -3490,7 +3490,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, ModuleSP module = GetObjectFile()->GetModule(); if (tag != DW_TAG_variable && tag != DW_TAG_constant && - (tag != DW_TAG_formal_parameter || !sc.function)) + tag != DW_TAG_member && (tag != DW_TAG_formal_parameter || !sc.function)) Michael137 wrote: Should we bail out (or at least assert) if we detect a `DW_AT_data_member_location`? Though I guess technically nothing should be calling `ParseVariableDIE` with such a DIE? https://github.com/llvm/llvm-project/pull/111859 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/111859 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Lookup static const members in FindGlobalVariables (PR #111859)
https://github.com/Michael137 edited https://github.com/llvm/llvm-project/pull/111859 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] Allow specifying libcxx builder image. (PR #110303)
Michael137 wrote: FYI, had to adjust the flag in one other place. Feel free to rebase the branch on `main`. I merged the changes https://github.com/llvm/llvm-project/pull/110303 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
https://github.com/jeffreytan81 created https://github.com/llvm/llvm-project/pull/113723 "statistics dump" currently report the statistics of all targets in debugger instead of current target. This is wrong because there is a "statistics dump --all-targets" option that supposed to include everything. This PR fixes the issue by only report statistics for current target instead of all. It also includes the change to reset statistics debug info/symbol table parsing/indexing time during debugger destroy. This is required so that we report current statistics if we plan to reuse lldb/lldb-dap across debug sessions >From 06d232c88fd85c9e60ac127730227dde81ec5a0d Mon Sep 17 00:00:00 2001 From: jeffreytan81 Date: Thu, 24 Oct 2024 17:14:55 -0700 Subject: [PATCH] Report statistics per target --- lldb/include/lldb/API/SBDebugger.h| 2 + lldb/include/lldb/Symbol/SymbolFile.h | 7 lldb/include/lldb/Symbol/SymbolFileOnDemand.h | 3 ++ lldb/include/lldb/Target/Statistics.h | 12 ++ lldb/source/API/SBDebugger.cpp| 6 +++ lldb/source/Core/Debugger.cpp | 1 + .../Plugins/SymbolFile/DWARF/DWARFIndex.h | 2 + .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 5 +++ .../SymbolFile/DWARF/SymbolFileDWARF.h| 3 ++ lldb/source/Symbol/SymbolFileOnDemand.cpp | 12 ++ lldb/source/Target/Statistics.cpp | 29 +- .../commands/statistics/basic/TestStats.py| 40 ++- .../API/commands/statistics/basic/second.cpp | 5 +++ 13 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 lldb/test/API/commands/statistics/basic/second.cpp diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 6afa1c932ab050..d80d609b3e7a28 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -426,6 +426,8 @@ class LLDB_API SBDebugger { SBTypeSynthetic GetSyntheticForType(SBTypeNameSpecifier); + void ResetStatistics(); + #ifndef SWIG /// Run the command interpreter. /// diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 8419495da73a22..7072d987e8b0ab 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -422,6 +422,13 @@ class SymbolFile : public PluginInterface { /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Reset the time taken to parse the debug information. + virtual void ResetDebugInfoParseTime() {} + + /// Reset the time it took to index the debug information in the object + /// file. + virtual void ResetDebugInfoIndexTime() {} + /// Get the additional modules that this symbol file uses to parse debug info. /// /// Some debug info is stored in stand alone object files that are represented diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h index 8073d1816860e3..12726e07c92e74 100644 --- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -182,6 +182,9 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile { lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + void ResetDebugInfoParseTime() override; + void ResetDebugInfoIndexTime() override; + uint32_t GetAbilities() override; Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); } diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h index f3414ae314f339..f1ba22508de432 100644 --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -41,6 +41,8 @@ class StatsDuration { } operator Duration() const { return get(); } + void reset() { value.store(0, std::memory_order_relaxed); } + StatsDuration &operator+=(Duration dur) { value.fetch_add(std::chrono::duration_cast(dur).count(), std::memory_order_relaxed); @@ -311,6 +313,16 @@ class DebuggerStats { ReportStatistics(Debugger &debugger, Target *target, const lldb_private::StatisticsOptions &options); + /// Reset metrics associated with one or all targets in a debugger. + /// + /// aram debugger + /// The debugger to reset the target list from if \a target is NULL. + /// + /// aram target + /// The target to reset statistics for, or if null, reset statistics + /// for all targets + static void ResetStatistics(Debugger &debugger, Target *target); + protected: // Collecting stats can be set to true to collect stats that are expensive // to collect. By default all stats that are cheap to collect are enabled. diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 47931f1c16f9a3..4efec747aacff1 100644
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
https://github.com/jeffreytan81 ready_for_review https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: None (jeffreytan81) Changes "statistics dump" currently report the statistics of all targets in debugger instead of current target. This is wrong because there is a "statistics dump --all-targets" option that supposed to include everything. This PR fixes the issue by only report statistics for current target instead of all. It also includes the change to reset statistics debug info/symbol table parsing/indexing time during debugger destroy. This is required so that we report current statistics if we plan to reuse lldb/lldb-dap across debug sessions --- Full diff: https://github.com/llvm/llvm-project/pull/113723.diff 13 Files Affected: - (modified) lldb/include/lldb/API/SBDebugger.h (+2) - (modified) lldb/include/lldb/Symbol/SymbolFile.h (+7) - (modified) lldb/include/lldb/Symbol/SymbolFileOnDemand.h (+3) - (modified) lldb/include/lldb/Target/Statistics.h (+12) - (modified) lldb/source/API/SBDebugger.cpp (+6) - (modified) lldb/source/Core/Debugger.cpp (+1) - (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h (+2) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (+5) - (modified) lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (+3) - (modified) lldb/source/Symbol/SymbolFileOnDemand.cpp (+12) - (modified) lldb/source/Target/Statistics.cpp (+27-2) - (modified) lldb/test/API/commands/statistics/basic/TestStats.py (+38-2) - (added) lldb/test/API/commands/statistics/basic/second.cpp (+5) ``diff diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 6afa1c932ab050..d80d609b3e7a28 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -426,6 +426,8 @@ class LLDB_API SBDebugger { SBTypeSynthetic GetSyntheticForType(SBTypeNameSpecifier); + void ResetStatistics(); + #ifndef SWIG /// Run the command interpreter. /// diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 8419495da73a22..7072d987e8b0ab 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -422,6 +422,13 @@ class SymbolFile : public PluginInterface { /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Reset the time taken to parse the debug information. + virtual void ResetDebugInfoParseTime() {} + + /// Reset the time it took to index the debug information in the object + /// file. + virtual void ResetDebugInfoIndexTime() {} + /// Get the additional modules that this symbol file uses to parse debug info. /// /// Some debug info is stored in stand alone object files that are represented diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h index 8073d1816860e3..12726e07c92e74 100644 --- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -182,6 +182,9 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile { lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + void ResetDebugInfoParseTime() override; + void ResetDebugInfoIndexTime() override; + uint32_t GetAbilities() override; Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); } diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h index f3414ae314f339..91a3ffb5bfa3d3 100644 --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -41,6 +41,8 @@ class StatsDuration { } operator Duration() const { return get(); } + void reset() { value.store(0, std::memory_order_relaxed); } + StatsDuration &operator+=(Duration dur) { value.fetch_add(std::chrono::duration_cast(dur).count(), std::memory_order_relaxed); @@ -311,6 +313,16 @@ class DebuggerStats { ReportStatistics(Debugger &debugger, Target *target, const lldb_private::StatisticsOptions &options); + /// Reset metrics associated with one or all targets in a debugger. + /// + /// \param debugger + /// The debugger to reset the target list from if \a target is NULL. + /// + /// \param target + /// The target to reset statistics for, or if null, reset statistics + /// for all targets + static void ResetStatistics(Debugger &debugger, Target *target); + protected: // Collecting stats can be set to true to collect stats that are expensive // to collect. By default all stats that are cheap to collect are enabled. diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 47931f1c16f9a3..4efec747aacff1 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -1667,6 +1667,12 @@ SBTypeSynthetic SBDebugger::GetSyntheticForT
[Lldb-commits] [lldb] [llvm] [lldb] Fix write only file action to truncate the file (PR #112657)
@@ -6,6 +6,8 @@ // //===--===// +#include bulbazord wrote: Will this work on windows? https://github.com/llvm/llvm-project/pull/112657 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb] Fix write only file action to truncate the file (PR #112657)
@@ -6,6 +6,8 @@ // //===--===// +#include kusmour wrote: Good question, from the code search it seems a lot of base classes have that #include. I don't have a windows machine to test with but I doubt this will break windows. eg. https://github.com/llvm/llvm-project/blob/main/lldb/source/Host/common/File.cpp#L15-L19 https://github.com/llvm/llvm-project/pull/112657 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Avoid repeated hash lookups (NFC) (PR #113412)
https://github.com/bulbazord approved this pull request. https://github.com/llvm/llvm-project/pull/113412 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` kastiglione wrote: ```suggestion - `over (x y -> x y x)` ``` https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Proof of concept data formatter compiler for Python (PR #113734)
https://github.com/kastiglione created https://github.com/llvm/llvm-project/pull/113734 None >From 57223942e91c47d0a61b148a65247cd9cbb16496 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Fri, 25 Oct 2024 12:56:00 -0700 Subject: [PATCH] [lldb] Proof of concept data formatter compiler for Python --- .../formatter-bytecode/optional_summary.py| 14 ++ .../formatter-bytecode/python_to_assembly.py | 145 ++ 2 files changed, 159 insertions(+) create mode 100644 lldb/examples/formatter-bytecode/optional_summary.py create mode 100755 lldb/examples/formatter-bytecode/python_to_assembly.py diff --git a/lldb/examples/formatter-bytecode/optional_summary.py b/lldb/examples/formatter-bytecode/optional_summary.py new file mode 100644 index 00..68e672d86613d1 --- /dev/null +++ b/lldb/examples/formatter-bytecode/optional_summary.py @@ -0,0 +1,14 @@ +def OptionalSummaryProvider(valobj, _): +failure = 2 +storage = valobj.GetChildMemberWithName("Storage") +hasVal = storage.GetChildMemberWithName("hasVal").GetValueAsUnsigned(failure) +if hasVal == failure: +return "" + +if hasVal == 0: +return "None" + +underlying_type = storage.GetType().GetTemplateArgumentType(0) +value = storage.GetChildMemberWithName("value") +value = value.Cast(underlying_type) +return value.GetSummary() diff --git a/lldb/examples/formatter-bytecode/python_to_assembly.py b/lldb/examples/formatter-bytecode/python_to_assembly.py new file mode 100755 index 00..6e2adbe093fdac --- /dev/null +++ b/lldb/examples/formatter-bytecode/python_to_assembly.py @@ -0,0 +1,145 @@ +#!/usr/bin/python3 + +import ast +import io +import sys +from typing import Any + +BUILTINS = { +"Cast": "@cast", +"GetChildMemberWithName": "@get_child_with_name", +"GetSummary": "@get_summary", +"GetTemplateArgumentType": "@get_template_argument_type", +"GetType": "@get_type", +"GetValueAsUnsigned": "@get_value_as_unsigned", +} + +COMPS = { +ast.Eq: "=", +ast.NotEq: "!=", +ast.Lt: "<", +ast.LtE: "=<", +ast.Gt: ">", +ast.GtE: "=>", +} + +class Compiler(ast.NodeVisitor): +# Track the stack index of locals variables. +# +# This is essentially an ordered dictionary, where the key is an index on +# the stack, and the value is the name of the variable whose value is at +# that index. +# +# Ex: `locals[0]` is the name of the first value pushed on the stack, etc. +locals: list[str] + +buffer: io.StringIO +final_buffer: io.StringIO + +def __init__(self) -> None: +self.locals = [] +self.buffer = io.StringIO() +self.final_buffer = io.StringIO() + +def visit_FunctionDef(self, node: ast.FunctionDef) -> None: +# Initialize `locals` with the (positional) arguments. +self.locals = [arg.arg for arg in node.args.args] +self.generic_visit(node) +self.locals.clear() + +def visit_Compare(self, node: ast.Compare) -> None: +self.visit(node.left) +# XXX: Does not handle multiple comparisons, ex: `0 < x < 10` +self.visit(node.comparators[0]) +self._output(COMPS[type(node.ops[0])]) + +def visit_If(self, node: ast.If) -> None: +self.visit(node.test) + +# Does the body `return`? +has_return = any(isinstance(x, ast.Return) for x in node.body) + +self._output("{") +self._visit_each(node.body) +if not node.orelse and not has_return: +# No else, and no early exit: a simple `if` +self._output("} if") +return + +self._output("}") +if node.orelse: +# Handle else. +self._output("{") +self._visit_each(node.orelse) +self._output("} ifelse") +elif has_return: +# Convert early exit into an `ifelse`. +self._output("{") +self._output("} ifelse", final=True) + +def visit_Constant(self, node: ast.Constant) -> None: +if isinstance(node.value, str): +self._output(f'"{node.value}"') +elif isinstance(node.value, bool): +self._output(int(node.value)) +else: +self._output(node.value) + +def visit_Call(self, node: ast.Call) -> None: +if isinstance(node.func, ast.Attribute): +# The receiver is the left hande side of the dot. +receiver = node.func.value +method = node.func.attr +if selector := BUILTINS.get(method): +# Visit the method's receiver to have its value on the stack. +self.visit(receiver) +# Visit the args to position them on the stack. +self._visit_each(node.args) +self._output(f"{selector} call") +else: +# TODO: fail +print(f"error: unsupported method {node.func.attr}", file=sys.stderr) + +def visit_As
[Lldb-commits] [lldb] [lldb] Proof of concept data formatter compiler for Python (PR #113734)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r eb9f4756bc3daaa4b19f4f46521dc05180814de4...57223942e91c47d0a61b148a65247cd9cbb16496 lldb/examples/formatter-bytecode/optional_summary.py lldb/examples/formatter-bytecode/python_to_assembly.py `` View the diff from darker here. ``diff --- python_to_assembly.py 2024-10-25 19:56:12.00 + +++ python_to_assembly.py 2024-10-25 19:59:11.920862 + @@ -20,10 +20,11 @@ ast.Lt: "<", ast.LtE: "=<", ast.Gt: ">", ast.GtE: "=>", } + class Compiler(ast.NodeVisitor): # Track the stack index of locals variables. # # This is essentially an ordered dictionary, where the key is an index on `` https://github.com/llvm/llvm-project/pull/113734 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Proof of concept data formatter compiler for Python (PR #113734)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Dave Lee (kastiglione) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/113734.diff 2 Files Affected: - (added) lldb/examples/formatter-bytecode/optional_summary.py (+14) - (added) lldb/examples/formatter-bytecode/python_to_assembly.py (+145) ``diff diff --git a/lldb/examples/formatter-bytecode/optional_summary.py b/lldb/examples/formatter-bytecode/optional_summary.py new file mode 100644 index 00..68e672d86613d1 --- /dev/null +++ b/lldb/examples/formatter-bytecode/optional_summary.py @@ -0,0 +1,14 @@ +def OptionalSummaryProvider(valobj, _): +failure = 2 +storage = valobj.GetChildMemberWithName("Storage") +hasVal = storage.GetChildMemberWithName("hasVal").GetValueAsUnsigned(failure) +if hasVal == failure: +return "" + +if hasVal == 0: +return "None" + +underlying_type = storage.GetType().GetTemplateArgumentType(0) +value = storage.GetChildMemberWithName("value") +value = value.Cast(underlying_type) +return value.GetSummary() diff --git a/lldb/examples/formatter-bytecode/python_to_assembly.py b/lldb/examples/formatter-bytecode/python_to_assembly.py new file mode 100755 index 00..6e2adbe093fdac --- /dev/null +++ b/lldb/examples/formatter-bytecode/python_to_assembly.py @@ -0,0 +1,145 @@ +#!/usr/bin/python3 + +import ast +import io +import sys +from typing import Any + +BUILTINS = { +"Cast": "@cast", +"GetChildMemberWithName": "@get_child_with_name", +"GetSummary": "@get_summary", +"GetTemplateArgumentType": "@get_template_argument_type", +"GetType": "@get_type", +"GetValueAsUnsigned": "@get_value_as_unsigned", +} + +COMPS = { +ast.Eq: "=", +ast.NotEq: "!=", +ast.Lt: "<", +ast.LtE: "=<", +ast.Gt: ">", +ast.GtE: "=>", +} + +class Compiler(ast.NodeVisitor): +# Track the stack index of locals variables. +# +# This is essentially an ordered dictionary, where the key is an index on +# the stack, and the value is the name of the variable whose value is at +# that index. +# +# Ex: `locals[0]` is the name of the first value pushed on the stack, etc. +locals: list[str] + +buffer: io.StringIO +final_buffer: io.StringIO + +def __init__(self) -> None: +self.locals = [] +self.buffer = io.StringIO() +self.final_buffer = io.StringIO() + +def visit_FunctionDef(self, node: ast.FunctionDef) -> None: +# Initialize `locals` with the (positional) arguments. +self.locals = [arg.arg for arg in node.args.args] +self.generic_visit(node) +self.locals.clear() + +def visit_Compare(self, node: ast.Compare) -> None: +self.visit(node.left) +# XXX: Does not handle multiple comparisons, ex: `0 < x < 10` +self.visit(node.comparators[0]) +self._output(COMPS[type(node.ops[0])]) + +def visit_If(self, node: ast.If) -> None: +self.visit(node.test) + +# Does the body `return`? +has_return = any(isinstance(x, ast.Return) for x in node.body) + +self._output("{") +self._visit_each(node.body) +if not node.orelse and not has_return: +# No else, and no early exit: a simple `if` +self._output("} if") +return + +self._output("}") +if node.orelse: +# Handle else. +self._output("{") +self._visit_each(node.orelse) +self._output("} ifelse") +elif has_return: +# Convert early exit into an `ifelse`. +self._output("{") +self._output("} ifelse", final=True) + +def visit_Constant(self, node: ast.Constant) -> None: +if isinstance(node.value, str): +self._output(f'"{node.value}"') +elif isinstance(node.value, bool): +self._output(int(node.value)) +else: +self._output(node.value) + +def visit_Call(self, node: ast.Call) -> None: +if isinstance(node.func, ast.Attribute): +# The receiver is the left hande side of the dot. +receiver = node.func.value +method = node.func.attr +if selector := BUILTINS.get(method): +# Visit the method's receiver to have its value on the stack. +self.visit(receiver) +# Visit the args to position them on the stack. +self._visit_each(node.args) +self._output(f"{selector} call") +else: +# TODO: fail +print(f"error: unsupported method {node.func.attr}", file=sys.stderr) + +def visit_Assign(self, node: ast.Assign) -> None: +# Visit RHS first, putting values on the stack. +self.visit(node.value) +# Determine the name(s). Either a single Name, or a Tuple of Names. +target = node.targets[0] +if isinstance(target, ast.Nam
[Lldb-commits] [lldb] [lldb] Proof of concept data formatter compiler for Python (PR #113734)
https://github.com/kastiglione converted_to_draft https://github.com/llvm/llvm-project/pull/113734 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
https://github.com/jeffreytan81 updated https://github.com/llvm/llvm-project/pull/113723 >From debd58ec81a8c245475531c990e969b39770bc1e Mon Sep 17 00:00:00 2001 From: jeffreytan81 Date: Thu, 24 Oct 2024 17:14:55 -0700 Subject: [PATCH] Report statistics per target --- lldb/include/lldb/API/SBDebugger.h| 2 + lldb/include/lldb/Symbol/SymbolFile.h | 7 lldb/include/lldb/Symbol/SymbolFileOnDemand.h | 3 ++ lldb/include/lldb/Target/Statistics.h | 12 ++ lldb/source/API/SBDebugger.cpp| 6 +++ lldb/source/Core/Debugger.cpp | 1 + .../Plugins/SymbolFile/DWARF/DWARFIndex.h | 2 + .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 5 +++ .../SymbolFile/DWARF/SymbolFileDWARF.h| 3 ++ lldb/source/Symbol/SymbolFileOnDemand.cpp | 12 ++ lldb/source/Target/Statistics.cpp | 29 +- .../commands/statistics/basic/TestStats.py| 40 ++- .../API/commands/statistics/basic/second.cpp | 5 +++ 13 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 lldb/test/API/commands/statistics/basic/second.cpp diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 6afa1c932ab050..d80d609b3e7a28 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -426,6 +426,8 @@ class LLDB_API SBDebugger { SBTypeSynthetic GetSyntheticForType(SBTypeNameSpecifier); + void ResetStatistics(); + #ifndef SWIG /// Run the command interpreter. /// diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 8419495da73a22..7072d987e8b0ab 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -422,6 +422,13 @@ class SymbolFile : public PluginInterface { /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Reset the time taken to parse the debug information. + virtual void ResetDebugInfoParseTime() {} + + /// Reset the time it took to index the debug information in the object + /// file. + virtual void ResetDebugInfoIndexTime() {} + /// Get the additional modules that this symbol file uses to parse debug info. /// /// Some debug info is stored in stand alone object files that are represented diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h index 8073d1816860e3..12726e07c92e74 100644 --- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -182,6 +182,9 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile { lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + void ResetDebugInfoParseTime() override; + void ResetDebugInfoIndexTime() override; + uint32_t GetAbilities() override; Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); } diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h index f3414ae314f339..91a3ffb5bfa3d3 100644 --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -41,6 +41,8 @@ class StatsDuration { } operator Duration() const { return get(); } + void reset() { value.store(0, std::memory_order_relaxed); } + StatsDuration &operator+=(Duration dur) { value.fetch_add(std::chrono::duration_cast(dur).count(), std::memory_order_relaxed); @@ -311,6 +313,16 @@ class DebuggerStats { ReportStatistics(Debugger &debugger, Target *target, const lldb_private::StatisticsOptions &options); + /// Reset metrics associated with one or all targets in a debugger. + /// + /// \param debugger + /// The debugger to reset the target list from if \a target is NULL. + /// + /// \param target + /// The target to reset statistics for, or if null, reset statistics + /// for all targets + static void ResetStatistics(Debugger &debugger, Target *target); + protected: // Collecting stats can be set to true to collect stats that are expensive // to collect. By default all stats that are cheap to collect are enabled. diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp index 47931f1c16f9a3..4efec747aacff1 100644 --- a/lldb/source/API/SBDebugger.cpp +++ b/lldb/source/API/SBDebugger.cpp @@ -1667,6 +1667,12 @@ SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) { DataVisualization::GetSyntheticForType(type_name.GetSP())); } +void SBDebugger::ResetStatistics() { + LLDB_INSTRUMENT_VA(this); + if (m_opaque_sp) +DebuggerStats::ResetStatistics(*m_opaque_sp, nullptr); +} + static llvm::ArrayRef GetCategoryArray(const char **categories) { if (categories == nullptr) return {}; diff --git a/lld
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,165 @@ +# A bytecode for (LLDB) data formatters + +## Background + +LLDB provides very rich customization options to display data types (see https://lldb.llvm.org/use/variable.html ). To use custom data formatters, developers typically need to edit the global `~/.lldbinit` file to make sure they are found and loaded. An example for this workflow is the `llvm/utils/lldbDataFormatters.py` script. Because of the manual configuration that is involved, this workflow doesn't scale very well. What would be nice is if developers or library authors could ship ship data formatters with their code and LLDB automatically finds them. + +In Swift we added the `DebugDescription` macro (see https://www.swift.org/blog/announcing-swift-6/#debugging ) that translates Swift string interpolation into LLDB summary strings, and puts them into a `.lldbsummaries` section, where LLDB can find them. This works well for simple summaries, but doesn't scale to synthetic child providers or summaries that need to perform some kind of conditional logic or computation. The logical next step would be to store full Python formatters instead of summary strings, but Python code is larger and more importantly it is potentially dangerous to just load an execute untrusted Python code in LLDB. + +This document describes a minimal bytecode tailored to running LLDB formatters. It defines a human-readable assembler representation for the language, an efficient binary encoding, a virtual machine for evaluating it, and format for embedding formatters into binary containers. + +### Goals + +Provide an efficient and secure encoding for data formatters that can be used as a compilation target from user-friendly representations (such as DIL, Swift DebugDescription, or NatVis). + +### Non-goals + +While humans could write the assembler syntax, making it user-friendly is not a goal. + +## Design of the virtual machine + +The LLDB formatter virtual machine uses a stack-based bytecode, comparable with DWARF expressions, but with higher-level data types and functions. + +The virtual machine has two stacks, a data and a control stack. The control stack is kept separate to make it easier to reason about the security aspects of the VM. + +### Data types +These data types are "host" data types, in LLDB parlance. +- _String_ (UTF-8) +- _Int_ (64 bit) +- _UInt_ (64 bit) +- _Object_ (Basically an `SBValue`) +- _Type_ (Basically an `SBType`) +- _Selector_ (One of the predefine functions) + +_Object_ and _Type_ are opaque, they can only be used as a parameters of `call`. + +## Instruction set + +### Stack operations + +These manipulate the data stack directly. + +- `dup (x -> x x)` +- `drop (x y -> x)` +- `pick (x ... UInt -> x ... x)` +- `over (x y -> y)` +- `swap (x y -> y x)` +- `rot (x y z -> z x y)` + +### Control flow + +- `{` pushes a code block address onto the control stack +- `}` (technically not an opcode) denotes the end of a code block +- `if` pops a block from the control stack, if the top of the data stack is nonzero, executes it +- `ifelse` pops two blocks from the control stack, if the top of the data stack is nonzero, executes the first, otherwise the second. + +### Literals for basic types + +- `123u ( -> UInt)` an unsigned 64-bit host integer. +- `123 ( -> Int)` a signed 64-bit host integer. +- `"abc" ( -> String)` a UTF-8 host string. +- `@strlen ( -> Selector)` one of the predefined functions supported by the VM. + +### Arithmetic, logic, and comparison operations +- `+ (x y -> [x+y])` +- `-` etc ... +- `*` +- `/` +- `%` +- `<<` +- `>>` +- `shra` (arithmetic shift right) +- `~` +- `|` +- `^` +- `=` +- `!=` +- `<` +- `>` +- `=<` +- `>=` + +### Function calls + +For security reasons the list of functions callable with `call` is predefined. The supported functions are either existing methods on `SBValue`, or string formatting operations. + +- `call (Object arg0 ... Selector -> retval)` + +Method is one of a predefined set of _Selectors_ +- `(Object @summary -> String)` +- `(Object @type_summary -> String)` + +- `(Object @get_num_children -> UInt)` +- `(Object UInt @get_child_at_index -> Object)` +- `(Object String @get_child_index -> UInt)` +- `(Object @get_type -> Type)` +- `(Object UInt @get_template_argument_type -> Type)` +- `(Object @get_value -> Object)` +- `(Object @get_value_as_unsigned -> UInt)` +- `(Object @get_value_as_signed -> Int)` +- `(Object @get_value_as_address -> UInt)` +- `(Object Type @cast -> Object)` + +- `(UInt @read_memory_byte -> UInt)` +- `(UInt @read_memory_uint32 -> UInt)` +- `(UInt @read_memory_int32 -> Int)` +- `(UInt @read_memory_unsigned -> UInt)` +- `(UInt @read_memory_signed -> Int)` +- `(UInt @read_memory_address -> UInt)` +- `(UInt Type @read_memory -> Object)` + +- `(String arg0 ... fmt -> String)` +- `(String arg0 ... sprintf -> String)` +- `(String strlen -> String)` + +## Byte Code + +Most instructions are just a single byte opcode. The only exceptions
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
https://github.com/clayborg requested changes to this pull request. https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,486 @@ +""" +Specification, compiler, disassembler, and interpreter +for LLDB dataformatter bytecode. + +See formatter-bytecode.md for more details. +""" +from __future__ import annotations + +# Types +type_String = 1 +type_Int = 2 +type_UInt = 3 +type_Object = 4 +type_Type = 5 + +# Opcodes +opcode = dict() + + +def define_opcode(n, mnemonic, name): +globals()["op_" + name] = n +if mnemonic: +opcode[mnemonic] = n +opcode[n] = mnemonic + + +define_opcode(1, "dup", "dup") +define_opcode(2, "drop", "drop") +define_opcode(3, "pick", "pick") +define_opcode(4, "over", "over") +define_opcode(5, "swap", "swap") +define_opcode(6, "rot", "rot") + +define_opcode(0x10, "{", "begin") +define_opcode(0x11, "if", "if") +define_opcode(0x12, "ifelse", "ifelse") + +define_opcode(0x20, None, "lit_uint") +define_opcode(0x21, None, "lit_int") +define_opcode(0x22, None, "lit_string") +define_opcode(0x23, None, "lit_selector") + +define_opcode(0x30, "+", "plus") +define_opcode(0x31, "-", "minus") +define_opcode(0x32, "*", "mul") +define_opcode(0x33, "/", "div") +define_opcode(0x34, "%", "mod") +define_opcode(0x35, "<<", "shl") +define_opcode(0x36, ">>", "shr") +define_opcode(0x37, "shra", "shra") + +define_opcode(0x40, "&", "and") +define_opcode(0x41, "|", "or") +define_opcode(0x42, "^", "xor") +define_opcode(0x43, "~", "not") + +define_opcode(0x50, "=", "eq") +define_opcode(0x51, "!=", "neq") +define_opcode(0x52, "<", "lt") +define_opcode(0x53, ">", "gt") +define_opcode(0x54, "=<", "le") +define_opcode(0x55, ">=", "ge") adrian-prantl wrote: Yeah I would say the priorities are roughly: 1. Safety of bytecode (e.g., `{` having an explicit hardcoded length, separate control stack) 2. Size of bytecode 3. Ergonomics of assembler for compiler writers 4. Ergonomics of assembler for humans https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add a compiler/interpreter of LLDB data formatter bytecode to lldb/examples (PR #113398)
@@ -0,0 +1,486 @@ +""" +Specification, compiler, disassembler, and interpreter +for LLDB dataformatter bytecode. + +See formatter-bytecode.md for more details. +""" +from __future__ import annotations + +# Types +type_String = 1 +type_Int = 2 +type_UInt = 3 +type_Object = 4 +type_Type = 5 + +# Opcodes +opcode = dict() + + +def define_opcode(n, mnemonic, name): +globals()["op_" + name] = n +if mnemonic: +opcode[mnemonic] = n +opcode[n] = mnemonic + + +define_opcode(1, "dup", "dup") +define_opcode(2, "drop", "drop") +define_opcode(3, "pick", "pick") +define_opcode(4, "over", "over") +define_opcode(5, "swap", "swap") +define_opcode(6, "rot", "rot") + +define_opcode(0x10, "{", "begin") +define_opcode(0x11, "if", "if") +define_opcode(0x12, "ifelse", "ifelse") + +define_opcode(0x20, None, "lit_uint") +define_opcode(0x21, None, "lit_int") +define_opcode(0x22, None, "lit_string") +define_opcode(0x23, None, "lit_selector") + +define_opcode(0x30, "+", "plus") +define_opcode(0x31, "-", "minus") +define_opcode(0x32, "*", "mul") +define_opcode(0x33, "/", "div") +define_opcode(0x34, "%", "mod") +define_opcode(0x35, "<<", "shl") +define_opcode(0x36, ">>", "shr") +define_opcode(0x37, "shra", "shra") + +define_opcode(0x40, "&", "and") +define_opcode(0x41, "|", "or") +define_opcode(0x42, "^", "xor") +define_opcode(0x43, "~", "not") + +define_opcode(0x50, "=", "eq") +define_opcode(0x51, "!=", "neq") +define_opcode(0x52, "<", "lt") +define_opcode(0x53, ">", "gt") +define_opcode(0x54, "=<", "le") +define_opcode(0x55, ">=", "ge") + +define_opcode(0x60, "call", "call") + +# Function signatures +sig_summary = 0 +sig_init = 1 +sig_get_num_children = 2 +sig_get_child_index = 3 +sig_get_child_at_index = 4 + +# Selectors +selector = dict() adrian-prantl wrote: It's an (intentionally!) hardcoded list of functions the program can call. ``` argn ... arg1 arg0 @selector call ``` behaves like the equivalent C code ``` selector(arg0, arg1, ... argn) ``` And in the cases of the ValueObj methods arg0 is the implicit `this` argument. https://github.com/llvm/llvm-project/pull/113398 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -555,6 +555,18 @@ StatsDuration::Duration SymbolFileOnDemand::GetDebugInfoIndexTime() { return m_sym_file_impl->GetDebugInfoIndexTime(); } +void SymbolFileOnDemand::ResetDebugInfoParseTime() { + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(), + __FUNCTION__); + return m_sym_file_impl->ResetDebugInfoParseTime(); +} + +void SymbolFileOnDemand::ResetDebugInfoIndexTime() { + LLDB_LOG(GetLog(), "[{0}] {1} is not skipped", GetSymbolFileName(), + __FUNCTION__); + return m_sym_file_impl->ResetDebugInfoIndexTime(); +} + jeffreytan81 wrote: "is not skipped" is correct -- it means this API call `ResetStatistics` is not skipped by SymbolFileOnDemand class and pass through to the underlying real symbol file. https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -236,6 +236,27 @@ void TargetStats::IncreaseSourceRealpathCompatibleCount(uint32_t count) { bool DebuggerStats::g_collecting_stats = false; +void DebuggerStats::ResetStatistics(Debugger &debugger, Target *target) { + const uint64_t num_modules = target != nullptr + ? target->GetImages().GetSize() + : Module::GetNumberAllocatedModules(); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { +Module *module = target != nullptr + ? target->GetImages().GetModuleAtIndex(image_idx).get() + : Module::GetAllocatedModuleAtIndex(image_idx); +if (module == nullptr) + continue; +ModuleStats module_stat; +module->GetSymtabParseTime().reset(); +module->GetSymtabIndexTime().reset(); +SymbolFile *sym_file = module->GetSymbolFile(); +if (sym_file) { + sym_file->ResetDebugInfoIndexTime(); + sym_file->ResetDebugInfoParseTime(); +} clayborg wrote: This should be done in `Module::ResetStatistics()` https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -422,6 +422,13 @@ class SymbolFile : public PluginInterface { /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Reset the time taken to parse the debug information. + virtual void ResetDebugInfoParseTime() {} clayborg wrote: Change to a single function `virtual void ResetStatistics();` https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] ccc15cd - [lldb] Avoid repeated hash lookups (NFC) (#113412)
Author: Kazu Hirata Date: 2024-10-25T15:35:01-07:00 New Revision: ccc15cd6f52922e83164b44e927870059c168ddf URL: https://github.com/llvm/llvm-project/commit/ccc15cd6f52922e83164b44e927870059c168ddf DIFF: https://github.com/llvm/llvm-project/commit/ccc15cd6f52922e83164b44e927870059c168ddf.diff LOG: [lldb] Avoid repeated hash lookups (NFC) (#113412) Added: Modified: lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp Removed: diff --git a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 49edd40544e32a..1a680d80a9d3d7 100644 --- a/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -461,8 +461,7 @@ size_t UnwindAssemblyInstEmulation::WriteMemory( if (reg_num != LLDB_INVALID_REGNUM && generic_regnum != LLDB_REGNUM_GENERIC_SP) { - if (m_pushed_regs.find(reg_num) == m_pushed_regs.end()) { -m_pushed_regs[reg_num] = addr; + if (m_pushed_regs.try_emplace(reg_num, addr).second) { const int32_t offset = addr - m_initial_sp; m_curr_row->SetRegisterLocationToAtCFAPlusOffset(reg_num, offset, /*can_replace=*/true); @@ -608,8 +607,8 @@ bool UnwindAssemblyInstEmulation::WriteRegister( generic_regnum != LLDB_REGNUM_GENERIC_SP) { switch (context.GetInfoType()) { case EmulateInstruction::eInfoTypeAddress: -if (m_pushed_regs.find(reg_num) != m_pushed_regs.end() && -context.info.address == m_pushed_regs[reg_num]) { +if (auto it = m_pushed_regs.find(reg_num); +it != m_pushed_regs.end() && context.info.address == it->second) { m_curr_row->SetRegisterLocationToSame(reg_num, false /*must_replace*/); m_curr_row_modified = true; ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Avoid repeated hash lookups (NFC) (PR #113412)
https://github.com/kazutakahirata closed https://github.com/llvm/llvm-project/pull/113412 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
https://github.com/jeffreytan81 updated https://github.com/llvm/llvm-project/pull/113723 >From abf234c1009b23b000a2b39684fb888084cf5e8c Mon Sep 17 00:00:00 2001 From: jeffreytan81 Date: Thu, 24 Oct 2024 17:14:55 -0700 Subject: [PATCH] Report statistics per target --- lldb/include/lldb/API/SBDebugger.h| 2 + lldb/include/lldb/API/SBTarget.h | 3 ++ lldb/include/lldb/Core/Module.h | 2 + lldb/include/lldb/Symbol/SymbolFile.h | 3 ++ lldb/include/lldb/Symbol/SymbolFileOnDemand.h | 2 + lldb/include/lldb/Target/Statistics.h | 12 ++ lldb/source/API/SBDebugger.cpp| 6 +++ lldb/source/API/SBTarget.cpp | 7 lldb/source/Core/Module.cpp | 9 + .../Plugins/SymbolFile/DWARF/DWARFIndex.h | 2 + .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 6 +++ .../SymbolFile/DWARF/SymbolFileDWARF.h| 2 + lldb/source/Symbol/SymbolFileOnDemand.cpp | 6 +++ lldb/source/Target/Statistics.cpp | 24 ++- .../commands/statistics/basic/TestStats.py| 40 ++- .../API/commands/statistics/basic/second.cpp | 5 +++ 16 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 lldb/test/API/commands/statistics/basic/second.cpp diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index 6afa1c932ab050..d80d609b3e7a28 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -426,6 +426,8 @@ class LLDB_API SBDebugger { SBTypeSynthetic GetSyntheticForType(SBTypeNameSpecifier); + void ResetStatistics(); + #ifndef SWIG /// Run the command interpreter. /// diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h index 35c2ed9c20a238..2e4392990bc4a8 100644 --- a/lldb/include/lldb/API/SBTarget.h +++ b/lldb/include/lldb/API/SBTarget.h @@ -101,6 +101,9 @@ class LLDB_API SBTarget { /// A SBStructuredData with the statistics collected. lldb::SBStructuredData GetStatistics(SBStatisticsOptions options); + /// Reset the statistics collected for this target. + void ResetStatistics(); + /// Return the platform object associated with the target. /// /// After return, the platform object should be checked for diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h index 5589c1c9a350dc..9170aca3ed7283 100644 --- a/lldb/include/lldb/Core/Module.h +++ b/lldb/include/lldb/Core/Module.h @@ -880,6 +880,8 @@ class Module : public std::enable_shared_from_this, /// ElapsedTime RAII object. StatsDuration &GetSymtabIndexTime() { return m_symtab_index_time; } + void ResetStatistics(); + /// \class LookupInfo Module.h "lldb/Core/Module.h" /// A class that encapsulates name lookup information. /// diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 8419495da73a22..837b922ae77f75 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -422,6 +422,9 @@ class SymbolFile : public PluginInterface { /// hasn't been indexed yet, or a valid duration if it has. virtual StatsDuration::Duration GetDebugInfoIndexTime() { return {}; } + /// Reset the statistics for the symbol file. + virtual void ResetStatistics() {} + /// Get the additional modules that this symbol file uses to parse debug info. /// /// Some debug info is stored in stand alone object files that are represented diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h index 8073d1816860e3..7a366bfabec865 100644 --- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h +++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h @@ -182,6 +182,8 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile { lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + void ResetStatistics() override; + uint32_t GetAbilities() override; Symtab *GetSymtab() override { return m_sym_file_impl->GetSymtab(); } diff --git a/lldb/include/lldb/Target/Statistics.h b/lldb/include/lldb/Target/Statistics.h index f3414ae314f339..91a3ffb5bfa3d3 100644 --- a/lldb/include/lldb/Target/Statistics.h +++ b/lldb/include/lldb/Target/Statistics.h @@ -41,6 +41,8 @@ class StatsDuration { } operator Duration() const { return get(); } + void reset() { value.store(0, std::memory_order_relaxed); } + StatsDuration &operator+=(Duration dur) { value.fetch_add(std::chrono::duration_cast(dur).count(), std::memory_order_relaxed); @@ -311,6 +313,16 @@ class DebuggerStats { ReportStatistics(Debugger &debugger, Target *target, const lldb_private::StatisticsOptions &options); + /// Reset metrics associated with one or all targets in a debugger. + /// + /// \param debugger + /// The deb
[Lldb-commits] [lldb] Fix statistics dump to report per-target (PR #113723)
@@ -1667,6 +1667,12 @@ SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) { DataVisualization::GetSyntheticForType(type_name.GetSP())); } +void SBDebugger::ResetStatistics() { clayborg wrote: Should we add a `void SBTarget::ResetStatistics()` too that calls with the right target? https://github.com/llvm/llvm-project/pull/113723 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits