Branch data Line data Source code
1 : : /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 : : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
3 : : // SPDX-FileCopyrightText: 2009 Red Hat, Inc.
4 : :
5 : : #include <config.h>
6 : :
7 : : #include <stdio.h> // for stderr
8 : :
9 : : #include <algorithm> // for max
10 : : #include <sstream>
11 : : #include <string>
12 : :
13 : : #include <glib-object.h>
14 : : #include <glib.h>
15 : :
16 : : #include <js/Printer.h>
17 : : #include <js/TypeDecls.h>
18 : : #include <js/Utility.h> // for UniqueChars
19 : : #include <js/friend/DumpFunctions.h>
20 : :
21 : : #include "gjs/auto.h"
22 : : #include "gjs/context-private.h"
23 : : #include "gjs/context.h"
24 : :
25 : 0 : void gjs_context_print_stack_stderr(GjsContext* self) {
26 : 0 : auto* cx = static_cast<JSContext*>(gjs_context_get_native_context(self));
27 : :
28 : 0 : g_printerr("== Stack trace for context %p ==\n", self);
29 : 0 : js::DumpBacktrace(cx, stderr);
30 : 0 : }
31 : :
32 : 0 : void gjs_dumpstack() {
33 : 0 : Gjs::SmartPointer<GList> contexts{gjs_context_get_all()};
34 : :
35 [ # # ]: 0 : for (GList* iter = contexts; iter; iter = iter->next) {
36 : 0 : Gjs::AutoUnref<GjsContext> gjs_context{GJS_CONTEXT(iter->data)};
37 : 0 : gjs_context_print_stack_stderr(gjs_context);
38 : 0 : }
39 : 0 : }
40 : :
41 : 44 : std::string gjs_dumpstack_string() {
42 : 44 : std::ostringstream all_traces;
43 : :
44 : 44 : Gjs::SmartPointer<GList> contexts{gjs_context_get_all()};
45 : 44 : js::Sprinter printer;
46 : :
47 [ + + ]: 88 : for (GList* iter = contexts; iter; iter = iter->next) {
48 : 44 : Gjs::AutoUnref<GjsContext> gjs_context{GJS_CONTEXT(iter->data)};
49 [ - + ]: 44 : if (!printer.init()) {
50 : 0 : all_traces << "No stack trace for context " << gjs_context.get()
51 : 0 : << ": out of memory\n\n";
52 : 0 : break;
53 : : }
54 : : auto* cx = static_cast<JSContext*>(
55 : 44 : gjs_context_get_native_context(gjs_context));
56 : 44 : js::DumpBacktrace(cx, printer);
57 : 44 : JS::UniqueChars trace = printer.release();
58 : 44 : all_traces << "== Stack trace for context " << gjs_context.get()
59 : : << " ==\n"
60 : 44 : << trace.get() << "\n";
61 [ + - ]: 44 : }
62 : 44 : std::string out = all_traces.str();
63 : : // COMPAT: 0zu in C++23
64 : 44 : out.resize(std::max(out.size() - 2, size_t{0}));
65 : :
66 : 88 : return out;
67 : 44 : }
|