Linux crash native stacks only have 1 line
Alexander Miloslavskiy
alexandr.miloslavskiy at gmail.com
Wed Apr 8 15:08:32 UTC 2020
On 08.04.2020 16:25, Volker Simonis wrote:
> Libjvm.so is already linked against libgcc anyway (either statically
> or dynamically, depending on the "--with-stdc++lib" configure option".
I understand that this means that yes, libgcc is fine to use.
> But the man page for "backtrace()" mentions;
>
> These functions make some assumptions about how a function's return
> address is stored on the stack. Note the following:
> * Omission of the frame pointers (as implied by any of gcc(1)'s
> nonzero optimization levels) may cause these assumptions to be
> violated.
> * Inlined functions do not have stack frames.
> * Tail-call optimization causes one stack frame to replace another.
>
> So I'm not sure if the result will be really better.
Luckily, 'backtrace()' is good enough. In fact, I would be surprised if
it was too dumb.
Try it yourself:
----------------
#include <gtk/gtk.h>
#include <stdio.h>
#include <csignal>
#include <execinfo.h>
void OnButtonClicked(GtkWidget*, gpointer*) {
void* myBacktrace[256];
int length = backtrace(myBacktrace, 256);
for (int i = 0; i < length; i++) {
printf("backtrace[%d] = %p\n", i, myBacktrace[i]);
}
std::raise(SIGINT);
}
int main(int argc, char **argv) {
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
gtk_window_resize(GTK_WINDOW(window), 200, 100);
GtkWidget *button = gtk_button_new_with_label("Test");
gtk_container_add(GTK_CONTAINER(window), button);
g_signal_connect(button, "clicked", G_CALLBACK(OnButtonClicked), 0);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
----------------
Compile with -O2:
g++ -O2 -g Snippet.cpp -o Snippet `pkg-config --cflags gtk+-3.0`
`pkg-config --libs gtk+-3.0`
Run under GDB. When it stops, run gdb `bt`.
I see that `backtrace()` is almost perfect!
It's easy to verify that there are no frame pointers, either by
inspecting stack with `x/32a $rsp` or by disassembling like `disas
g_signal_emit`.
>
> Also notice that "VMError::print_native_stack()" prints a mixed
> Native/Java stack which ideally looks something like:
> If you use a helper function like "backtrace()", it will only unwind
> native frames until it reaches the first Java frame because it won't
> be able to unwind Java frames. Even gdb can not do that , because it
> doesn't know the frame layout of HotSpots JIT compiled or interpreted
> frames.
Right, that's why I intend to use `_Unwind_Backtrace` directly instead
of `backtrace()`. The first is a powerful iterator-like API, second is
simple to use but without any advanced stuff.
How does that sound to you?
More information about the hotspot-dev
mailing list