diff --git a/applications/lazstacktrace/lazstacktrace.ico b/applications/lazstacktrace/lazstacktrace.ico new file mode 100644 index 000000000..0341321b5 Binary files /dev/null and b/applications/lazstacktrace/lazstacktrace.ico differ diff --git a/applications/lazstacktrace/lazstacktrace.lpi b/applications/lazstacktrace/lazstacktrace.lpi new file mode 100644 index 000000000..2248881e9 --- /dev/null +++ b/applications/lazstacktrace/lazstacktrace.lpi @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/lazstacktrace/lazstacktrace.lpr b/applications/lazstacktrace/lazstacktrace.lpr new file mode 100644 index 000000000..a18950eeb --- /dev/null +++ b/applications/lazstacktrace/lazstacktrace.lpr @@ -0,0 +1,21 @@ +program lazstacktrace; + +{$mode objfpc}{$H+} + +uses + {$IFDEF UNIX}{$IFDEF UseCThreads} + cthreads, + {$ENDIF}{$ENDIF} + Interfaces, // this includes the LCL widgetset + Forms, mainform + { you can add units after this }; + +{$R *.res} + +begin + RequireDerivedFormResource := True; + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. + diff --git a/applications/lazstacktrace/lazstacktrace.res b/applications/lazstacktrace/lazstacktrace.res new file mode 100644 index 000000000..7c6cf3e4b Binary files /dev/null and b/applications/lazstacktrace/lazstacktrace.res differ diff --git a/applications/lazstacktrace/mainform.lfm b/applications/lazstacktrace/mainform.lfm new file mode 100644 index 000000000..f5e765a28 --- /dev/null +++ b/applications/lazstacktrace/mainform.lfm @@ -0,0 +1,99 @@ +object Form1: TForm1 + Left = 313 + Height = 447 + Top = 186 + Width = 400 + Caption = 'Stacktrace resolver' + ClientHeight = 447 + ClientWidth = 400 + LCLVersion = '0.9.31' + object editGDBPath: TFileNameEdit + Left = 104 + Height = 25 + Top = 56 + Width = 264 + FileName = '/usr/bin/gdb' + DialogOptions = [] + FilterIndex = 0 + HideDirectories = False + ButtonWidth = 23 + NumGlyphs = 0 + MaxLength = 0 + TabOrder = 0 + end + object Label1: TLabel + Left = 11 + Height = 18 + Top = 63 + Width = 83 + Caption = 'Path to GDB:' + ParentColor = False + end + object Label2: TLabel + Left = 9 + Height = 39 + Top = 9 + Width = 381 + AutoSize = False + Caption = 'This Program resolves stacktraces generated by FPC apps using GDB. It adds the symbol names to addresses.' + ParentColor = False + WordWrap = True + end + object Label3: TLabel + Left = 11 + Height = 18 + Top = 120 + Width = 78 + Caption = 'Stack trace:' + ParentColor = False + end + object memoStacktrace: TMemo + AnchorSideRight.Control = Owner + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 8 + Height = 260 + Top = 143 + Width = 387 + Anchors = [akLeft, akRight, akBottom] + BorderSpacing.Right = 5 + BorderSpacing.Bottom = 44 + TabOrder = 1 + end + object buttonResolveSymbols: TButton + AnchorSideBottom.Control = Owner + AnchorSideBottom.Side = asrBottom + Left = 136 + Height = 30 + Top = 412 + Width = 123 + Anchors = [akLeft, akBottom] + BorderSpacing.Bottom = 5 + Caption = 'Resolve Symbols' + OnClick = buttonResolveSymbolsClick + TabOrder = 2 + end + object Label4: TLabel + Left = 11 + Height = 18 + Top = 95 + Width = 109 + Caption = 'Path to Program:' + ParentColor = False + end + object editProgramPath: TFileNameEdit + Left = 128 + Height = 25 + Top = 95 + Width = 240 + FileName = '/home/felipe/Programas/lazarus-ccr/examples/androidlcl/android/libs/armeabi/libandroidlcltest.so' + DialogOptions = [] + FilterIndex = 0 + HideDirectories = False + ButtonWidth = 23 + NumGlyphs = 0 + MaxLength = 0 + TabOrder = 3 + end +end diff --git a/applications/lazstacktrace/mainform.pas b/applications/lazstacktrace/mainform.pas new file mode 100644 index 000000000..5d5189d5d --- /dev/null +++ b/applications/lazstacktrace/mainform.pas @@ -0,0 +1,81 @@ +unit mainform; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, EditBtn, + StdCtrls, process; + +type + + { TForm1 } + + TForm1 = class(TForm) + buttonResolveSymbols: TButton; + editGDBPath: TFileNameEdit; + editProgramPath: TFileNameEdit; + Label1: TLabel; + Label2: TLabel; + Label3: TLabel; + Label4: TLabel; + memoStacktrace: TMemo; + procedure buttonResolveSymbolsClick(Sender: TObject); + private + { private declarations } + public + { public declarations } + end; + +var + Form1: TForm1; + +implementation + +{$R *.lfm} + +{ TForm1 } + +procedure TForm1.buttonResolveSymbolsClick(Sender: TObject); +var + GDBProcess: TProcess; + GDBOutput: TStringList; + Str, StackStr, lCurAddress: string; + lAddressPos: SizeInt; + i: Integer; + StrGdbOutput: String; +begin + GDBProcess := TProcess.Create(nil); + GDBOutput := TStringList.Create; + memoStacktrace.Lines.BeginUpdate; + try + for i := 0 to memoStacktrace.Lines.Count - 1 do + begin + // Obtain the stack address or skip this line + StackStr := memoStacktrace.Lines.Strings[i]; + lAddressPos := Pos('$', StackStr); + if lAddressPos <= 0 then Continue; + lCurAddress := Copy(StackStr, lAddressPos+1, 8); + + // Run GDB to get the symbol name + Str := Format('%s --batch "--eval-command=info symbol 0x%s" %s', [editGDBPath.FileName, lCurAddress, editProgramPath.FileName]); + GDBProcess.CommandLine := Str; + GDBProcess.Options := GDBProcess.Options + [poWaitOnExit, poUsePipes, poStderrToOutPut]; + GDBProcess.Execute; + GDBOutput.LoadFromStream(GDBProcess.Output); + if GDBOutput.Count >= 1 then StrGdbOutput := GDBOutput.Strings[0] + else StrGdbOutput := ''; + + // Add the symbol name to the memo + memoStacktrace.Lines.Strings[i] := Format('%s %s', [StackStr, StrGdbOutput]); + end; + finally + GDBProcess.Free; + GDBOutput.Free; + memoStacktrace.Lines.EndUpdate; + end; +end; + +end. +