From eaff0f0d3f7828c2acd9ebde4979acc0b3fa43b5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 19 Jan 2005 01:15:12 +0000 Subject: [PATCH] implemented wxStackWalker for Unix (using glibc-specific methods); moved wxUSE_STACKWALKER to common setu_inc.h git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31474 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 123 ++++++++++++++++++--- build/bakefiles/files.bkl | 2 + configure | 208 +++++++++++++++++++++++++++++++++++- configure.in | 54 ++++++++++ include/wx/mac/setup0.h | 12 +++ include/wx/msw/setup0.h | 18 ++-- include/wx/msw/stackwalk.h | 4 +- include/wx/setup_inc.h | 9 ++ include/wx/stackwalk.h | 12 +++ include/wx/unix/stackwalk.h | 69 ++++++++++++ samples/console/console.cpp | 76 ++++++++++++- setup.h.in | 5 + src/unix/stackwalk.cpp | 188 ++++++++++++++++++++++++++++++++ 13 files changed, 753 insertions(+), 27 deletions(-) create mode 100644 include/wx/unix/stackwalk.h create mode 100644 src/unix/stackwalk.cpp diff --git a/Makefile.in b/Makefile.in index e9310ca894..d9e7392549 100644 --- a/Makefile.in +++ b/Makefile.in @@ -403,6 +403,7 @@ ALL_BASE_SOURCES = \ src/unix/dlunix.cpp \ src/unix/mimetype.cpp \ src/unix/snglinst.cpp \ + src/unix/stackwalk.cpp \ src/unix/stdpaths.cpp \ src/unix/threadpsx.cpp \ src/msw/basemsw.cpp \ @@ -1196,6 +1197,7 @@ COND_PLATFORM_UNIX_1_BASE_PLATFORM_HDR = \ wx/unix/execute.h \ wx/unix/mimetype.h \ wx/unix/pipe.h \ + wx/unix/stackwalk.h \ wx/unix/stdpaths.h @COND_PLATFORM_UNIX_1@BASE_PLATFORM_HDR = $(COND_PLATFORM_UNIX_1_BASE_PLATFORM_HDR) COND_PLATFORM_WIN32_1_BASE_PLATFORM_HDR = \ @@ -1219,6 +1221,7 @@ COND_TOOLKIT_COCOA_BASE_PLATFORM_HDR = \ wx/unix/execute.h \ wx/unix/mimetype.h \ wx/unix/pipe.h \ + wx/unix/stackwalk.h \ wx/unix/stdpaths.h @COND_TOOLKIT_COCOA@BASE_PLATFORM_HDR = $(COND_TOOLKIT_COCOA_BASE_PLATFORM_HDR) COND_TOOLKIT_MAC_BASE_PLATFORM_HDR = \ @@ -2483,6 +2486,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS = \ monodll_dlunix.o \ monodll_mimetype.o \ monodll_snglinst.o \ + monodll_stackwalk.o \ monodll_stdpaths.o \ monodll_threadpsx.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS) @@ -2511,6 +2515,7 @@ COND_TOOLKIT____BASE_MACOSX_SRC_OBJECTS = \ monodll_dlunix.o \ monodll_mimetype.o \ monodll_snglinst.o \ + monodll_stackwalk.o \ monodll_stdpaths.o \ monodll_threadpsx.o \ monodll_cfstring.o \ @@ -2522,6 +2527,7 @@ COND_TOOLKIT_COCOA___BASE_MACOSX_SRC_OBJECTS = \ monodll_dlunix.o \ monodll_mimetype.o \ monodll_snglinst.o \ + monodll_stackwalk.o \ monodll_stdpaths.o \ monodll_threadpsx.o \ monodll_cfstring.o \ @@ -2533,6 +2539,7 @@ COND_TOOLKIT_GTK___BASE_MACOSX_SRC_OBJECTS = \ monodll_dlunix.o \ monodll_mimetype.o \ monodll_snglinst.o \ + monodll_stackwalk.o \ monodll_stdpaths.o \ monodll_threadpsx.o \ monodll_cfstring.o \ @@ -2557,6 +2564,7 @@ COND_TOOLKIT_MOTIF___BASE_MACOSX_SRC_OBJECTS = \ monodll_dlunix.o \ monodll_mimetype.o \ monodll_snglinst.o \ + monodll_stackwalk.o \ monodll_stdpaths.o \ monodll_threadpsx.o \ monodll_cfstring.o \ @@ -2568,6 +2576,7 @@ COND_TOOLKIT_X11___BASE_MACOSX_SRC_OBJECTS = \ monodll_dlunix.o \ monodll_mimetype.o \ monodll_snglinst.o \ + monodll_stackwalk.o \ monodll_stdpaths.o \ monodll_threadpsx.o \ monodll_cfstring.o \ @@ -3916,6 +3925,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_1 = \ monolib_dlunix.o \ monolib_mimetype.o \ monolib_snglinst.o \ + monolib_stackwalk.o \ monolib_stdpaths.o \ monolib_threadpsx.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS_1 = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_1) @@ -3944,6 +3954,7 @@ COND_TOOLKIT____BASE_MACOSX_SRC_OBJECTS_1 = \ monolib_dlunix.o \ monolib_mimetype.o \ monolib_snglinst.o \ + monolib_stackwalk.o \ monolib_stdpaths.o \ monolib_threadpsx.o \ monolib_cfstring.o \ @@ -3955,6 +3966,7 @@ COND_TOOLKIT_COCOA___BASE_MACOSX_SRC_OBJECTS_1 = \ monolib_dlunix.o \ monolib_mimetype.o \ monolib_snglinst.o \ + monolib_stackwalk.o \ monolib_stdpaths.o \ monolib_threadpsx.o \ monolib_cfstring.o \ @@ -3966,6 +3978,7 @@ COND_TOOLKIT_GTK___BASE_MACOSX_SRC_OBJECTS_1 = \ monolib_dlunix.o \ monolib_mimetype.o \ monolib_snglinst.o \ + monolib_stackwalk.o \ monolib_stdpaths.o \ monolib_threadpsx.o \ monolib_cfstring.o \ @@ -3990,6 +4003,7 @@ COND_TOOLKIT_MOTIF___BASE_MACOSX_SRC_OBJECTS_1 = \ monolib_dlunix.o \ monolib_mimetype.o \ monolib_snglinst.o \ + monolib_stackwalk.o \ monolib_stdpaths.o \ monolib_threadpsx.o \ monolib_cfstring.o \ @@ -4001,6 +4015,7 @@ COND_TOOLKIT_X11___BASE_MACOSX_SRC_OBJECTS_1 = \ monolib_dlunix.o \ monolib_mimetype.o \ monolib_snglinst.o \ + monolib_stackwalk.o \ monolib_stdpaths.o \ monolib_threadpsx.o \ monolib_cfstring.o \ @@ -5386,6 +5401,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_2 = \ basedll_dlunix.o \ basedll_mimetype.o \ basedll_snglinst.o \ + basedll_stackwalk.o \ basedll_stdpaths.o \ basedll_threadpsx.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS_2 = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_2) @@ -5414,6 +5430,7 @@ COND_TOOLKIT____BASE_MACOSX_SRC_OBJECTS_2 = \ basedll_dlunix.o \ basedll_mimetype.o \ basedll_snglinst.o \ + basedll_stackwalk.o \ basedll_stdpaths.o \ basedll_threadpsx.o \ basedll_cfstring.o \ @@ -5425,6 +5442,7 @@ COND_TOOLKIT_COCOA___BASE_MACOSX_SRC_OBJECTS_2 = \ basedll_dlunix.o \ basedll_mimetype.o \ basedll_snglinst.o \ + basedll_stackwalk.o \ basedll_stdpaths.o \ basedll_threadpsx.o \ basedll_cfstring.o \ @@ -5436,6 +5454,7 @@ COND_TOOLKIT_GTK___BASE_MACOSX_SRC_OBJECTS_2 = \ basedll_dlunix.o \ basedll_mimetype.o \ basedll_snglinst.o \ + basedll_stackwalk.o \ basedll_stdpaths.o \ basedll_threadpsx.o \ basedll_cfstring.o \ @@ -5460,6 +5479,7 @@ COND_TOOLKIT_MOTIF___BASE_MACOSX_SRC_OBJECTS_2 = \ basedll_dlunix.o \ basedll_mimetype.o \ basedll_snglinst.o \ + basedll_stackwalk.o \ basedll_stdpaths.o \ basedll_threadpsx.o \ basedll_cfstring.o \ @@ -5471,6 +5491,7 @@ COND_TOOLKIT_X11___BASE_MACOSX_SRC_OBJECTS_2 = \ basedll_dlunix.o \ basedll_mimetype.o \ basedll_snglinst.o \ + basedll_stackwalk.o \ basedll_stdpaths.o \ basedll_threadpsx.o \ basedll_cfstring.o \ @@ -5526,6 +5547,7 @@ COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_3 = \ baselib_dlunix.o \ baselib_mimetype.o \ baselib_snglinst.o \ + baselib_stackwalk.o \ baselib_stdpaths.o \ baselib_threadpsx.o @COND_PLATFORM_UNIX_1@__BASE_PLATFORM_SRC_OBJECTS_3 = $(COND_PLATFORM_UNIX_1___BASE_PLATFORM_SRC_OBJECTS_3) @@ -5554,6 +5576,7 @@ COND_TOOLKIT____BASE_MACOSX_SRC_OBJECTS_3 = \ baselib_dlunix.o \ baselib_mimetype.o \ baselib_snglinst.o \ + baselib_stackwalk.o \ baselib_stdpaths.o \ baselib_threadpsx.o \ baselib_cfstring.o \ @@ -5565,6 +5588,7 @@ COND_TOOLKIT_COCOA___BASE_MACOSX_SRC_OBJECTS_3 = \ baselib_dlunix.o \ baselib_mimetype.o \ baselib_snglinst.o \ + baselib_stackwalk.o \ baselib_stdpaths.o \ baselib_threadpsx.o \ baselib_cfstring.o \ @@ -5576,6 +5600,7 @@ COND_TOOLKIT_GTK___BASE_MACOSX_SRC_OBJECTS_3 = \ baselib_dlunix.o \ baselib_mimetype.o \ baselib_snglinst.o \ + baselib_stackwalk.o \ baselib_stdpaths.o \ baselib_threadpsx.o \ baselib_cfstring.o \ @@ -5600,6 +5625,7 @@ COND_TOOLKIT_MOTIF___BASE_MACOSX_SRC_OBJECTS_3 = \ baselib_dlunix.o \ baselib_mimetype.o \ baselib_snglinst.o \ + baselib_stackwalk.o \ baselib_stdpaths.o \ baselib_threadpsx.o \ baselib_cfstring.o \ @@ -5611,6 +5637,7 @@ COND_TOOLKIT_X11___BASE_MACOSX_SRC_OBJECTS_3 = \ baselib_dlunix.o \ baselib_mimetype.o \ baselib_snglinst.o \ + baselib_stackwalk.o \ baselib_stdpaths.o \ baselib_threadpsx.o \ baselib_cfstring.o \ @@ -9944,9 +9971,6 @@ monodll_regconf.o: $(srcdir)/src/msw/regconf.cpp $(MONODLL_ODEP) monodll_registry.o: $(srcdir)/src/msw/registry.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< -monodll_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(MONODLL_ODEP) - $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< - monodll_time.o: $(srcdir)/src/msw/wince/time.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< @@ -10526,6 +10550,27 @@ monodll_gprint.o: $(srcdir)/src/gtk/gnome/gprint.cpp $(MONODLL_ODEP) @COND_PLATFORM_WIN32_1@monodll_snglinst.o: $(srcdir)/src/msw/snglinst.cpp $(MONODLL_ODEP) @COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< +@COND_PLATFORM_UNIX_1@monodll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONODLL_ODEP) +@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@monodll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONODLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@monodll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONODLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@monodll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONODLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@monodll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONODLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_@monodll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONODLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< + +@COND_PLATFORM_WIN32_1@monodll_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(MONODLL_ODEP) +@COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< + @COND_PLATFORM_UNIX_1@monodll_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(MONODLL_ODEP) @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $< @@ -13304,9 +13349,6 @@ monolib_regconf.o: $(srcdir)/src/msw/regconf.cpp $(MONOLIB_ODEP) monolib_registry.o: $(srcdir)/src/msw/registry.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< -monolib_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(MONOLIB_ODEP) - $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< - monolib_time.o: $(srcdir)/src/msw/wince/time.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< @@ -13886,6 +13928,27 @@ monolib_gprint.o: $(srcdir)/src/gtk/gnome/gprint.cpp $(MONOLIB_ODEP) @COND_PLATFORM_WIN32_1@monolib_snglinst.o: $(srcdir)/src/msw/snglinst.cpp $(MONOLIB_ODEP) @COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< +@COND_PLATFORM_UNIX_1@monolib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONOLIB_ODEP) +@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@monolib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONOLIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@monolib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONOLIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@monolib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONOLIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@monolib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONOLIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_@monolib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(MONOLIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< + +@COND_PLATFORM_WIN32_1@monolib_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(MONOLIB_ODEP) +@COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< + @COND_PLATFORM_UNIX_1@monolib_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(MONOLIB_ODEP) @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $< @@ -16664,9 +16727,6 @@ basedll_regconf.o: $(srcdir)/src/msw/regconf.cpp $(BASEDLL_ODEP) basedll_registry.o: $(srcdir)/src/msw/registry.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< -basedll_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(BASEDLL_ODEP) - $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< - basedll_time.o: $(srcdir)/src/msw/wince/time.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< @@ -16832,6 +16892,27 @@ basedll_uma.o: $(srcdir)/src/mac/carbon/uma.cpp $(BASEDLL_ODEP) @COND_PLATFORM_WIN32_1@basedll_snglinst.o: $(srcdir)/src/msw/snglinst.cpp $(BASEDLL_ODEP) @COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< +@COND_PLATFORM_UNIX_1@basedll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASEDLL_ODEP) +@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@basedll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASEDLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@basedll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASEDLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@basedll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASEDLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@basedll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASEDLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_@basedll_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASEDLL_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< + +@COND_PLATFORM_WIN32_1@basedll_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(BASEDLL_ODEP) +@COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< + @COND_PLATFORM_UNIX_1@basedll_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(BASEDLL_ODEP) @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $< @@ -17168,9 +17249,6 @@ baselib_regconf.o: $(srcdir)/src/msw/regconf.cpp $(BASELIB_ODEP) baselib_registry.o: $(srcdir)/src/msw/registry.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< -baselib_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(BASELIB_ODEP) - $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< - baselib_time.o: $(srcdir)/src/msw/wince/time.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< @@ -17336,6 +17414,27 @@ baselib_uma.o: $(srcdir)/src/mac/carbon/uma.cpp $(BASELIB_ODEP) @COND_PLATFORM_WIN32_1@baselib_snglinst.o: $(srcdir)/src/msw/snglinst.cpp $(BASELIB_ODEP) @COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< +@COND_PLATFORM_UNIX_1@baselib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASELIB_ODEP) +@COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@baselib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASELIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_COCOA@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@baselib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASELIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_GTK@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@baselib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASELIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_X11@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@baselib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASELIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_MOTIF@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< + +@COND_PLATFORM_MACOSX_1_TOOLKIT_@baselib_stackwalk.o: $(srcdir)/src/unix/stackwalk.cpp $(BASELIB_ODEP) +@COND_PLATFORM_MACOSX_1_TOOLKIT_@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< + +@COND_PLATFORM_WIN32_1@baselib_stackwalk.o: $(srcdir)/src/msw/stackwalk.cpp $(BASELIB_ODEP) +@COND_PLATFORM_WIN32_1@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< + @COND_PLATFORM_UNIX_1@baselib_stdpaths.o: $(srcdir)/src/unix/stdpaths.cpp $(BASELIB_ODEP) @COND_PLATFORM_UNIX_1@ $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $< diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 9c09e2751f..cc3305c2cb 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -59,6 +59,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/unix/dlunix.cpp src/unix/mimetype.cpp src/unix/snglinst.cpp + src/unix/stackwalk.cpp src/unix/stdpaths.cpp src/unix/threadpsx.cpp @@ -71,6 +72,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/unix/execute.h wx/unix/mimetype.h wx/unix/pipe.h + wx/unix/stackwalk.h wx/unix/stdpaths.h diff --git a/configure b/configure index eb672cbf65..91be247107 100755 --- a/configure +++ b/configure @@ -904,6 +904,7 @@ Optional Features: --enable-ipc use interprocess communication (wxSocket etc.) --enable-apple_ieee use the Apple IEEE codec --enable-catch_segvs catch signals in wxApp::OnFatalException (Unix only) + --enable-backtrace use wxStackWalker class for getting backtraces --enable-cmdline use wxCmdLineParser class --enable-datetime use wxDateTime class --enable-dialupman use dialup network classes @@ -2069,6 +2070,7 @@ if test $DEBUG_CONFIGURE = 1; then DEFAULT_wxUSE_OPENGL=no DEFAULT_wxUSE_ON_FATAL_EXCEPTION=no + DEFAULT_wxUSE_STACKWALKER=no DEFAULT_wxUSE_SNGLINST_CHECKER=no DEFAULT_wxUSE_STD_IOSTREAM=no DEFAULT_wxUSE_CMDLINE_PARSER=no @@ -2259,6 +2261,7 @@ else DEFAULT_wxUSE_OPENGL=no DEFAULT_wxUSE_ON_FATAL_EXCEPTION=yes + DEFAULT_wxUSE_STACKWALKER=yes DEFAULT_wxUSE_SNGLINST_CHECKER=yes DEFAULT_wxUSE_STD_IOSTREAM=no DEFAULT_wxUSE_CMDLINE_PARSER=yes @@ -4704,6 +4707,47 @@ echo "${ECHO_T}no" >&6 fi + enablestring= + echo "$as_me:$LINENO: checking for --${enablestring:-enable}-backtrace" >&5 +echo $ECHO_N "checking for --${enablestring:-enable}-backtrace... $ECHO_C" >&6 + no_cache=0 + # Check whether --enable-backtrace or --disable-backtrace was given. +if test "${enable_backtrace+set}" = set; then + enableval="$enable_backtrace" + + if test "$enableval" = yes; then + ac_cv_use_backtrace='wxUSE_STACKWALKER=yes' + else + ac_cv_use_backtrace='wxUSE_STACKWALKER=no' + fi + +else + + LINE=`grep "wxUSE_STACKWALKER" ${wx_arg_cache_file}` + if test "x$LINE" != x ; then + eval "DEFAULT_$LINE" + else + no_cache=1 + fi + + ac_cv_use_backtrace='wxUSE_STACKWALKER='$DEFAULT_wxUSE_STACKWALKER + +fi; + + eval "$ac_cv_use_backtrace" + if test "$no_cache" != 1; then + echo $ac_cv_use_backtrace >> ${wx_arg_cache_file}.tmp + fi + + if test "$wxUSE_STACKWALKER" = yes; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + fi + + enablestring= echo "$as_me:$LINENO: checking for --${enablestring:-enable}-cmdline" >&5 echo $ECHO_N "checking for --${enablestring:-enable}-cmdline... $ECHO_C" >&6 @@ -29984,6 +30028,161 @@ _ACEOF fi fi +if test "$wxUSE_STACKWALKER" = "yes" -a "$wxUSE_UNIX" = "yes"; then + + + ac_ext=cc +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + echo "$as_me:$LINENO: checking for backtrace() in " >&5 +echo $ECHO_N "checking for backtrace() in ... $ECHO_C" >&6 +if test "${wx_cv_func_backtrace+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + + void *trace[1]; + char **messages; + + backtrace(trace, 1); + messages = backtrace_symbols(trace, 1); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + wx_cv_func_backtrace=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +wx_cv_func_backtrace=no + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + + +fi +echo "$as_me:$LINENO: result: $wx_cv_func_backtrace" >&5 +echo "${ECHO_T}$wx_cv_func_backtrace" >&6 + + + if test "$wx_cv_func_backtrace" = "no"; then + { echo "$as_me:$LINENO: WARNING: backtrace() is not available, wxStackWalker will not be available" >&5 +echo "$as_me: WARNING: backtrace() is not available, wxStackWalker will not be available" >&2;} + wxUSE_STACKWALKER=no + else + echo "$as_me:$LINENO: checking for __cxa_demangle() in " >&5 +echo $ECHO_N "checking for __cxa_demangle() in ... $ECHO_C" >&6 +if test "${wx_cv_func_cxa_demangle+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ + + int rc; + __cxxabiv1::__cxa_demangle("foo", 0, 0, &rc); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + wx_cv_func_cxa_demangle=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +wx_cv_func_cxa_demangle=no + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + + +fi +echo "$as_me:$LINENO: result: $wx_cv_func_cxa_demangle" >&5 +echo "${ECHO_T}$wx_cv_func_cxa_demangle" >&6 + + if test "$wx_cv_func_cxa_demangle" = "yes"; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_CXA_DEMANGLE 1 +_ACEOF + + fi + fi + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi + for ac_func in mkstemp mktemp @@ -34843,6 +35042,13 @@ _ACEOF fi +if test "$wxUSE_STACKWALKER" = "yes"; then + cat >>confdefs.h <<\_ACEOF +#define wxUSE_STACKWALKER 1 +_ACEOF + +fi + if test "$wxUSE_SNGLINST_CHECKER" = "yes"; then cat >>confdefs.h <<\_ACEOF #define wxUSE_SNGLINST_CHECKER 1 @@ -40202,8 +40408,6 @@ fi - - BAKEFILE_AUTOCONF_INC_M4_VERSION="0.1.4" diff --git a/configure.in b/configure.in index 0bf2f2b30e..bc996640d0 100644 --- a/configure.in +++ b/configure.in @@ -417,6 +417,7 @@ if test $DEBUG_CONFIGURE = 1; then DEFAULT_wxUSE_OPENGL=no DEFAULT_wxUSE_ON_FATAL_EXCEPTION=no + DEFAULT_wxUSE_STACKWALKER=no DEFAULT_wxUSE_SNGLINST_CHECKER=no DEFAULT_wxUSE_STD_IOSTREAM=no DEFAULT_wxUSE_CMDLINE_PARSER=no @@ -607,6 +608,7 @@ else DEFAULT_wxUSE_OPENGL=no DEFAULT_wxUSE_ON_FATAL_EXCEPTION=yes + DEFAULT_wxUSE_STACKWALKER=yes DEFAULT_wxUSE_SNGLINST_CHECKER=yes DEFAULT_wxUSE_STD_IOSTREAM=no DEFAULT_wxUSE_CMDLINE_PARSER=yes @@ -881,6 +883,7 @@ WX_ARG_ENABLE(ipc, [ --enable-ipc use interprocess communi dnl please keep the settings below in alphabetical order WX_ARG_ENABLE(apple_ieee, [ --enable-apple_ieee use the Apple IEEE codec], wxUSE_APPLE_IEEE) WX_ARG_ENABLE(catch_segvs, [ --enable-catch_segvs catch signals in wxApp::OnFatalException (Unix only)], wxUSE_ON_FATAL_EXCEPTION) +WX_ARG_ENABLE(backtrace, [ --enable-backtrace use wxStackWalker class for getting backtraces], wxUSE_STACKWALKER) WX_ARG_ENABLE(cmdline, [ --enable-cmdline use wxCmdLineParser class], wxUSE_CMDLINE_PARSER) WX_ARG_ENABLE(datetime, [ --enable-datetime use wxDateTime class], wxUSE_DATETIME) WX_ARG_ENABLE(dialupman, [ --enable-dialupman use dialup network classes], wxUSE_DIALUP_MANAGER) @@ -3759,6 +3762,53 @@ if test "$wxUSE_ON_FATAL_EXCEPTION" = "yes" -a "$wxUSE_UNIX" = "yes"; then fi fi +dnl backtrace() and backtrace_symbols() for wxStackWalker +if test "$wxUSE_STACKWALKER" = "yes" -a "$wxUSE_UNIX" = "yes"; then + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + AC_CACHE_CHECK([for backtrace() in ], wx_cv_func_backtrace, + [ + AC_TRY_COMPILE([#include ], + [ + void *trace[1]; + char **messages; + + backtrace(trace, 1); + messages = backtrace_symbols(trace, 1); + ], + wx_cv_func_backtrace=yes, + wx_cv_func_backtrace=no + ) + ] + ) + + + if test "$wx_cv_func_backtrace" = "no"; then + AC_MSG_WARN([backtrace() is not available, wxStackWalker will not be available]) + wxUSE_STACKWALKER=no + else + AC_CACHE_CHECK([for __cxa_demangle() in ], wx_cv_func_cxa_demangle, + [ + AC_TRY_COMPILE([#include ], + [ + int rc; + __cxxabiv1::__cxa_demangle("foo", 0, 0, &rc); + ], + wx_cv_func_cxa_demangle=yes, + wx_cv_func_cxa_demangle=no + ) + ] + ) + + if test "$wx_cv_func_cxa_demangle" = "yes"; then + AC_DEFINE(HAVE_CXA_DEMANGLE) + fi + fi + + AC_LANG_RESTORE +fi + dnl check for the function for temp files creation AC_CHECK_FUNCS(mkstemp mktemp, break) @@ -4718,6 +4768,10 @@ if test "$wxUSE_ON_FATAL_EXCEPTION" = "yes"; then AC_DEFINE(wxUSE_ON_FATAL_EXCEPTION) fi +if test "$wxUSE_STACKWALKER" = "yes"; then + AC_DEFINE(wxUSE_STACKWALKER) +fi + if test "$wxUSE_SNGLINST_CHECKER" = "yes"; then AC_DEFINE(wxUSE_SNGLINST_CHECKER) fi diff --git a/include/wx/mac/setup0.h b/include/wx/mac/setup0.h index a91a4067f6..ebe1069425 100644 --- a/include/wx/mac/setup0.h +++ b/include/wx/mac/setup0.h @@ -128,6 +128,15 @@ #define wxUSE_ON_FATAL_EXCEPTION 0 #endif +// Set this to 1 to be able to generate a human-readable (unlike +// machine-readable minidumop created by wxCrashReport::Generate()) stack back +// trace when your program crashes using wxStackWalker +// +// Default is 1 if supported by the compiler. +// +// Recommended setting: 1, set to 0 if your programs never crash +#define wxUSE_STACKWALKER 1 + // ---------------------------------------------------------------------------- // Unicode support // ---------------------------------------------------------------------------- @@ -1039,6 +1048,9 @@ #undef wxUSE_STD_IOSTREAM #define wxUSE_STD_IOSTREAM 1 + + #undef wxUSE_STACKWALKER + #define wxUSE_STACKWALKER 0 #endif // things not implemented under Mac diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index 88699aa4e5..42e599b68b 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -127,6 +127,15 @@ #define wxUSE_ON_FATAL_EXCEPTION 0 #endif +// Set this to 1 to be able to generate a human-readable (unlike +// machine-readable minidumop created by wxCrashReport::Generate()) stack back +// trace when your program crashes using wxStackWalker +// +// Default is 1 if supported by the compiler. +// +// Recommended setting: 1, set to 0 if your programs never crash +#define wxUSE_STACKWALKER 1 + // ---------------------------------------------------------------------------- // Unicode support // ---------------------------------------------------------------------------- @@ -1111,15 +1120,6 @@ // Recommended setting: 1, set to 0 if your programs never crash #define wxUSE_CRASHREPORT 1 -// Set this to 1 to be able to generate a human-readable (unlike -// machine-readable minidumop created by wxCrashReport::Generate()) stack back -// trace when your program crashes using wxStackWalker -// -// Default is 1 if supported by the compiler. -// -// Recommended setting: 1, set to 0 if your programs never crash -#define wxUSE_STACKWALKER 1 - // ---------------------------------------------------------------------------- // obsolete settings // ---------------------------------------------------------------------------- diff --git a/include/wx/msw/stackwalk.h b/include/wx/msw/stackwalk.h index b003181bc8..9c794e7db8 100644 --- a/include/wx/msw/stackwalk.h +++ b/include/wx/msw/stackwalk.h @@ -84,7 +84,9 @@ private: class WXDLLIMPEXP_BASE wxStackWalker : public wxStackWalkerBase { public: - wxStackWalker() { } + // we don't use ctor argument, it is for compatibility with Unix version + // only + wxStackWalker(const char * WXUNUSED(argv0) = NULL) { } virtual void Walk(size_t skip = 1); virtual void WalkFromException(); diff --git a/include/wx/setup_inc.h b/include/wx/setup_inc.h index 9ce5ddca88..be8284eba6 100644 --- a/include/wx/setup_inc.h +++ b/include/wx/setup_inc.h @@ -112,6 +112,15 @@ #define wxUSE_ON_FATAL_EXCEPTION 0 #endif +// Set this to 1 to be able to generate a human-readable (unlike +// machine-readable minidumop created by wxCrashReport::Generate()) stack back +// trace when your program crashes using wxStackWalker +// +// Default is 1 if supported by the compiler. +// +// Recommended setting: 1, set to 0 if your programs never crash +#define wxUSE_STACKWALKER 1 + // ---------------------------------------------------------------------------- // Unicode support // ---------------------------------------------------------------------------- diff --git a/include/wx/stackwalk.h b/include/wx/stackwalk.h index 5e8beacc91..298317ef7d 100644 --- a/include/wx/stackwalk.h +++ b/include/wx/stackwalk.h @@ -54,6 +54,9 @@ public: // return the instruction pointer offset from the start of the function size_t GetOffset() const { ConstCast()->OnGetName(); return m_offset; } + // get the module this function belongs to (not always available) + wxString GetModule() const { ConstCast()->OnGetName(); return m_module; } + // return true if we have the filename and line number for this frame bool HasSourceLocation() const { return !GetFileName().empty(); } @@ -101,7 +104,9 @@ protected: size_t m_level; wxString m_name, + m_module, m_filename; + size_t m_line; void *m_address; @@ -118,6 +123,9 @@ public: // ctor does nothing, use Walk() to walk the stack wxStackWalkerBase() { } + // dtor does nothing neither but should be virtual + virtual ~wxStackWalkerBase() { } + // enumerate stack frames from the current location, skipping the initial // number of them (this can be useful when Walk() is called from some known // location and you don't want to see the first few frames anyhow; also @@ -136,6 +144,10 @@ protected: #ifdef __WXMSW__ #include "wx/msw/stackwalk.h" +#elif defined(__UNIX__) + #include "wx/unix/stackwalk.h" +#else + #error "wxStackWalker is not supported, set wxUSE_STACKWALKER to 0" #endif #endif // wxUSE_STACKWALKER diff --git a/include/wx/unix/stackwalk.h b/include/wx/unix/stackwalk.h new file mode 100644 index 0000000000..77aebf52f3 --- /dev/null +++ b/include/wx/unix/stackwalk.h @@ -0,0 +1,69 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/unix/stackwalk.h +// Purpose: declaration of wxStackWalker for Unix +// Author: Vadim Zeitlin +// Modified by: +// Created: 2005-01-19 +// RCS-ID: $Id$ +// Copyright: (c) 2005 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_UNIX_STACKWALK_H_ +#define _WX_UNIX_STACKWALK_H_ + +// ---------------------------------------------------------------------------- +// wxStackFrame +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxStackFrame : public wxStackFrameBase +{ +public: + // arguments are the stack depth of this frame, its address and the return + // value of backtrace_symbols() for it + // + // NB: we don't copy syminfo pointer so it should have lifetime at least as + // long as ours + wxStackFrame(size_t level, void *address, const char *syminfo) + : wxStackFrameBase(level, address) + { + m_hasName = + m_hasLocation = false; + + m_syminfo = syminfo; + } + +protected: + virtual void OnGetName(); + virtual void OnGetLocation(); + +private: + const char *m_syminfo; + + bool m_hasName, + m_hasLocation; +}; + +// ---------------------------------------------------------------------------- +// wxStackWalker +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxStackWalker : public wxStackWalkerBase +{ +public: + // we need the full path to the program executable to be able to use + // addr2line, normally we can retrieve it from wxTheApp but if wxTheApp + // doesn't exist or doesn't have the correct value, the path may be given + // explicitly + wxStackWalker(const char *argv0 = NULL) { ms_exepath = argv0; } + + virtual void Walk(size_t skip = 1); + virtual void WalkFromException() { Walk(2); } + + static const wxString& GetExePath() { return ms_exepath; } + +private: + static wxString ms_exepath; +}; + +#endif // _WX_UNIX_STACKWALK_H_ diff --git a/samples/console/console.cpp b/samples/console/console.cpp index 3e7e57defe..1ad703cabd 100644 --- a/samples/console/console.cpp +++ b/samples/console/console.cpp @@ -74,6 +74,7 @@ #define TEST_SCOPEGUARD #define TEST_SNGLINST // #define TEST_SOCKETS --FIXME! (RN) + #define TEST_STACKWALKER #define TEST_STDPATHS #define TEST_STREAMS #define TEST_TEXTSTREAM @@ -84,7 +85,7 @@ #define TEST_WCHAR #define TEST_ZIP #else // #if TEST_ALL - #define TEST_DLLLOADER + #define TEST_STACKWALKER #endif // some tests are interactive, define this to run them @@ -433,7 +434,7 @@ static void TestDllListLoaded() for ( size_t n = 0; n < count; ++n ) { const wxDynamicLibraryDetails& details = dlls[n]; - printf("%-45s", details.GetPath().c_str()); + printf("%-45s", details.GetPath().mb_str()); void *addr; size_t len; @@ -443,7 +444,7 @@ static void TestDllListLoaded() (unsigned long)addr, (unsigned long)((char *)addr + len)); } - printf(" %s\n", details.GetVersion().c_str()); + printf(" %s\n", details.GetVersion().mb_str()); } } @@ -2629,6 +2630,71 @@ static void TestFtpUpload() #endif // TEST_FTP +// ---------------------------------------------------------------------------- +// stack backtrace +// ---------------------------------------------------------------------------- + +#ifdef TEST_STACKWALKER + +#include "wx/stackwalk.h" + +class StackDump : public wxStackWalker +{ +public: + StackDump(const char *argv0) + : wxStackWalker(argv0) + { + } + + virtual void Walk() + { + wxPuts(_T("Stack dump:")); + + wxStackWalker::Walk(); + } + +protected: + virtual void OnStackFrame(const wxStackFrame& frame) + { + printf("[%2d] ", frame.GetLevel()); + + wxString name = frame.GetName(); + if ( !name.empty() ) + { + printf("%-20.40s", name.mb_str()); + } + else + { + printf("0x%08lx", (unsigned long)frame.GetAddress()); + } + + if ( frame.HasSourceLocation() ) + { + printf("\t%s:%d", + frame.GetFileName().mb_str(), + frame.GetLine()); + } + + puts(""); + + wxString type, val; + for ( size_t n = 0; frame.GetParam(n, &type, &name, &val); n++ ) + { + printf("\t%s %s = %s\n", type.mb_str(), name.mb_str(), val.mb_str()); + } + } +}; + +static void TestStackWalk(const char *argv0) +{ + wxPuts(_T("*** Testing wxStackWalker ***\n")); + + StackDump dump(argv0); + dump.Walk(); +} + +#endif // TEST_STACKWALKER + // ---------------------------------------------------------------------------- // standard paths // ---------------------------------------------------------------------------- @@ -4332,6 +4398,10 @@ int main(int argc, char **argv) TestScopeGuard(); #endif +#ifdef TEST_STACKWALKER + TestStackWalk(argv[0]); +#endif // TEST_STACKWALKER + #ifdef TEST_STDPATHS TestStandardPaths(); #endif diff --git a/setup.h.in b/setup.h.in index baf634693e..faa8c5e664 100644 --- a/setup.h.in +++ b/setup.h.in @@ -168,6 +168,8 @@ #define wxUSE_ON_FATAL_EXCEPTION 0 #endif +#define wxUSE_STACKWALKER 0 + #ifndef wxUSE_UNICODE #define wxUSE_UNICODE 0 @@ -695,6 +697,9 @@ /* Define if you have pw_gecos field in struct passwd */ #undef HAVE_PW_GECOS +/* Define if you have __cxa_demangle() in */ +#undef HAVE_CXA_DEMANGLE + /* Define if you have dlopen() */ #undef HAVE_DLOPEN diff --git a/src/unix/stackwalk.cpp b/src/unix/stackwalk.cpp new file mode 100644 index 0000000000..556eaf6837 --- /dev/null +++ b/src/unix/stackwalk.cpp @@ -0,0 +1,188 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: msw/stackwalk.cpp +// Purpose: wxStackWalker implementation for Unix/glibc +// Author: Vadim Zeitlin +// Modified by: +// Created: 2005-01-18 +// RCS-ID: $Id$ +// Copyright: (c) 2005 Vadim Zeitlin +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_STACKWALKER + +#ifndef WX_PRECOMP + #include "wx/string.h" +#endif + +#include "wx/stackwalk.h" + +#include + +#ifdef HAVE_CXA_DEMANGLE + #include +#endif // HAVE_CXA_DEMANGLE + +// ============================================================================ +// implementation +// ============================================================================ + +wxString wxStackWalker::ms_exepath; + +// ---------------------------------------------------------------------------- +// wxStackFrame +// ---------------------------------------------------------------------------- + +void wxStackFrame::OnGetName() +{ + if ( m_hasName ) + return; + + m_hasName = true; + + // try addr2line first because it always gives us demangled names (even if + // __cxa_demangle is not available) and because it seems less error-prone + // when it works, backtrace_symbols() sometimes returns incorrect results + OnGetLocation(); + + // format is: "module(funcname+offset) [address]" but the part in + // parentheses can be not present + wxString syminfo = wxString::FromAscii(m_syminfo); + const size_t posOpen = syminfo.find(_T('(')); + if ( posOpen != wxString::npos ) + { + const size_t posPlus = syminfo.find(_T('+'), posOpen + 1); + if ( posPlus != wxString::npos ) + { + const size_t posClose = syminfo.find(_T(')'), posPlus + 1); + if ( posClose != wxString::npos ) + { + if ( m_name.empty() ) + { + m_name.assign(syminfo, posOpen + 1, posPlus - posOpen - 1); + +#ifdef HAVE_CXA_DEMANGLE + int rc = -1; + char *cppfunc = __cxxabiv1::__cxa_demangle + ( + m_name.mb_str(), + NULL, // output buffer (none, alloc it) + NULL, // [out] len of output buffer + &rc + ); + if ( rc == 0 ) + m_name = wxString::FromAscii(cppfunc); + + free(cppfunc); +#endif // HAVE_CXA_DEMANGLE + } + + unsigned long ofs; + if ( wxString(syminfo, posPlus + 1, posClose - posPlus - 1). + ToULong(&ofs, 0) ) + m_offset = ofs; + } + } + } + + m_module.assign(syminfo, posOpen); +} + +void wxStackFrame::OnGetLocation() +{ + if ( m_hasLocation ) + return; + + m_hasLocation = true; + + // we need to launch addr2line tool to get this information and we need to + // have the program name for this + wxString exepath = wxStackWalker::GetExePath(); + if ( exepath.empty() ) + { + if ( !wxTheApp || !wxTheApp->argv ) + return; + exepath = wxTheApp->argv[0]; + } + + wxArrayString output; + wxLogNull noLog; + if ( wxExecute(wxString::Format(_T("addr2line -C -f -e \"%s\" %p"), + exepath.c_str(), + m_address), output) == 0 ) + { + if ( output.GetCount() != 2 ) + { + wxLogDebug(_T("Unexpected addr2line output.")); + } + else // 1st line has function name, 2nd one -- the file/line info + { + if ( GetName().empty() ) + { + m_name = output[0]; + if ( m_name == _T("??") ) + m_name.clear(); + } + + const size_t posColon = output[1].find(_T(':')); + if ( posColon != wxString::npos ) + { + m_filename.assign(output[1], 0, posColon); + if ( m_filename == _T("??") ) + { + m_filename.clear(); + } + else + { + unsigned long line; + if ( wxString(output[1], posColon + 1, wxString::npos). + ToULong(&line) ) + m_line = line; + } + } + else + { + wxLogDebug(_T("Unexpected addr2line format: \"%s\""), + output[1].c_str()); + } + } + } +} + +// ---------------------------------------------------------------------------- +// wxStackWalker +// ---------------------------------------------------------------------------- + +void wxStackWalker::Walk(size_t skip) +{ + // that many frames should be enough for everyone + void *addresses[200]; + + int depth = backtrace(addresses, WXSIZEOF(addresses)); + if ( !depth ) + return; + + char **symbols = backtrace_symbols(addresses, depth); + + for ( int n = 0; n < depth; n++ ) + { + wxStackFrame frame(n, addresses[n], symbols[n]); + OnStackFrame(frame); + } +} + +#endif // wxUSE_STACKWALKER -- 2.45.2