Compare commits
No commits in common. "rawhide" and "f39" have entirely different histories.
5 changed files with 120 additions and 550 deletions
97
erlang.spec
97
erlang.spec
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
|
||||
Name: erlang
|
||||
Version: 26.2.5.16
|
||||
Version: 26.2.5.5
|
||||
Release: 1%{?dist}
|
||||
Summary: General-purpose programming language and runtime environment
|
||||
|
||||
|
|
@ -106,13 +106,12 @@ Patch5: otp-0005-Do-not-install-nteventlog-and-related-doc-files-on-n.patch
|
|||
Patch6: otp-0006-Add-extra-search-directory.patch
|
||||
Patch7: otp-0007-Avoid-forking-sed-to-get-basename.patch
|
||||
Patch8: otp-0008-Load-man-pages-from-system-wide-directory.patch
|
||||
Patch9: otp-0009-Add-GDB-tools.patch
|
||||
Patch9: otp-0009-configure.ac-C99-fix-for-ERTS___AFTER_MORECORE_HOOK_.patch
|
||||
Patch10: otp-0010-configure.ac-C99-fixes-for-poll_works-check.patch
|
||||
# end of autogenerated patch tag list
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
# For gdb-tools
|
||||
BuildRequires: gdb
|
||||
BuildRequires: flex
|
||||
BuildRequires: make
|
||||
|
||||
|
|
@ -243,7 +242,7 @@ A byte code compiler for Erlang which produces highly compact code.
|
|||
%package crypto
|
||||
Summary: Cryptographical support
|
||||
BuildRequires: pkgconfig(openssl)
|
||||
%if 0%{?fedora} > 40
|
||||
%if 0%{fedora} > 40
|
||||
BuildRequires: openssl-devel-engine
|
||||
%endif
|
||||
Requires: %{name}-erts%{?_isa} = %{version}-%{release}
|
||||
|
|
@ -352,6 +351,7 @@ BuildRequires: m4
|
|||
BuildRequires: ncurses-devel
|
||||
BuildRequires: zlib-devel
|
||||
# epmd user, epmd group
|
||||
Requires(pre): shadow-utils
|
||||
Requires: %{name}-kernel%{?_isa} = %{version}-%{release}
|
||||
Requires: %{name}-stdlib%{?_isa} = %{version}-%{release}
|
||||
Requires: lksctp-tools
|
||||
|
|
@ -362,8 +362,6 @@ Provides: erlang(erl_drv_version) = 3.3
|
|||
#Provides: erlang(erl_nif_version) = %%(%%{buildroot}/bin/erl -noshell -eval 'io:format(erlang:system_info(nif_version)).' -s erlang halt)
|
||||
Provides: erlang(erl_nif_version) = 2.17
|
||||
Provides: bundled(pcre) = 8.44
|
||||
# git commit 965d19506ff2aed72e039b8c650b6ef5e9446b8c
|
||||
Provides: bundled(asmjit)
|
||||
Obsoletes: erlang-appmon
|
||||
Obsoletes: erlang-docbuilder
|
||||
Obsoletes: erlang-gs
|
||||
|
|
@ -426,14 +424,6 @@ Requires: %{name}-stdlib%{?_isa} = %{version}-%{release}
|
|||
%description ftp
|
||||
FTP client.
|
||||
|
||||
%package gdb-tools
|
||||
Summary: GDB plugin
|
||||
License: GPL-3.0-or-later
|
||||
Requires: gdb
|
||||
|
||||
%description gdb-tools
|
||||
GDB plugin.
|
||||
|
||||
%package inets
|
||||
Summary: A set of services such as a Web server and a HTTP client etc
|
||||
Requires: %{name}-erts%{?_isa} = %{version}-%{release}
|
||||
|
|
@ -753,11 +743,6 @@ Provides support for XML 1.0.
|
|||
# remove shipped zlib sources
|
||||
#rm -f erts/emulator/zlib/*.[ch]
|
||||
|
||||
# Create a sysusers.d config file
|
||||
cat >erlang.sysusers.conf <<EOF
|
||||
u epmd - 'Erlang Port Mapper Daemon' /dev/null -
|
||||
EOF
|
||||
|
||||
|
||||
%build
|
||||
# Reconfigure everything to apply changes to the autotools templates
|
||||
|
|
@ -951,19 +936,6 @@ install -D -p -m 0644 %{SOURCE8} %{buildroot}%{_unitdir}/epmd@.socket
|
|||
|
||||
%if %{__with_wxwidgets}
|
||||
echo "No need to fix additional scripts"
|
||||
# Fix file conflict w/ python3-typer-cli by renaming our typer to erlang-typer.
|
||||
# We only rename the symlink in %%{_bindir}, not its direct and indirect
|
||||
# targets in subdirectories of %%{_libdir}.
|
||||
#
|
||||
# File conflicts: /usr/bin/typer between erlang-dialyzer and python3-typer-cli
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2359567
|
||||
mv %{buildroot}%{_bindir}/typer %{buildroot}%{_bindir}/erlang-typer
|
||||
%if %{with doc}
|
||||
mv %{buildroot}%{_mandir}/man1/typer.1 \
|
||||
%{buildroot}%{_mandir}/man1/erlang-typer.1
|
||||
sed -r -i 's/^(\.TH[[:blank:]]+)?(typer)\b/\1erlang-\2/' \
|
||||
%{buildroot}%{_mandir}/man1/erlang-typer.1
|
||||
%endif
|
||||
%else
|
||||
# FIXME workaround for broken Erlang install procedure
|
||||
echo "Removing scripts which won't work w/o wxWidgets anyway"
|
||||
|
|
@ -979,10 +951,6 @@ done
|
|||
install -d -p -m 0755 %{buildroot}%{_datadir}/erlang/
|
||||
install -d -p -m 0755 %{buildroot}%{_datadir}/erlang/lib
|
||||
|
||||
install -m0644 -D erlang.sysusers.conf %{buildroot}%{_sysusersdir}/erlang.conf
|
||||
|
||||
# GDB tools
|
||||
install -D -p -m 0755 ./bin/*/jit-reader.so %{buildroot}%{_libdir}/gdb/jit-reader.so
|
||||
|
||||
%check
|
||||
TARGET="$(make target_configured)"
|
||||
|
|
@ -993,6 +961,11 @@ ERL_TOP=${ERL_TOP} make TARGET=${TARGET} release_tests
|
|||
# https://github.com/erlang/otp/wiki/Running-tests
|
||||
|
||||
|
||||
%pre erts
|
||||
getent group epmd >/dev/null || groupadd -r epmd
|
||||
getent passwd epmd >/dev/null || \
|
||||
useradd -r -g epmd -d /dev/null -s /sbin/nologin \
|
||||
-c "Erlang Port Mapper Daemon" epmd 2>/dev/null || :
|
||||
|
||||
|
||||
%files
|
||||
|
|
@ -1071,14 +1044,14 @@ ERL_TOP=${ERL_TOP} make TARGET=${TARGET} release_tests
|
|||
%files dialyzer
|
||||
%{_bindir}/dialyzer
|
||||
# FIXME FIXME FIXME this must be installed properly!!!!!!
|
||||
%{_bindir}/erlang-typer
|
||||
%{_bindir}/typer
|
||||
%{_libdir}/erlang/bin/dialyzer
|
||||
%{_libdir}/erlang/bin/typer
|
||||
%{_libdir}/erlang/erts-*/bin/dialyzer
|
||||
%{_libdir}/erlang/erts-*/bin/typer
|
||||
%{_libdir}/erlang/lib/dialyzer-*/
|
||||
%if %{with doc}
|
||||
%{_mandir}/man1/erlang-typer.*
|
||||
%{_mandir}/man1/typer.*
|
||||
%{_mandir}/man3/dialyzer.*
|
||||
%endif
|
||||
%endif # __with_wxwidgets
|
||||
|
|
@ -1236,7 +1209,6 @@ ERL_TOP=${ERL_TOP} make TARGET=${TARGET} release_tests
|
|||
%{_unitdir}/epmd.socket
|
||||
%{_unitdir}/epmd@.service
|
||||
%{_unitdir}/epmd@.socket
|
||||
%{_sysusersdir}/erlang.conf
|
||||
|
||||
%if %{__with_wxwidgets}
|
||||
%files et
|
||||
|
|
@ -1302,9 +1274,6 @@ ERL_TOP=${ERL_TOP} make TARGET=${TARGET} release_tests
|
|||
%{_mandir}/man3/ftp.*
|
||||
%endif
|
||||
|
||||
%files gdb-tools
|
||||
%{_libdir}/gdb/jit-reader.so
|
||||
|
||||
%files inets
|
||||
%dir %{_libdir}/erlang/lib/inets-*/
|
||||
%{_libdir}/erlang/lib/inets-*/ebin
|
||||
|
|
@ -1992,48 +1961,6 @@ ERL_TOP=${ERL_TOP} make TARGET=${TARGET} release_tests
|
|||
|
||||
|
||||
%changelog
|
||||
* Wed Sep 10 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.15-1
|
||||
- Ver. 26.2.5.15
|
||||
|
||||
* Wed Jul 23 2025 Fedora Release Engineering <releng@fedoraproject.org> - 26.2.5.14-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild
|
||||
|
||||
* Thu Jul 17 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.14-1
|
||||
- Ver. 26.2.5.14
|
||||
|
||||
* Fri Jun 20 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.13-3
|
||||
- Add GDB tools
|
||||
|
||||
* Wed Jun 18 2025 Benjamin A. Beasley <code@musicinmybrain.net> - 26.2.5.13-2
|
||||
- Rename typer (in /usr/bin) to erlang-typer; fixes RHBZ#2359567
|
||||
|
||||
* Mon Jun 16 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.13-1
|
||||
- Ver. 26.2.5.13
|
||||
|
||||
* Thu May 8 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.12-1
|
||||
- Ver. 26.2.5.12
|
||||
|
||||
* Wed Apr 16 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.11-1
|
||||
- Ver. 26.2.5.11
|
||||
|
||||
* Fri Mar 28 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.10-1
|
||||
- Ver. 26.2.5.10
|
||||
|
||||
* Mon Mar 10 2025 Zbigniew Jedrzejewski-Szmek <zbyszek@in.waw.pl> - 26.2.5.9-2
|
||||
- Add sysusers.d config file to allow rpm to create users/groups automatically
|
||||
|
||||
* Thu Feb 13 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.8-1
|
||||
- Ver. 26.2.5.8
|
||||
|
||||
* Tue Feb 11 2025 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.7-1
|
||||
- Ver. 26.2.5.7
|
||||
|
||||
* Thu Jan 16 2025 Fedora Release Engineering <releng@fedoraproject.org> - 26.2.5.6-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild
|
||||
|
||||
* Sat Dec 7 2024 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.6-1
|
||||
- Ver. 26.2.5.6
|
||||
|
||||
* Fri Nov 1 2024 Peter Lemenkov <lemenkov@gmail.com> - 26.2.5.5-1
|
||||
- Ver. 26.2.5.5
|
||||
|
||||
|
|
|
|||
|
|
@ -1,464 +0,0 @@
|
|||
From: Peter Lemenkov <lemenkov@gmail.com>
|
||||
Date: Thu, 19 Jun 2025 13:17:52 +0200
|
||||
Subject: [PATCH] Add GDB tools
|
||||
|
||||
* https://github.com/erlang/otp-gdb-tools
|
||||
* Commit 7b864f58c534699e4124e31ecfda86041b941037.
|
||||
|
||||
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
|
||||
|
||||
diff --git a/erts/etc/unix/gdb-tools/README.md b/erts/etc/unix/gdb-tools/README.md
|
||||
new file mode 100644
|
||||
index 0000000000..8a6cf92b1d
|
||||
--- /dev/null
|
||||
+++ b/erts/etc/unix/gdb-tools/README.md
|
||||
@@ -0,0 +1,42 @@
|
||||
+# Erlang/OTP GDB Tools
|
||||
+
|
||||
+This repository contains GDB tools that cannot
|
||||
+be part of the main Erlang/OTP repository for licensing
|
||||
+reasons. The tools are used when building and debugging
|
||||
+Erlang/OTP with gdb and are installed as needed by the
|
||||
+Erlang/OTP build system.
|
||||
+
|
||||
+Right now the only tool in this repository is the jit-reader
|
||||
+which is a plugin to gdb that allows it to read the stack of
|
||||
+Erlang processes when using the JIT. This allows commands
|
||||
+such as `backtrace` to show Erlang stackframes. For example:
|
||||
+
|
||||
+```
|
||||
+(gdb) bt
|
||||
+#0 0x00007fffa40005ee in global::call_bif_shared ()
|
||||
+#1 0x00007fffa411eaac in erl_eval:eval_lc1/7 () at erl_eval.erl:929
|
||||
+#2 0x00007fffa411e7bc in erl_eval:eval_lc/7 () at erl_eval.erl:917
|
||||
+#3 0x00007fffa4296528 in lists:map_1/2 () at lists.erl:2082
|
||||
+#4 0x00007fffa4296554 in lists:map_1/2 () at lists.erl:2082
|
||||
+#5 0x00007fffa4296554 in lists:map_1/2 () at lists.erl:2082
|
||||
+#6 0x00007fffa4296554 in lists:map_1/2 () at lists.erl:2082
|
||||
+.....
|
||||
+#98 0x00007fffa4296554 in lists:map_1/2 () at lists.erl:2082
|
||||
+#99 0x00007fffa4296554 in lists:map_1/2 () at lists.erl:2082
|
||||
+#100 0x00007fffa4296554 in lists:map_1/2 () at lists.erl:2082
|
||||
+#101 0x00007fffa42963d4 in lists:map/2 () at lists.erl:2077
|
||||
+#102 0x00007fffa411e45c in erl_eval:do_apply/7 () at erl_eval.erl:904
|
||||
+#103 0x00007fffa45f4c58 in shell:exprs/7 () at shell.erl:893
|
||||
+#104 0x00007fffa45f42c4 in shell:eval_exprs/7 () at shell.erl:849
|
||||
+#105 0x00007fffa45f3dac in shell:eval_loop/4 () at shell.erl:834
|
||||
+#106 0x00007fffa40024b8 in erts_beamasm:normal_exit/0-CodeInfoPrologue ()
|
||||
+Backtrace stopped: previous frame inner to this frame (corrupt stack?)
|
||||
+(gdb)
|
||||
+```
|
||||
+
|
||||
+## Updates of jit-reader
|
||||
+
|
||||
+When updating jit-reader you first need to update this repository
|
||||
+and push the new version here. Then you need to run
|
||||
+`./otp_build update_gdb_tools` in the Erlang/OTP repo for
|
||||
+it to use the correct commit.
|
||||
diff --git a/erts/etc/unix/gdb-tools/jit-reader.c b/erts/etc/unix/gdb-tools/jit-reader.c
|
||||
new file mode 100644
|
||||
index 0000000000..3c39c5540d
|
||||
--- /dev/null
|
||||
+++ b/erts/etc/unix/gdb-tools/jit-reader.c
|
||||
@@ -0,0 +1,386 @@
|
||||
+#include <gdb/jit-reader.h>
|
||||
+
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdint.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* Useful links
|
||||
+ * - https://pwparchive.wordpress.com/2011/11/20/new-jit-interface-for-gdb/
|
||||
+ * - https://sourceware.org/gdb/current/onlinedocs/gdb/Custom-Debug-Info.html
|
||||
+ * - https://github.com/tetzank/asmjit-utilities
|
||||
+ * - https://github.com/bminor/binutils-gdb/blob/master/gdb/testsuite/gdb.base/jitreader.c
|
||||
+ */
|
||||
+
|
||||
+GDB_DECLARE_GPL_COMPATIBLE_READER
|
||||
+
|
||||
+#if 0
|
||||
+#define HARD_DEBUG
|
||||
+static FILE *log = NULL;
|
||||
+#define LOG(...) do { fprintf(log, ##__VA_ARGS__); fflush(log); } while(0)
|
||||
+#else
|
||||
+#define LOG(...)
|
||||
+#endif
|
||||
+
|
||||
+typedef enum {
|
||||
+ X64_RBP = 6, /* Frame pointer iff native frames are enabled */
|
||||
+ X64_RSP = 7, /* Stack pointer when using native stack */
|
||||
+ X64_R12 = 12, /* Stack pointer when using non-native stack */
|
||||
+ X64_R13 = 13, /* Current process */
|
||||
+ X64_RIP = 16
|
||||
+} X64Register;
|
||||
+
|
||||
+typedef enum {
|
||||
+ /* Return address only */
|
||||
+ ERTS_FRAME_LAYOUT_RA,
|
||||
+ /* Frame pointer, return address */
|
||||
+ ERTS_FRAME_LAYOUT_FP_RA
|
||||
+} ErtsFrameLayout;
|
||||
+
|
||||
+struct emulator_info {
|
||||
+ /* 0 = regular, 1 = frame pointers */
|
||||
+ int frame_layout;
|
||||
+ const void *normal_exit;
|
||||
+};
|
||||
+
|
||||
+struct erlang_module_info {
|
||||
+ uint64_t base_address;
|
||||
+ uint32_t range_count;
|
||||
+ uint32_t code_size;
|
||||
+ /* Module name, including null terminator. */
|
||||
+ uint16_t name_length;
|
||||
+ char name[];
|
||||
+ /* array of range_info structures */
|
||||
+};
|
||||
+
|
||||
+struct range_info {
|
||||
+ uint32_t start_offset;
|
||||
+ uint32_t end_offset;
|
||||
+ uint32_t line_count;
|
||||
+ /* Range name, including null terminator. */
|
||||
+ uint16_t name_length;
|
||||
+ char name[];
|
||||
+ /* array of line_info structures */
|
||||
+};
|
||||
+
|
||||
+struct line_info {
|
||||
+ uint32_t start_offset;
|
||||
+ uint32_t line_number;
|
||||
+ /* File name, including null terminator. */
|
||||
+ uint16_t file_length;
|
||||
+ char file[];
|
||||
+};
|
||||
+
|
||||
+enum debug_info_header {
|
||||
+ DEBUG_INFO_HEADER_EMULATOR = 0,
|
||||
+ DEBUG_INFO_HEADER_MODULE = 1,
|
||||
+};
|
||||
+
|
||||
+struct debug_info {
|
||||
+ enum debug_info_header header;
|
||||
+ union {
|
||||
+ struct emulator_info emu;
|
||||
+ struct erlang_module_info mod;
|
||||
+ } payload;
|
||||
+};
|
||||
+
|
||||
+typedef struct range {
|
||||
+ GDB_CORE_ADDR start;
|
||||
+ GDB_CORE_ADDR end;
|
||||
+#ifdef HARD_DEBUG
|
||||
+ char *name;
|
||||
+#endif
|
||||
+} range;
|
||||
+
|
||||
+typedef struct priv {
|
||||
+ range *ranges;
|
||||
+ int num_ranges;
|
||||
+ ErtsFrameLayout frame_layout;
|
||||
+ const void *normal_exit;
|
||||
+} priv;
|
||||
+
|
||||
+static enum gdb_status read_module_info(struct gdb_reader_funcs *self,
|
||||
+ struct gdb_symbol_callbacks *cb,
|
||||
+ struct erlang_module_info *module_info) {
|
||||
+ struct gdb_object *obj = cb->object_open(cb);
|
||||
+ GDB_CORE_ADDR mod_start, mod_end;
|
||||
+ char *symfile = (char*)module_info;
|
||||
+ priv *priv = self->priv_data;
|
||||
+
|
||||
+ symfile += sizeof(*module_info) + module_info->name_length;
|
||||
+
|
||||
+ mod_start = module_info->base_address;
|
||||
+ mod_end = mod_start + module_info->code_size;
|
||||
+
|
||||
+ priv->ranges = realloc(priv->ranges, (priv->num_ranges + 1) * sizeof(range));
|
||||
+ priv->ranges[priv->num_ranges].start = mod_start;
|
||||
+ priv->ranges[priv->num_ranges].end = mod_end;
|
||||
+#ifdef HARD_DEBUG
|
||||
+ priv->ranges[priv->num_ranges].name = strdup(module_info->name);
|
||||
+#endif
|
||||
+ priv->num_ranges += 1;
|
||||
+
|
||||
+ LOG("Add module `%s` (0x%lx, 0x%lx)\r\n",
|
||||
+ module_info->name, mod_start, mod_end);
|
||||
+
|
||||
+ for (int range = 0; range < module_info->range_count; range++) {
|
||||
+ struct range_info *range_info;
|
||||
+ struct gdb_symtab *symtab;
|
||||
+ GDB_CORE_ADDR begin, end;
|
||||
+
|
||||
+ range_info = (struct range_info *)symfile;
|
||||
+ symfile += sizeof(*range_info) + range_info->name_length;
|
||||
+
|
||||
+ begin = mod_start + range_info->start_offset;
|
||||
+ end = mod_start + range_info->end_offset;
|
||||
+
|
||||
+ LOG("Add range `%s` (0x%lx, 0x%lx), %u lines\r\n",
|
||||
+ range_info->name,
|
||||
+ begin, end,
|
||||
+ range_info->line_count);
|
||||
+
|
||||
+ /* A bug in GDB < 9 forces us to open and close the symtab for each
|
||||
+ * iteration. */
|
||||
+ symtab = cb->symtab_open(cb, obj, module_info->name);
|
||||
+ cb->block_open(cb, symtab, NULL, begin, end, range_info->name);
|
||||
+ cb->symtab_close(cb, symtab);
|
||||
+
|
||||
+ for (int line = 0; line < range_info->line_count; line++) {
|
||||
+ struct gdb_line_mapping line_mapping;
|
||||
+ struct line_info *line_info;
|
||||
+
|
||||
+ line_info = (struct line_info *)symfile;
|
||||
+ symfile += sizeof(*line_info) + line_info->file_length;
|
||||
+
|
||||
+ line_mapping.pc = mod_start + line_info->start_offset;
|
||||
+ line_mapping.line = line_info->line_number;
|
||||
+
|
||||
+ LOG("\t%s:%u\r\n", line_info->file, line_info->line_number);
|
||||
+
|
||||
+ /* The symbol table must be opened and closed on every single line
|
||||
+ * for file names to work properly, as there is no other way to
|
||||
+ * tell GDB that a certain line belongs to a different file than
|
||||
+ * the rest of the table. Sigh. */
|
||||
+ symtab = cb->symtab_open(cb, obj, line_info->file);
|
||||
+
|
||||
+ cb->block_open(cb, symtab, NULL, line_mapping.pc, end,
|
||||
+ range_info->name);
|
||||
+ cb->line_mapping_add(cb, symtab, 1, &line_mapping);
|
||||
+ cb->symtab_close(cb, symtab);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cb->object_close(cb, obj);
|
||||
+
|
||||
+ return GDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static enum gdb_status read_emulator_info(struct gdb_reader_funcs *self,
|
||||
+ struct gdb_symbol_callbacks *cb,
|
||||
+ struct emulator_info *emulator_info) {
|
||||
+ priv *priv = self->priv_data;
|
||||
+
|
||||
+ priv->frame_layout = emulator_info->frame_layout;
|
||||
+ priv->normal_exit = emulator_info->normal_exit;
|
||||
+
|
||||
+ LOG("initialize: frame layout = %i\r\n", priv->frame_layout);
|
||||
+
|
||||
+ return GDB_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static enum gdb_status read_debug_info(struct gdb_reader_funcs *self,
|
||||
+ struct gdb_symbol_callbacks *cb,
|
||||
+ void *memory, long memory_sz) {
|
||||
+ struct debug_info *debug_info = memory;
|
||||
+
|
||||
+ (void)memory_sz;
|
||||
+
|
||||
+ switch (debug_info->header) {
|
||||
+ case DEBUG_INFO_HEADER_EMULATOR:
|
||||
+ return read_emulator_info(self, cb, &debug_info->payload.emu);
|
||||
+ case DEBUG_INFO_HEADER_MODULE:
|
||||
+ return read_module_info(self, cb, &debug_info->payload.mod);
|
||||
+ }
|
||||
+
|
||||
+ return GDB_FAIL;
|
||||
+}
|
||||
+
|
||||
+static void regfree(struct gdb_reg_value *reg) {
|
||||
+ free(reg);
|
||||
+}
|
||||
+
|
||||
+static struct range *get_range(priv *priv, GDB_CORE_ADDR rip) {
|
||||
+ for (int i = 0; i < priv->num_ranges; i++) {
|
||||
+ if (rip >= priv->ranges[i].start && rip < priv->ranges[i].end) {
|
||||
+ return &priv->ranges[i];
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static enum gdb_status unwind(struct gdb_reader_funcs *self,
|
||||
+ struct gdb_unwind_callbacks *cb) {
|
||||
+ GDB_CORE_ADDR rbp, rsp, rip;
|
||||
+ struct range *range;
|
||||
+ priv *priv;
|
||||
+
|
||||
+ rbp = *(GDB_CORE_ADDR*)cb->reg_get(cb, X64_RBP)->value;
|
||||
+ rsp = *(GDB_CORE_ADDR*)cb->reg_get(cb, X64_RSP)->value;
|
||||
+ rip = *(GDB_CORE_ADDR*)cb->reg_get(cb, X64_RIP)->value;
|
||||
+
|
||||
+ priv = self->priv_data;
|
||||
+ range = get_range(priv, rip);
|
||||
+
|
||||
+ /* Check that rip points to one of the addresses that we handle */
|
||||
+ if (range) {
|
||||
+ struct gdb_reg_value *prev_rbp, *prev_rsp, *prev_rip;
|
||||
+
|
||||
+ prev_rbp = malloc(sizeof(struct gdb_reg_value) + sizeof(char*));
|
||||
+ prev_rsp = malloc(sizeof(struct gdb_reg_value) + sizeof(char*));
|
||||
+ prev_rip = malloc(sizeof(struct gdb_reg_value) + sizeof(char*));
|
||||
+
|
||||
+ LOG("UNWIND match %s: rbp: 0x%lx rsp: 0x%lx rip: 0x%lx \r\n",
|
||||
+ range->name, rbp, rsp, rip);
|
||||
+
|
||||
+ prev_rbp->free = ®free;
|
||||
+ prev_rbp->defined = 1;
|
||||
+ prev_rbp->size = sizeof(char*);
|
||||
+ prev_rsp->free = ®free;
|
||||
+ prev_rsp->defined = 1;
|
||||
+ prev_rsp->size = sizeof(char*);
|
||||
+ prev_rip->free = ®free;
|
||||
+ prev_rip->defined = 1;
|
||||
+ prev_rip->size = sizeof(char*);
|
||||
+
|
||||
+ if (priv->frame_layout == ERTS_FRAME_LAYOUT_FP_RA) {
|
||||
+ /* Frame pointers are enabled, which means that rbp will point to
|
||||
+ * where we stored the previous frames rbp. Also the previous
|
||||
+ * frames address will be at rbp + 8 and the previous frames rsp
|
||||
+ * will be rbp + 16.
|
||||
+ *
|
||||
+ * 0x00: <- prev_rsp
|
||||
+ * 0x08: prev call addr
|
||||
+ * 0x10: prev rbp <- curr rbp
|
||||
+ * 0x18: current frame
|
||||
+ * 0x20: <- curr rip */
|
||||
+ cb->target_read(rbp + 1 * sizeof(char*), &prev_rip->value,
|
||||
+ sizeof(char*));
|
||||
+ cb->target_read(rbp + 0 * sizeof(char*), &prev_rbp->value,
|
||||
+ sizeof(char*));
|
||||
+ *(GDB_CORE_ADDR*)prev_rsp->value = rbp + sizeof(char*[2]);
|
||||
+ } else {
|
||||
+ /* Normal frame layout, we need to scan the stack. */
|
||||
+ cb->target_read(rsp, &prev_rip->value, sizeof(char*));
|
||||
+
|
||||
+ for (rsp += sizeof(char*); ; rsp += sizeof(char*)) {
|
||||
+ cb->target_read(rsp, &prev_rip->value, sizeof(char*));
|
||||
+
|
||||
+ LOG("rsp: 0x%lx rip: 0x%lx\r\n",
|
||||
+ rsp, *(GDB_CORE_ADDR*)prev_rip->value);
|
||||
+
|
||||
+ /* Check if it is a cp */
|
||||
+ if ((*(GDB_CORE_ADDR*)prev_rip->value & 0x3) == 0) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *(GDB_CORE_ADDR*)prev_rsp->value = rsp;
|
||||
+ *(GDB_CORE_ADDR*)prev_rbp->value = rsp - sizeof(char*);
|
||||
+ }
|
||||
+
|
||||
+ if (*(GDB_CORE_ADDR*)prev_rip->value == (uintptr_t)priv->normal_exit) {
|
||||
+ LOG("Normal exit\r\n");
|
||||
+ *(GDB_CORE_ADDR*)prev_rsp->value = 0;
|
||||
+ *(GDB_CORE_ADDR*)prev_rbp->value = 0;
|
||||
+ } else {
|
||||
+ LOG("UNWIND prev: rbp: 0x%lx rsp: 0x%lx rip: 0x%lx\r\n",
|
||||
+ *(GDB_CORE_ADDR*)prev_rbp->value,
|
||||
+ *(GDB_CORE_ADDR*)prev_rsp->value,
|
||||
+ *(GDB_CORE_ADDR*)prev_rip->value);
|
||||
+ }
|
||||
+
|
||||
+ cb->reg_set(cb, X64_RIP, prev_rip);
|
||||
+ cb->reg_set(cb, X64_RSP, prev_rsp);
|
||||
+ cb->reg_set(cb, X64_RBP, prev_rbp);
|
||||
+
|
||||
+ return GDB_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ LOG("UNWIND no match: rbp: 0x%lx rsp: 0x%lx rip: 0x%lx\r\n", rbp, rsp, rip);
|
||||
+ return GDB_FAIL;
|
||||
+}
|
||||
+
|
||||
+static struct gdb_frame_id get_frame_id(struct gdb_reader_funcs *self,
|
||||
+ struct gdb_unwind_callbacks *cb){
|
||||
+ struct gdb_frame_id frame = {0, 0};
|
||||
+ GDB_CORE_ADDR rbp, rsp, rip;
|
||||
+ struct range *range;
|
||||
+ priv *priv;
|
||||
+
|
||||
+ rbp = *(GDB_CORE_ADDR*)cb->reg_get(cb, X64_RBP)->value;
|
||||
+ rsp = *(GDB_CORE_ADDR*)cb->reg_get(cb, X64_RSP)->value;
|
||||
+ rip = *(GDB_CORE_ADDR*)cb->reg_get(cb, X64_RIP)->value;
|
||||
+
|
||||
+ priv = self->priv_data;
|
||||
+ range = get_range(priv, rip);
|
||||
+
|
||||
+ LOG("FRAME: rip: 0x%lx rsp: 0x%lx rbp: 0x%lx \r\n", rip, rsp, rbp);
|
||||
+
|
||||
+ if (range) {
|
||||
+ frame.code_address = rip;
|
||||
+
|
||||
+ if (priv->frame_layout == ERTS_FRAME_LAYOUT_FP_RA) {
|
||||
+ frame.stack_address = rbp + sizeof(char*);
|
||||
+ } else {
|
||||
+ GDB_CORE_ADDR prev_rip;
|
||||
+
|
||||
+ for (rsp += sizeof(char*); ; rsp += sizeof(char*)) {
|
||||
+ cb->target_read(rsp, &prev_rip, sizeof(char*));
|
||||
+
|
||||
+ LOG("rsp: 0x%lx rip: 0x%lx\r\n", rsp, prev_rip);
|
||||
+
|
||||
+ /* Check if it is a cp */
|
||||
+ if ((prev_rip & 0x3) == 0) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ frame.stack_address = rsp;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ LOG("FRAME: code_address: 0x%lx stack_address: 0x%lx\r\n",
|
||||
+ frame.code_address, frame.stack_address);
|
||||
+
|
||||
+ return frame;
|
||||
+}
|
||||
+
|
||||
+static void destroy(struct gdb_reader_funcs *self){
|
||||
+ free(self);
|
||||
+}
|
||||
+
|
||||
+struct gdb_reader_funcs *gdb_init_reader(void){
|
||||
+ struct gdb_reader_funcs *funcs = malloc(sizeof(struct gdb_reader_funcs));
|
||||
+ priv *priv_data = malloc(sizeof(priv));
|
||||
+
|
||||
+ priv_data->num_ranges = 1;
|
||||
+ priv_data->ranges = malloc(sizeof(range));
|
||||
+ priv_data->ranges[0].start = 0;
|
||||
+ priv_data->ranges[0].end = 0;
|
||||
+
|
||||
+ funcs->reader_version = GDB_READER_INTERFACE_VERSION;
|
||||
+ funcs->priv_data = priv_data;
|
||||
+
|
||||
+ funcs->read = read_debug_info;
|
||||
+ funcs->unwind = unwind;
|
||||
+ funcs->get_frame_id = get_frame_id;
|
||||
+ funcs->destroy = destroy;
|
||||
+
|
||||
+#ifdef HARD_DEBUG
|
||||
+ log = fopen("/tmp/jit-reader.log","w+");
|
||||
+ if (!log) fprintf(stderr,"Could not open /tmp/jit-reader.log");
|
||||
+#endif
|
||||
+
|
||||
+ return funcs;
|
||||
+}
|
||||
diff --git a/erts/etc/unix/gdb-tools/jit-reader.mk b/erts/etc/unix/gdb-tools/jit-reader.mk
|
||||
new file mode 100644
|
||||
index 0000000000..8ef0bccec2
|
||||
--- /dev/null
|
||||
+++ b/erts/etc/unix/gdb-tools/jit-reader.mk
|
||||
@@ -0,0 +1,9 @@
|
||||
+EXTRA_LIBS = $(BINDIR)/jit-reader.so
|
||||
+
|
||||
+jit-reader: $(EXTRA_LIBS)
|
||||
+
|
||||
+$(OBJDIR)/jit-reader.o: $(GDB_TOOLS)/jit-reader.c $(GDB_TOOLS)/jit-reader.h
|
||||
+ $(V_CC) $(DED_CFLAGS) -I$(ETC) -o $@ -c $<
|
||||
+
|
||||
+$(BINDIR)/jit-reader.so: $(OBJDIR)/jit-reader.o
|
||||
+ $(V_LD) $(DED_LDFLAGS) -o $@ $^
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 24 Nov 2022 11:57:49 +0100
|
||||
Subject: [PATCH] configure.ac: C99 fix for
|
||||
ERTS___AFTER_MORECORE_HOOK_CAN_TRACK_MALLOC
|
||||
|
||||
#include <unistd.h> for the sbrk function if the header is available.
|
||||
|
||||
diff --git a/erts/configure b/erts/configure
|
||||
index 2044690dc6..f31d7775a4 100755
|
||||
--- a/erts/configure
|
||||
+++ b/erts/configure
|
||||
@@ -20937,6 +20937,9 @@ else $as_nop
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
+#ifdef HAVE_UNISTD_H
|
||||
+# include <unistd.h>
|
||||
+#endif
|
||||
#if defined(HAVE_END_SYMBOL)
|
||||
extern char end;
|
||||
#elif defined(HAVE__END_SYMBOL)
|
||||
diff --git a/erts/configure.ac b/erts/configure.ac
|
||||
index f247c1e71f..59c4d05460 100644
|
||||
--- a/erts/configure.ac
|
||||
+++ b/erts/configure.ac
|
||||
@@ -2459,6 +2459,9 @@ AC_CACHE_CHECK([if __after_morecore_hook can track malloc()s core memory use],
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
+#ifdef HAVE_UNISTD_H
|
||||
+# include <unistd.h>
|
||||
+#endif
|
||||
#if defined(HAVE_END_SYMBOL)
|
||||
extern char end;
|
||||
#elif defined(HAVE__END_SYMBOL)
|
||||
72
otp-0010-configure.ac-C99-fixes-for-poll_works-check.patch
Normal file
72
otp-0010-configure.ac-C99-fixes-for-poll_works-check.patch
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Thu, 24 Nov 2022 11:59:22 +0100
|
||||
Subject: [PATCH] configure.ac: C99 fixes for poll_works check
|
||||
|
||||
Include <fcntl.h> if it is available for the open prototype.
|
||||
Return from main instead of calling exit, so that no function
|
||||
declaration is needed.
|
||||
|
||||
diff --git a/erts/configure b/erts/configure
|
||||
index f31d7775a4..77fb9d0d7f 100755
|
||||
--- a/erts/configure
|
||||
+++ b/erts/configure
|
||||
@@ -24893,10 +24893,13 @@ else $as_nop
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <poll.h>
|
||||
-main()
|
||||
+#ifdef HAVE_FCNTL_H
|
||||
+#include <fcntl.h>
|
||||
+#endif
|
||||
+int main()
|
||||
{
|
||||
#ifdef _POLL_EMUL_H_
|
||||
- exit(1); /* Implemented using select() -- fail */
|
||||
+ return 1; /* Implemented using select() -- fail */
|
||||
#else
|
||||
struct pollfd fds[1];
|
||||
int fd;
|
||||
@@ -24905,9 +24908,9 @@ main()
|
||||
fds[0].events = POLLIN;
|
||||
fds[0].revents = 0;
|
||||
if (poll(fds, 1, 0) < 0 || (fds[0].revents & POLLNVAL) != 0) {
|
||||
- exit(1); /* Does not work for devices -- fail */
|
||||
+ return 1; /* Does not work for devices -- fail */
|
||||
}
|
||||
- exit(0);
|
||||
+ return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/erts/configure.ac b/erts/configure.ac
|
||||
index 59c4d05460..0abb11a967 100644
|
||||
--- a/erts/configure.ac
|
||||
+++ b/erts/configure.ac
|
||||
@@ -3102,10 +3102,13 @@ poll_works=no
|
||||
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <poll.h>
|
||||
-main()
|
||||
+#ifdef HAVE_FCNTL_H
|
||||
+#include <fcntl.h>
|
||||
+#endif
|
||||
+int main()
|
||||
{
|
||||
#ifdef _POLL_EMUL_H_
|
||||
- exit(1); /* Implemented using select() -- fail */
|
||||
+ return 1; /* Implemented using select() -- fail */
|
||||
#else
|
||||
struct pollfd fds[1];
|
||||
int fd;
|
||||
@@ -3114,9 +3117,9 @@ main()
|
||||
fds[0].events = POLLIN;
|
||||
fds[0].revents = 0;
|
||||
if (poll(fds, 1, 0) < 0 || (fds[0].revents & POLLNVAL) != 0) {
|
||||
- exit(1); /* Does not work for devices -- fail */
|
||||
+ return 1; /* Does not work for devices -- fail */
|
||||
}
|
||||
- exit(0);
|
||||
+ return 0;
|
||||
#endif
|
||||
}
|
||||
]])],[poll_works=yes],[poll_works=no],[
|
||||
2
sources
2
sources
|
|
@ -1 +1 @@
|
|||
SHA512 (otp-OTP-26.2.5.16.tar.gz) = 4e973be7e8ccad196d59759108a521535b0f046268eb0406f789a50f411fa27c9c11fcfb61a7218605bf1b32921bb52c52fc7c99917e1acfc0d3ed09437129b2
|
||||
SHA512 (otp-OTP-26.2.5.5.tar.gz) = af6dc4ce7999a64ec3312bca96b37d980d3d4a21f7efa9d2e8d1bba8cfa800951db3c6b5b081d4db1b90306faf21ee08b11f3ab3373c549c471b806d47043bed
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue