tags:

views:

117

answers:

4

Does not need to be a full debugger but i need to get a good stack trace dump when an assert is raised. A simple list of called functions is not enough. I'm pretty happy with my Eiffel system which is giving me something like

17 frames in current stack.
=====  Displaying only top 10 frames in run-time stack  =====
agent call wrapper 2
======================================
lookup_key USER_COMMAND_INVOCATION
Current = USER_COMMAND_INVOCATION#03FE5D00
        [ arachno_window = #061A4AF0
          window = #061A4AF0
          mrec = Void
          trigger = "if"
          param_int = 0
          param_str = Void
          skip_next_keystroke = false
          in_continuation_key = false
          current_hook = #05EFB500
          update_default_command = #05EF3578
          default_command = "Editor.Modifications#cInsert Typed Text"
          last_invoked_command = "Editor.Modifications#cTab Character"
          show_popup_menu_action = #061B3C30
          build_menu = Void
          menu_line = 0
          menu_offset = 0
          modifiers = #03FDCAC8
          code = #03FDCB88
          character = #03FDCB58
          count = 0
          prefix_count = -1
          selected_commands = #03FDCA98
          cached_file_types = #03FDCA68
          cached_file_context = #03FDCA38
          cached_window_type_name = Void
          project_context_action = #061B3C80
          program_context_action = #061B3C58
          window_context_action = #061B3CA8
          cached_window_name_valid = false
          cached_file_type_valid = false
          cached_file_context_valid = false
          reset_prefix_on_next_event = false
        ]
before = true
mod = BIT_32
        [ bits = 0
        ]
c = 65362
str = ""
menu = Void
map = Void
key = Void
b = Void
i = 0
n = 0
m = 0
cval = 65362
char = 0
cnt = 0
s = Void
skip_flag = false
prefix_found_flag = false
ev = AGUI_EVENT_CONSTANTS
t = Void
consume = false
line 387 column 13 file x:\work_arachno\src\run\user_command_invocation.e
======================================
on_key_hook (late bind.)
======================================
on_key_hook EDITOR_KEY_STEALER_HOOK
Current = EDITOR_KEY_STEALER_HOOK#05EFB500
        [ callback = POINTER#063D1570
          sapi = SCRIPTING_API
        ]
mod = BIT_32
        [ bits = 0
        ]
code = 65362
str = ""
Result = false
break = false
engine = POINTER#04BEE690
cmd_pair = Void
line 41 column 0 file x:\work_arachno\src\editor\editor_key_stealer_hook.e
======================================
callback SCRIPTING_API
ptr = POINTER#04BEE690
cb = POINTER#063D1570
args = 3
res = 1
Result = 0
line 481 column 16 file x:\work_arachno\src\scripting\scripting_api.e
======================================
External CECIL call.
======================================
editor__move_lines EDITOR_SCRIPTING
Current = EDITOR_SCRIPTING#05EE17A0
        [ sapi = SCRIPTING_API
          view = #061A47D0
          positions = #05EE1780
          stealer_hook = #05EFB500
          html_file_dialog = Void
          html_file_dialog_modified = false
        ]
manager = EDITOR_MANAGER#05EE0ED8
        [ configuration = #03FD7F00
          breakpoints = #05ED0460
          folding_settings = #05ED76C0
          lang_descriptors = #05EDD360
          confirm_edit_while_debugging = true
          use_word_wrap = false
          are_foldings_visible = true
          are_line_numbers_visible = true
          are_modified_markers_visible = true
          are_bookmarks_visible = true
          are_whitespaces_visible = false
          is_highlight_current_line = false
          is_highlight_search_results = true
          is_right_margin_visible = true
          are_indent_lines_visible = true
          are_line_endings_visible = false
          are_end_of_line_dots_visible = false
          are_breakpoints_visible = false
          commands = #03FD1E70
          completition = #0400A8C0
          tooltip_buffer = Void
          folding_background_task_id = 0
          folding_file_observer = #061C6EE0
          folding_rand = #05EDDE88
          bracket_window = Void
          bracket_window_popdown_task = 0
          tracked_positions = Void
          code_hinting = #05EE2F20
          code_hinting_active = false
          code_hinting_window_id = 0
          code_hinting_file_id = 0
          code_hinting_shutdown_task = 0
          code_hinting_shutdown_agent = #05ED2690
          code_hinting_autostart = true
          code_hinting_info_display = 2
          code_hinting_display_id = 0
          code_hinting_sequence_id = 3
        ]
engine = POINTER#04BEE690
sobj = POINTER#07526740
Result = 0
first = 486
last = 486
ref = 487
before = false
line 220 column 25 file ΘÖ▓♣
======================================
move_lines (late bind.)
======================================
move_lines EDITOR_BUFFER
Current = EDITOR_BUFFER#03FE91B0
        [ modified_lines = #074BD408
          modified_lines_string = ""
          lines = #074BD348
          last_modified_position = #061D6B18
          is_read_only_state = false
          is_modified = true
          is_special_empty = false
          is_zombie = false
          line_end_coding = 1
          loaded_without_last_newline = true
          descriptor = #05EE04C0
          views = #074BD3A8
          transform_position = Void
          transform_array = #07552E40
          forbid_update_counter = 0
          inside_undo_operation = false
          debug_position_list = #074BD390
        ]
pos = EDITOR_POSITION#061B35A0
        [ help = "caret"
          buffer_line = #03FF0460
          offset = 18
          data = #075181E0
          is_anchored = false
          is_transformed = false
          next_transformed = Void
          next = #044C0270
        ]
lower = 486
upper = 486
ref = 487
before = false
count = 1
src = 0
dest = 1
i = 2214
j = 2213
low = 486
up = 489
target = 486
skip = false
a = ARRAY[EDITOR_BUFFER_LINE]#075529C0
        [ storage = NATIVE_ARRAY[EDITOR_BUFFER_LINE]#03FDA448
          capacity = 1
          upper = 1
          lower = 1
        ]
set = SET[INTEGER]#075266E0
        [ buckets = NATIVE_ARRAY[SET_NODE[INTEGER]]#0755B000
          cache_user = -1
          cache_node = Void
          cache_buckets = 0
          count = 2213
          capacity = 3079
        ]
line 1107 column 25 file x:\work_arachno\src\editor\editor_buffer.e
======================================

It means i get a dump of all stack variables and the current (this) object. And the best is that i can ship this to the customer because it requires zero configuration on the client side.

Does anyone know how i can do this in a C++/C or even D or CObject (i have to switch the langauge anyway and this are my four preferred targets)?

And everyone who says i should deploy GDB will get downvotes.

+1  A: 

for windows, look at minidumps, creatable with methods in toolhelp.dll

stijn
A: 

As stijn pointed out, under Windows a minidump may be sufficient. If it is, it'll undoubtedly be a whole lot easier than almost any alternative.

A minidump won't be very close to what you're getting from Eiffel though. If you need something closer, you'll probably have to write (most of) the code yourself. The Antex Stack Walker would probably be a reasonable start (look for stackwalker.cpp and stackwalker.h).

Jerry Coffin
A: 

You might want to look at google-breakpad: http://code.google.com/p/google-breakpad/

It's the project formerly known as Airbag:

I'll admit that I haven't used it (my needs for something like this have been Windows-only), but it appears to have Mozilla behind it and seems to be pretty active.

It's a set of libraries and tools to automatically send crashdumps to a server so you can do post mortems. As I understand it Firefox is currently using it, so I imagine it's pretty cross-platform. The downside is that it's not self-contained in the client program - you need some infrastructure in place for it to be useful. That might or might not be workable for your situation.

Though if you don't want to have a service that gets the reports (maybe you just want them on the client or have them sent by email) I imagine you could have the client reporter send it's information to a 'server' program that also exists on the client machine to do the reporting. No idea how much work it would be to get it to function like that.

Michael Burr
+1  A: 

If you're on Linux with glibc look into the 'backtrace()' function. I've used it on a PPC system to get stacktraces whenever a critical error occurs.

In my implementation I just log the return addresses and use a script on the host platform (based around addr2line) to translate is back into filename/function name/line number.

Kristof Provost