#97, handle signals + fix breakpoint on d_throwc

This commit is contained in:
Basile Burg 2016-09-18 19:19:09 +02:00
parent 1159e0ac02
commit 1a97a709c3
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
1 changed files with 91 additions and 41 deletions

View File

@ -7,9 +7,9 @@ interface
uses uses
Classes, SysUtils, FileUtil, ListFilterEdit, Forms, Controls, Graphics, Classes, SysUtils, FileUtil, ListFilterEdit, Forms, Controls, Graphics,
RegExpr, ComCtrls, PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls, RegExpr, ComCtrls, PropEdits, GraphPropEdits, RTTIGrids, Dialogs, ExtCtrls,
Menus, strutils, Buttons, StdCtrls, process, ce_common, ce_interfaces, Menus, strutils, Buttons, StdCtrls, process, fpjson,
ce_widget, ce_processes, ce_observer, ce_synmemo, ce_sharedres, ce_common, ce_interfaces, ce_widget, ce_processes, ce_observer, ce_synmemo,
ce_stringrange, ce_dsgncontrols, fpjson; ce_sharedres, ce_stringrange, ce_dsgncontrols, ce_dialogs;
type type
@ -577,7 +577,7 @@ begin
str := 'break ' + fFileLineBrks.Strings[i] + ':' + intToStr(PtrUInt(fFileLineBrks.Objects[i])) + #10; str := 'break ' + fFileLineBrks.Strings[i] + ':' + intToStr(PtrUInt(fFileLineBrks.Objects[i])) + #10;
fGdb.Input.Write(str[1], str.length); fGdb.Input.Write(str[1], str.length);
end; end;
// break on druntime exceptions heper + throw' // break on druntime exceptions + any throw'
fGdb.OnReadData := @gdboutQuiet; fGdb.OnReadData := @gdboutQuiet;
gdbCommand('break onAssertError'); gdbCommand('break onAssertError');
gdbCommand('break onAssertErrorMsg'); gdbCommand('break onAssertErrorMsg');
@ -590,6 +590,13 @@ begin
gdbCommand('break onSwitchError'); gdbCommand('break onSwitchError');
gdbCommand('break onUnicodeError'); gdbCommand('break onUnicodeError');
gdbCommand('break _d_throwc'); gdbCommand('break _d_throwc');
gdbCommand('break _d_throwdwarf');
gdbCommand('break _d_assertm');
gdbCommand('break _d_assert');
gdbCommand('break _d_assert_msg');
gdbCommand('break _d_array_bounds');
gdbCommand('break _d_arraybounds');
gdbCommand('break _d_switch_error');
fGdb.OnReadData := @gdboutJsonize; fGdb.OnReadData := @gdboutJsonize;
// launch // launch
gdbCommand('run'); gdbCommand('run');
@ -760,60 +767,103 @@ end;
// ^done,stack=[frame={level="0",addr="0x00000000004a4e04",func="_D3std6getopt38__T6getoptTE3std6getopt6configTAyaTPbZ6getoptFKAAyaE3std6getopt6configAyaPbZS3std6getopt12GetoptResult",file="/usr/include/dmd/phobos/std/getopt.d",fullname="/usr/include/dmd/phobos/std/getopt.d",line="438"},frame={level="1",addr="0x000000000049fb82",func="D main",file="/home/basile/Dev/dproj/Resource.d/src/resource.d",fullname="/home/basile/Dev/dproj/Resource.d/src/resource.d",line="39"}] // ^done,stack=[frame={level="0",addr="0x00000000004a4e04",func="_D3std6getopt38__T6getoptTE3std6getopt6configTAyaTPbZ6getoptFKAAyaE3std6getopt6configAyaPbZS3std6getopt12GetoptResult",file="/usr/include/dmd/phobos/std/getopt.d",fullname="/usr/include/dmd/phobos/std/getopt.d",line="438"},frame={level="1",addr="0x000000000049fb82",func="D main",file="/home/basile/Dev/dproj/Resource.d/src/resource.d",fullname="/home/basile/Dev/dproj/Resource.d/src/resource.d",line="39"}]
// *stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",frame={addr="0x000000000049fb89",func="D main",args=[{name="args",value="..."}],file="/home/basile/Dev/dproj/Resource.d/src/resource.d",fullname="/home/basile/Dev/dproj/Resource.d/src/resource.d",line="25"},thread-id="1",stopped-threads="all",core="3"
procedure TCEGdbWidget.interpretJson; procedure TCEGdbWidget.interpretJson;
var var
i: integer;
val: TJSONData; val: TJSONData;
obj: TJSONObject; obj: TJSONObject;
arr: TJSONArray; arr: TJSONArray;
idx: integer; // common data
// brkp data addr: PtrUint = 0;
fne: string = ''; fullname: string = '';
lne: integer = -1; func:string = '';
line: integer = -1;
// registers data // registers data
rnm: integer = 0; number: integer = 0;
rvl: PtrUInt = 0; gprval: PtrUInt = 0;
// call stack data // signal data
nme: string; sigmean: string;
adr: PtrUInt; signame: string;
begin begin
val := fJson.Find('reason'); val := fJson.Find('reason');
if val.isNotNil and (val.AsString = 'breakpoint-hit') then if val.isNotNil then
begin begin
obj := TJSONObject(fJson.Find('frame'));
if obj.isNotNil and (obj.JSONType = jtObject) then if val.AsString = 'breakpoint-hit' then
begin begin
val := obj.Find('fullname'); obj := TJSONObject(fJson.Find('frame'));
if val.isNotNil then if obj.isNotNil and (obj.JSONType = jtObject) then
fne := val.AsString;
val := obj.Find('line');
if val.isNotNil then
lne := strToInt(val.AsString);
if (lne <> -1) and fne.fileExists then
begin begin
getMultiDocHandler.openDocument(fne); val := obj.Find('fullname');
fDoc.setFocus; if val.isNotNil then
fDoc.CaretY:= lne; fullname := val.AsString;
val := obj.Find('line');
if val.isNotNil then
line := strToInt(val.AsString);
if (line <> -1) and fullname.fileExists then
begin
getMultiDocHandler.openDocument(fullname);
fDoc.setFocus;
fDoc.CaretY:= line;
end;
end;
end
//TODO-cGDB: in the settings, option to automatically ignore particular signals.
else if val.AsString = 'signal-received' then
begin
signame := 'unknown signal';
sigmean := 'unknown meaning';
val := fJson.Find('signal-name');
if val.isNotNil then
signame := val.AsString;
val := fJson.Find('signal-meaning');
if val.isNotNil then
sigmean += val.AsString;
obj := TJSONObject(fJson.Find('frame'));
if obj.isNotNil and (obj.JSONType = jtObject) then
begin
val := obj.Find('fullname');
if val.isNotNil then
fullname := val.AsString;
val := obj.Find('line');
if val.isNotNil then
line := strToInt(val.AsString);
end;
if dlgYesNo(format('The signal %s (%s) was received on line %d of file %s .'
+ LineEnding + 'Do you wish to pause execution ?', [signame, sigmean, line, fullname]),
'Unexpected signal received') = mrNo then
gdbCommand('continue', @gdboutJsonize)
else
begin
if (line <> -1) and fullname.fileExists then
begin
getMultiDocHandler.openDocument(fullname);
fDoc.setFocus;
fDoc.CaretY:= line;
end;
end; end;
end; end;
end; end;
val := fJson.Find('register-values'); val := fJson.Find('register-values');
if val.isNotNil and (val.JSONType = jtArray) then if val.isNotNil and (val.JSONType = jtArray) then
begin begin
arr := TJSONArray(val); arr := TJSONArray(val);
for idx := 0 to arr.Count-1 do for i := 0 to arr.Count-1 do
begin begin
obj := TJSONObject(arr.Objects[idx]); obj := TJSONObject(arr.Objects[i]);
if obj.isNil then if obj.isNil then
break break
else else
begin begin
val := obj.Find('number'); val := obj.Find('number');
if val.isNotNil then if val.isNotNil then
rnm := strToInt(val.AsString); number := strToInt(val.AsString);
val := obj.Find('value'); val := obj.Find('value');
//if val.isNotNil and (val.JSONType = jtString) then //if val.isNotNil and (val.JSONType = jtString) then
// rvl := StrToInt64(val.AsString) // rvl := StrToInt64(val.AsString)
@ -831,25 +881,25 @@ begin
fStackItems.clear; fStackItems.clear;
lstCallStack.Clear; lstCallStack.Clear;
arr := TJSONArray(val); arr := TJSONArray(val);
for idx := 0 to arr.Count-1 do for i := 0 to arr.Count-1 do
begin begin
obj := arr.Objects[idx]; obj := arr.Objects[i];
if obj.isNil then if obj.isNil then
break; break;
val := obj.Find('fullname'); val := obj.Find('fullname');
if val.isNotNil then if val.isNotNil then
fne:= val.AsString; fullname:= val.AsString;
// TODO-cGDB: demangle function name. // TODO-cGDB: demangle function name.
val := obj.Find('func'); val := obj.Find('func');
if val.isNotNil then if val.isNotNil then
nme:= val.AsString; func:= val.AsString;
val := obj.Find('addr'); val := obj.Find('addr');
if val.isNotNil then if val.isNotNil then
adr := val.AsInt64; addr := val.AsInt64;
val := obj.Find('line'); val := obj.Find('line');
if val.isNotNil then if val.isNotNil then
lne := val.AsInteger; line := val.AsInteger;
fStackItems.addItem(adr, fne, nme, lne); fStackItems.addItem(addr, fullname, func, line);
end; end;
fStackItems.assignToList(lstCallStack); fStackItems.assignToList(lstCallStack);
end; end;
@ -858,8 +908,8 @@ begin
begin begin
arr := TJSONArray(fJson.Find('CLI')); arr := TJSONArray(fJson.Find('CLI'));
if arr.isNotNil then if arr.isNotNil then
for idx := 0 to arr.Count-1 do for i := 0 to arr.Count-1 do
fMsg.message(arr.Strings[idx], nil, amcMisc, amkBub); fMsg.message(arr.Strings[i], nil, amcMisc, amkBub);
end; end;
end; end;
@ -874,8 +924,8 @@ begin
fLog.Clear; fLog.Clear;
fGdb.getFullLines(fLog); fGdb.getFullLines(fLog);
for str in fLog do //for str in fLog do
fMsg.message(str, nil, amcMisc, amkAuto); // fMsg.message(str, nil, amcMisc, amkAuto);
if flog.Text.isEmpty then if flog.Text.isEmpty then
exit; exit;