[njs] Added native function symbolizer for function tracing in debug.
Dmitry Volyntsev
xeioex at nginx.com
Wed Jun 29 06:05:38 UTC 2022
details: https://hg.nginx.org/njs/rev/8fe7d9723477
branches:
changeset: 1899:8fe7d9723477
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Jun 28 22:36:30 2022 -0700
description:
Added native function symbolizer for function tracing in debug.
diffstat:
auto/cc | 4 +
auto/help | 4 +
auto/libbfd | 35 ++++++
auto/link | 31 +++++
auto/openssl | 1 +
auto/options | 9 +
auto/pcre | 3 +
auto/sources | 4 +
configure | 15 +-
src/njs.h | 3 +
src/njs_addr2line.c | 265 +++++++++++++++++++++++++++++++++++++++++++++++
src/njs_addr2line.h | 22 +++
src/njs_function.c | 25 +++-
src/njs_main.h | 1 +
src/njs_shell.c | 13 ++
src/njs_sprintf.c | 6 +
src/njs_vmcode.c | 6 +-
src/njs_vmcode.h | 4 +-
src/test/njs_unit_test.c | 43 +++++++-
19 files changed, 474 insertions(+), 20 deletions(-)
diffs (736 lines):
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/cc
--- a/auto/cc Wed Jun 22 23:37:27 2022 -0700
+++ b/auto/cc Tue Jun 28 22:36:30 2022 -0700
@@ -177,6 +177,10 @@ if [ "$NJS_DEBUG_MEMORY" = "YES" ]; then
njs_define=NJS_DEBUG_MEMORY . auto/define
fi
+if [ "$NJS_DEBUG_OPCODE" = "YES" ]; then
+ njs_define=NJS_DEBUG_OPCODE . auto/define
+fi
+
if [ "$NJS_TEST262" = "YES" ]; then
njs_define=NJS_TEST262 . auto/define
fi
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/help
--- a/auto/help Wed Jun 22 23:37:27 2022 -0700
+++ b/auto/help Tue Jun 28 22:36:30 2022 -0700
@@ -33,10 +33,14 @@ default: "$NJS_LD_OPT"
--address-sanitizer=YES enables build with address sanitizer, \
default: "$NJS_ADDRESS_SANITIZER"
+ --addr2line=YES enables native function symbolization, \
+default: "$NJS_ADDR2LINE"
--debug=YES enables additional runtime checks, \
default: "$NJS_DEBUG"
--debug-memory=YES enables memory alloc debug, \
default: "$NJS_DEBUG_MEMORY"
+ --debug-opcode=YES enables runtime function tracing, \
+default: "$NJS_DEBUG_OPCODE"
--test262=YES enables test262 extentions, \
default: "$NJS_TEST262"
END
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/libbfd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/auto/libbfd Tue Jun 28 22:36:30 2022 -0700
@@ -0,0 +1,35 @@
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+
+NJS_HAVE_LIBBFD=NO
+
+if [ $NJS_ADDR2LINE = YES ]; then
+ njs_found=no
+
+ njs_feature="BFD library"
+ njs_feature_name=NJS_HAVE_LIBBFD
+ njs_feature_run=yes
+ njs_feature_incs=
+ njs_feature_libs="-lbfd"
+ njs_feature_test="#include <bfd.h>
+
+ int main() {
+ bfd_init();
+ return 0;
+ }"
+ . auto/feature
+
+ if [ $njs_found = no ]; then
+ njs_feature="OpenSSL library -lcrypto"
+ njs_feature_libs="-lcrypto"
+
+ . auto/feature
+ fi
+
+
+ if [ $njs_found = yes ]; then
+ NJS_HAVE_LIBBFD=YES
+ NJS_LIB_AUX_LIBS="$NJS_LIB_AUX_LIBS $njs_feature_libs"
+ fi
+fi
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/link
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/auto/link Tue Jun 28 22:36:30 2022 -0700
@@ -0,0 +1,31 @@
+
+# Copyright (C) Dmitry Volyntsev
+# Copyright (C) NGINX, Inc.
+
+
+NJS_HAVE_DL_ITERATE_PHDR=NO
+
+if [ $NJS_ADDR2LINE = YES ]; then
+ njs_feature="dl_iterate_phdr()"
+ njs_feature_name=NJS_HAVE_DL_ITERATE_PHDR
+ njs_feature_run=yes
+ njs_feature_incs=
+ njs_feature_libs=
+ njs_feature_test="#define _GNU_SOURCE
+ #include <link.h>
+
+ static int
+ cb(struct dl_phdr_info *info, size_t size, void *data) {
+ return 0;
+ }
+
+ int main() {
+ dl_iterate_phdr(cb, 0);
+ return 0;
+ }"
+ . auto/feature
+
+ if [ $njs_found = yes ]; then
+ NJS_HAVE_DL_ITERATE_PHDR=YES
+ fi
+fi
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/openssl
--- a/auto/openssl Wed Jun 22 23:37:27 2022 -0700
+++ b/auto/openssl Tue Jun 28 22:36:30 2022 -0700
@@ -46,6 +46,7 @@ if [ $NJS_OPENSSL = YES ]; then
NJS_HAVE_OPENSSL=YES
NJS_OPENSSL_LIB="$njs_feature_libs"
+ NJS_LIB_AUX_LIBS="$NJS_LIB_AUX_LIBS $njs_feature_libs"
fi
fi
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/options
--- a/auto/options Wed Jun 22 23:37:27 2022 -0700
+++ b/auto/options Tue Jun 28 22:36:30 2022 -0700
@@ -8,7 +8,10 @@ NJS_LD_OPT=${NJS_CC_OPT:--O}
NJS_DEBUG=NO
NJS_DEBUG_MEMORY=NO
+NJS_DEBUG_OPCODE=NO
+
NJS_ADDRESS_SANITIZER=NO
+NJS_ADDR2LINE=NO
NJS_TEST262=YES
NJS_OPENSSL=YES
@@ -34,8 +37,10 @@ do
--build-dir=*) NJS_BUILD_DIR="$value" ;;
--address-sanitizer=*) NJS_ADDRESS_SANITIZER="$value" ;;
+ --addr2line=*) NJS_ADDR2LINE="$value" ;;
--debug=*) NJS_DEBUG="$value" ;;
--debug-memory=*) NJS_DEBUG_MEMORY="$value" ;;
+ --debug-opcode=*) NJS_DEBUG_OPCODE="$value" ;;
--test262=*) NJS_TEST262="$value" ;;
--no-openssl) NJS_OPENSSL=NO ;;
@@ -66,3 +71,7 @@ done
if [ "$NJS_DEBUG_MEMORY" = "YES" ]; then
NJS_DEBUG=YES
fi
+
+if [ "$NJS_DEBUG_OPCODE" = "YES" ]; then
+ NJS_ADDR2LINE=YES
+fi
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/pcre
--- a/auto/pcre Wed Jun 22 23:37:27 2022 -0700
+++ b/auto/pcre Tue Jun 28 22:36:30 2022 -0700
@@ -134,3 +134,6 @@ if [ $NJS_PCRE = YES ]; then
fi
fi
+
+NJS_LIB_AUX_CFLAGS="$NJS_LIB_AUX_CFLAGS $NJS_PCRE_CFLAGS"
+NJS_LIB_AUX_LIBS="$NJS_LIB_AUX_LIBS $NJS_PCRE_LIB"
diff -r 20ee5213e3c4 -r 8fe7d9723477 auto/sources
--- a/auto/sources Wed Jun 22 23:37:27 2022 -0700
+++ b/auto/sources Tue Jun 28 22:36:30 2022 -0700
@@ -75,6 +75,10 @@ if [ "$NJS_PCRE" = "YES" ]; then
NJS_LIB_SRCS="$NJS_LIB_SRCS external/njs_regex.c"
fi
+if [ "$NJS_HAVE_LIBBFD" = "YES" -a "$NJS_HAVE_DL_ITERATE_PHDR" = "YES" ]; then
+ NJS_LIB_SRCS="$NJS_LIB_SRCS src/njs_addr2line.c"
+fi
+
NJS_TS_SRCS=$(find ts/ -name "*.d.ts" -o -name "*.json")
NJS_TEST_TS_SRCS=$(find test/ts/ -name "*.ts" -o -name "*.json")
diff -r 20ee5213e3c4 -r 8fe7d9723477 configure
--- a/configure Wed Jun 22 23:37:27 2022 -0700
+++ b/configure Tue Jun 28 22:36:30 2022 -0700
@@ -33,6 +33,10 @@ cat << END > $NJS_AUTO_CONFIG_H
END
+NJS_LIBS="$NJS_LIBRT"
+NJS_LIB_AUX_CFLAGS=
+NJS_LIB_AUX_LIBS=
+
. auto/os
. auto/cc
. auto/types
@@ -46,16 +50,11 @@ END
. auto/pcre
. auto/readline
. auto/openssl
-. auto/sources
-
-NJS_LIB_AUX_CFLAGS="$NJS_PCRE_CFLAGS"
+. auto/libbfd
+. auto/link
-NJS_LIBS="$NJS_LIBRT"
-NJS_LIB_AUX_LIBS="$NJS_PCRE_LIB $NJS_OPENSSL_LIB"
-
+. auto/sources
. auto/modules
. auto/make
-
. auto/expect
-
. auto/summary
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs.h
--- a/src/njs.h Wed Jun 22 23:37:27 2022 -0700
+++ b/src/njs.h Tue Jun 28 22:36:30 2022 -0700
@@ -250,6 +250,9 @@ typedef struct {
uint8_t unsafe; /* 1 bit */
uint8_t module; /* 1 bit */
uint8_t ast; /* 1 bit */
+#ifdef NJS_DEBUG_OPCODE
+ uint8_t opcode_debug; /* 1 bit */
+#endif
uint8_t unhandled_rejection;
} njs_vm_opt_t;
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_addr2line.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/njs_addr2line.c Tue Jun 28 22:36:30 2022 -0700
@@ -0,0 +1,265 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ *
+ * addr2line impementaton based upon the work by Jeff Muizelaar.
+ *
+ * A hacky replacement for backtrace_symbols in glibc
+ *
+ * backtrace_symbols in glibc looks up symbols using dladdr which is limited in
+ * the symbols that it sees. libbacktracesymbols opens the executable and
+ * shared libraries using libbfd and will look up backtrace information using
+ * the symbol table and the dwarf line information.
+ *
+ * Derived from addr2line.c from GNU Binutils by Jeff Muizelaar
+ *
+ * Copyright 2007 Jeff Muizelaar
+ *
+ * addr2line.c -- convert addresses to line number and function name
+ * Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Contributed by Ulrich Lauther <Ulrich.Lauther at mchp.siemens.de>
+ *
+ * This file was part of GNU Binutils.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#define _GNU_SOURCE
+#include <njs_main.h>
+#include <njs_addr2line.h>
+
+#include <bfd.h>
+#include <link.h>
+
+
+typedef struct {
+ const char *file;
+ ElfW(Addr) address;
+ ElfW(Addr) base;
+ void *hdr;
+} njs_file_match_t;
+
+
+typedef struct {
+ bfd_vma pc;
+ const char *filename;
+ const char *functionname;
+ unsigned int line;
+ njs_bool_t found;
+ asymbol **syms;
+} njs_translate_address_t;
+
+
+static u_char *njs_process_file(u_char *buf, u_char *end, bfd_vma *addr,
+ const char *file_name);
+static long njs_read_symtab(bfd *abfd, asymbol ***syms);
+static u_char *njs_translate_address(u_char *buf, u_char *end, bfd_vma *addr,
+ bfd *abfd, asymbol **syms);
+static void njs_find_address_in_section(bfd *abfd, asection *section,
+ void *data);
+static int njs_find_matching_file(struct dl_phdr_info *info, size_t size,
+ void *data);
+
+
+u_char *
+_njs_addr2line(u_char *buf, u_char *end, void *address)
+{
+ bfd_vma addr;
+ const char *fname;
+
+ njs_file_match_t match = { .address = (ElfW(Addr)) address };
+
+ bfd_init();
+
+ dl_iterate_phdr(njs_find_matching_file, &match);
+
+ fname = "/proc/self/exe";
+ if (match.file != NULL && njs_strlen(match.file)) {
+ fname = match.file;
+ }
+
+ addr = (ElfW(Addr)) address - match.base;
+
+ return njs_process_file(buf, end, &addr, fname);
+}
+
+
+static u_char *
+njs_process_file(u_char *buf, u_char *end, bfd_vma *addr, const char *file_name)
+{
+ bfd *abfd;
+ char **matching;
+ u_char *p;
+ asymbol **syms;
+
+ abfd = bfd_openr(file_name, NULL);
+ if (abfd == NULL) {
+ njs_stderror("%s: failed to open while looking for addr2line",
+ file_name);
+ return NULL;
+ }
+
+ if (bfd_check_format(abfd, bfd_archive)) {
+ njs_stderror("%s: can not get addresses from archive", file_name);
+ return NULL;
+ }
+
+ if (!bfd_check_format_matches(abfd, bfd_object, &matching)) {
+ njs_stderror("%s: bfd_check_format_matches() failed",
+ bfd_get_filename(abfd));
+ return NULL;
+ }
+
+ if (njs_read_symtab(abfd, &syms) <= 0) {
+ njs_stderror("%s: njs_read_symtab() failed",
+ bfd_get_filename(abfd));
+ return NULL;
+ }
+
+ p = njs_translate_address(buf, end, addr, abfd, syms);
+
+ if (syms != NULL) {
+ free(syms);
+ syms = NULL;
+ }
+
+ bfd_close(abfd);
+
+ return p;
+}
+
+
+static long
+njs_read_symtab(bfd *abfd, asymbol ***syms)
+{
+ long symcount;
+ unsigned size;
+
+ if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) {
+ return 0;
+ }
+
+ symcount = bfd_read_minisymbols(abfd, 0, (PTR) syms, &size);
+ if (symcount == 0) {
+ symcount = bfd_read_minisymbols(abfd, 1 /* dynamic */,
+ (PTR) syms, &size);
+ }
+
+ return symcount;
+}
+
+
+static u_char *
+njs_translate_address(u_char *buf, u_char *end, bfd_vma *addr, bfd *abfd,
+ asymbol **syms)
+{
+ char *h;
+ const char *name;
+ njs_translate_address_t ctx;
+
+ ctx.pc = *addr;
+ ctx.found = 0;
+ ctx.syms = syms;
+
+ bfd_map_over_sections(abfd, njs_find_address_in_section, &ctx);
+
+ if (!ctx.found) {
+ return njs_sprintf(buf, end, "\?\? \t\?\?:0 [0x%p]", addr);
+ }
+
+ name = ctx.functionname;
+
+ if (name == NULL || *name == '\0') {
+ name = "??";
+ }
+
+ if (ctx.filename != NULL) {
+ h = strrchr(ctx.filename, '/');
+ if (h != NULL) {
+ ctx.filename = h + 1;
+ }
+ }
+
+ return njs_sprintf(buf, end, "%s() %s:%ud [0x%p]", name,
+ ctx.filename ? ctx.filename : "??", ctx.line, addr);
+}
+
+
+static void
+njs_find_address_in_section(bfd *abfd, asection *section, void *data)
+{
+ bfd_vma vma;
+ bfd_size_type size;
+ njs_translate_address_t *ctx;
+
+ ctx = data;
+
+ if (ctx->found) {
+ return;
+ }
+
+ if ((bfd_section_flags(section) & SEC_ALLOC) == 0) {
+ return;
+ }
+
+ vma = bfd_section_vma(section);
+ if (ctx->pc < vma) {
+ return;
+ }
+
+ size = bfd_section_size(section);
+ if (ctx->pc >= vma + size) {
+ return;
+ }
+
+ ctx->found = bfd_find_nearest_line(abfd, section, ctx->syms, ctx->pc - vma,
+ &ctx->filename, &ctx->functionname,
+ &ctx->line);
+}
+
+
+static int
+njs_find_matching_file(struct dl_phdr_info *info, size_t size, void *data)
+{
+ long n;
+ const ElfW(Phdr) *phdr;
+
+ ElfW(Addr) load_base = info->dlpi_addr;
+ njs_file_match_t *match = data;
+
+ /*
+ * This code is modeled from Gfind_proc_info-lsb.c:callback()
+ * from libunwind.
+ */
+
+ phdr = info->dlpi_phdr;
+
+ for (n = info->dlpi_phnum; --n >= 0; phdr++) {
+ if (phdr->p_type == PT_LOAD) {
+ ElfW(Addr) vaddr = phdr->p_vaddr + load_base;
+
+ if (match->address >= vaddr
+ && match->address < vaddr + phdr->p_memsz)
+ {
+ /* we found a match */
+ match->file = info->dlpi_name;
+ match->base = info->dlpi_addr;
+ }
+ }
+ }
+
+ return 0;
+}
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_addr2line.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/njs_addr2line.h Tue Jun 28 22:36:30 2022 -0700
@@ -0,0 +1,22 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) Nginx, Inc.
+ */
+
+#ifndef _NJS_ADDR2LINE_H_INCLUDED_
+#define _NJS_ADDR2LINE_H_INCLUDED_
+
+
+ u_char *_njs_addr2line(u_char *buf, u_char *end, void *address);
+
+
+#if defined(NJS_HAVE_LIBBFD) && defined(NJS_HAVE_DL_ITERATE_PHDR)
+#define NJS_HAVE_ADDR2LINE 1
+#define njs_addr2line(buf, end, addr) _njs_addr2line(buf, end, addr)
+#else
+#define njs_addr2line(buf, end, addr) \
+ njs_sprintf(buf, end, "\?\?() \?\?:0 [0x%p]", addr)
+#endif
+
+#endif /* _NJS_ADDR2LINE_H_INCLUDED_ */
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_function.c
--- a/src/njs_function.c Wed Jun 22 23:37:27 2022 -0700
+++ b/src/njs_function.c Tue Jun 28 22:36:30 2022 -0700
@@ -711,15 +711,18 @@ njs_function_native_call(njs_vm_t *vm)
native = vm->top_frame;
function = native->function;
-#ifdef NJS_OPCODE_DEBUG
- njs_str_t name;
+#ifdef NJS_DEBUG_OPCODE
+ njs_str_t name;
+
+ if (vm->options.opcode_debug) {
- ret = njs_builtin_match_native_function(vm, function, &name);
- if (ret != NJS_OK) {
- name = njs_entry_unknown;
- }
+ ret = njs_builtin_match_native_function(vm, function, &name);
+ if (ret != NJS_OK) {
+ name = njs_str_value("unmapped");
+ }
- njs_printf("CALL NATIVE %V\n", &name);
+ njs_printf("CALL NATIVE %V %P\n", &name, function->u.native);
+ }
#endif
if (njs_fast_path(function->bound == NULL)) {
@@ -737,6 +740,14 @@ njs_function_native_call(njs_vm_t *vm)
}
ret = call(vm, native->arguments, native->nargs, function->magic8);
+
+#ifdef NJS_DEBUG_OPCODE
+ if (vm->options.opcode_debug) {
+ njs_printf("CALL NATIVE RETCODE: %i %V %P\n", ret, &name,
+ function->u.native);
+ }
+#endif
+
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_main.h
--- a/src/njs_main.h Wed Jun 22 23:37:27 2022 -0700
+++ b/src/njs_main.h Tue Jun 28 22:36:30 2022 -0700
@@ -37,6 +37,7 @@
#include <njs_utils.h>
#include <njs_sprintf.h>
#include <njs_assert.h>
+#include <njs_addr2line.h>
#include <njs_regex.h>
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_shell.c
--- a/src/njs_shell.c Wed Jun 22 23:37:27 2022 -0700
+++ b/src/njs_shell.c Tue Jun 28 22:36:30 2022 -0700
@@ -36,6 +36,7 @@ typedef struct {
uint8_t version;
uint8_t ast;
uint8_t unhandled_rejection;
+ uint8_t opcode_debug;
int exit_code;
char *file;
@@ -272,6 +273,9 @@ main(int argc, char **argv)
vm_options.sandbox = opts.sandbox;
vm_options.unsafe = !opts.safe;
vm_options.module = opts.module;
+#ifdef NJS_DEBUG_OPCODE
+ vm_options.opcode_debug = opts.opcode_debug;
+#endif
vm_options.ops = &njs_console_ops;
vm_options.addons = njs_console_addon_modules;
@@ -334,6 +338,9 @@ njs_options_parse(njs_opts_t *opts, int
" -d print disassembled code.\n"
" -e set failure exit code.\n"
" -f disabled denormals mode.\n"
+#ifdef NJS_DEBUG_OPCODE
+ " -o enable opcode debug.\n"
+#endif
" -p set path prefix for modules.\n"
" -q disable interactive introduction prompt.\n"
" -r ignore unhandled promise rejection.\n"
@@ -410,6 +417,12 @@ njs_options_parse(njs_opts_t *opts, int
opts->denormals = 0;
break;
+#ifdef NJS_DEBUG_OPCODE
+ case 'o':
+ opts->opcode_debug = 1;
+ break;
+#endif
+
case 'p':
if (++i < argc) {
opts->n_paths++;
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_sprintf.c
--- a/src/njs_sprintf.c Wed Jun 22 23:37:27 2022 -0700
+++ b/src/njs_sprintf.c Tue Jun 28 22:36:30 2022 -0700
@@ -27,6 +27,7 @@
* %*s length and string
*
* %p void *
+ * %P symbolized function address
* %b njs_bool_t
* %V njs_str_t *
* %Z '\0'
@@ -372,6 +373,11 @@ njs_vsprintf(u_char *buf, u_char *end, c
*/
goto number;
+ case 'P':
+ buf = njs_addr2line(buf, end, va_arg(args, void *));
+ fmt++;
+ continue;
+
case 'c':
d = va_arg(args, int);
*buf++ = (u_char) (d & 0xFF);
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_vmcode.c
--- a/src/njs_vmcode.c Wed Jun 22 23:37:27 2022 -0700
+++ b/src/njs_vmcode.c Tue Jun 28 22:36:30 2022 -0700
@@ -165,8 +165,10 @@ next:
* as a single unsigned comparision.
*/
-#ifdef NJS_OPCODE_DEBUG
- njs_disassemble(pc, NULL, 1, NULL);
+#ifdef NJS_DEBUG_OPCODE
+ if (vm->options.opcode_debug) {
+ njs_disassemble(pc, NULL, 1, NULL);
+ }
#endif
if (op > NJS_VMCODE_NORET) {
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/njs_vmcode.h
--- a/src/njs_vmcode.h Wed Jun 22 23:37:27 2022 -0700
+++ b/src/njs_vmcode.h Tue Jun 28 22:36:30 2022 -0700
@@ -450,9 +450,9 @@ njs_int_t njs_vmcode_interpreter(njs_vm_
njs_object_t *njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor);
-#ifdef NJS_OPCODE_DEBUG
+#ifdef NJS_DEBUG_OPCODE
#define njs_vmcode_debug(vm, pc, prefix) { \
- do { \
+ if (vm->options.opcode_debug) do { \
njs_vm_code_t *code; \
\
code = njs_lookup_code(vm, pc); \
diff -r 20ee5213e3c4 -r 8fe7d9723477 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Wed Jun 22 23:37:27 2022 -0700
+++ b/src/test/njs_unit_test.c Tue Jun 28 22:36:30 2022 -0700
@@ -13269,7 +13269,7 @@ static njs_unit_test_t njs_test[] =
njs_str("5") },
{ njs_str("var a = (new Function('return [' + ','.repeat(2**16) + ']'))();"
- "njs.dump(a)"),
+ "njs.dump(a)"),
njs_str("[<65536 empty items>]") },
{ njs_str("(new Function('var a = 7; return a' + '= a'.repeat(2**13)))()"),
@@ -23415,6 +23415,43 @@ njs_to_int32_test(njs_vm_t *vm, njs_opts
}
+#ifdef NJS_HAVE_ADDR2LINE
+static njs_int_t
+njs_addr2line_test(njs_vm_t *vm, njs_opts_t *opts, njs_stat_t *stat)
+{
+ njs_str_t v;
+ njs_uint_t i;
+ u_char buf[512];
+
+ static const struct {
+ void *fp;
+ const char *name;
+ } tests[] = {
+ { njs_addr2line_test, njs_stringify(njs_addr2line_test) },
+ { njs_to_int32_test, njs_stringify(njs_to_int32_test) },
+ };
+
+ for (i = 0; i < njs_nitems(tests); i++) {
+ v.start = buf;
+ v.length = njs_sprintf(buf, &buf[512], "%P", tests[i].fp) - buf;
+
+ if (memcmp(buf, tests[i].name, njs_strlen(tests[i].name))) {
+ njs_printf("njs_addr2line_test(%p):\n"
+ "expected: %s\n got: %V\n",
+ tests[i].fp, tests[i].name, &v);
+
+ stat->failed++;
+ continue;
+ }
+
+ stat->passed++;
+ }
+
+ return NJS_OK;
+}
+#endif
+
+
static njs_int_t
njs_vm_internal_api_test(njs_unit_test_t unused[], size_t num, njs_str_t *name,
njs_opts_t *opts, njs_stat_t *stat)
@@ -23443,6 +23480,10 @@ njs_vm_internal_api_test(njs_unit_test_t
njs_str("njs_string_to_index_test") },
{ njs_to_int32_test,
njs_str("njs_to_int32_test") },
+#ifdef NJS_HAVE_ADDR2LINE
+ { njs_addr2line_test,
+ njs_str("njs_addr2line_test") },
+#endif
};
vm = NULL;
More information about the nginx-devel
mailing list