acid: watchpoint support
This commit is contained in:
parent
5dcb407add
commit
68cfc786ba
|
@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'b';
|
bpfmt = 'b';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
@ -84,13 +86,18 @@ defn pstop(pid)
|
||||||
local l;
|
local l;
|
||||||
local pc;
|
local pc;
|
||||||
|
|
||||||
pc = *PC;
|
pc = (*PC)\i;
|
||||||
|
|
||||||
|
if notes && regexp("^sys: watchpoint ", notes[0]) then
|
||||||
|
pc--;
|
||||||
|
|
||||||
print(pid,": ", reason(*TRAP), "\t");
|
print(pid,": ", reason(*TRAP), "\t");
|
||||||
print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
|
print(fmt(pc, 'a'), "\t", pc, "\n");
|
||||||
|
|
||||||
if notes then {
|
if notes then {
|
||||||
if notes[0] != "sys: breakpoint" then {
|
if regexp("^sys: watchpoint ", notes[0]) then
|
||||||
|
wpprocess();
|
||||||
|
else if notes[0] != "sys: breakpoint" then {
|
||||||
print("Notes pending:\n");
|
print("Notes pending:\n");
|
||||||
l = notes;
|
l = notes;
|
||||||
while l do {
|
while l do {
|
||||||
|
|
|
@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'x';
|
bpfmt = 'x';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
|
|
@ -4,6 +4,8 @@ defn acidinit()
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'b';
|
bpfmt = 'b';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
@ -98,13 +100,18 @@ defn pstop(pid)
|
||||||
local l;
|
local l;
|
||||||
local pc;
|
local pc;
|
||||||
|
|
||||||
pc = *PC;
|
pc = (*PC)\i;
|
||||||
|
|
||||||
|
if notes && regexp("^sys: watchpoint ", notes[0]) then
|
||||||
|
pc--;
|
||||||
|
|
||||||
print(pid,": ", reason(*TRAP), "\t");
|
print(pid,": ", reason(*TRAP), "\t");
|
||||||
print(fmt(pc, 'a'), "\t", fmt(pc, 'i'), "\n");
|
print(fmt(pc, 'a'), "\t", pc, "\n");
|
||||||
|
|
||||||
if notes then {
|
if notes then {
|
||||||
if notes[0] != "sys: breakpoint" then {
|
if regexp("^sys: watchpoint ", notes[0]) then
|
||||||
|
wpprocess();
|
||||||
|
else if notes[0] != "sys: breakpoint" then {
|
||||||
print("Notes pending:\n");
|
print("Notes pending:\n");
|
||||||
l = notes;
|
l = notes;
|
||||||
while l do {
|
while l do {
|
||||||
|
|
|
@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'X';
|
bpfmt = 'X';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
|
|
@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'X';
|
bpfmt = 'X';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
|
|
@ -267,6 +267,7 @@ defn step() // single step the process
|
||||||
bput = fmt(*PC, bpfmt);
|
bput = fmt(*PC, bpfmt);
|
||||||
*bput = @bput;
|
*bput = @bput;
|
||||||
}
|
}
|
||||||
|
wpupdate(0);
|
||||||
|
|
||||||
lst = follow(*PC);
|
lst = follow(*PC);
|
||||||
|
|
||||||
|
@ -336,6 +337,134 @@ defn bpdel(addr) // delete a breakpoint
|
||||||
bplist = nbplist; // delete from memory
|
bplist = nbplist; // delete from memory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defn wpflush() // copy wplist to /proc/$pid/watchpt
|
||||||
|
{
|
||||||
|
local s, lst, el;
|
||||||
|
|
||||||
|
lst = wplist;
|
||||||
|
s = "";
|
||||||
|
while lst do {
|
||||||
|
el = head lst;
|
||||||
|
s = s + (el[0] + " " + itoa(el[1]) + " " + itoa(el[2]) + "\n");
|
||||||
|
lst = tail lst;
|
||||||
|
}
|
||||||
|
lst = proclist;
|
||||||
|
while lst do {
|
||||||
|
if access("/proc/"+itoa(head lst)+"/watchpt") then
|
||||||
|
printto("/proc/"+itoa(head lst)+"/watchpt", s);
|
||||||
|
lst = tail lst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defn wpset(type, addr, len) // set a watchpoint
|
||||||
|
{
|
||||||
|
local lst;
|
||||||
|
|
||||||
|
if status(pid) != "Stopped" then {
|
||||||
|
print("Waiting...\n");
|
||||||
|
stop(pid);
|
||||||
|
}
|
||||||
|
if !regexp("^[rwx\\-]+$", type) then {
|
||||||
|
print("invalid type\n");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
lst = proclist;
|
||||||
|
while lst do {
|
||||||
|
if rc("echo '"+type+" "+itoa(addr)+" "+itoa(len)+"' >> /proc/"+itoa(head lst)+"/watchpt") != "" then
|
||||||
|
return {};
|
||||||
|
lst = tail lst;
|
||||||
|
}
|
||||||
|
wplist = append wplist, {type, addr, len, {}};
|
||||||
|
}
|
||||||
|
|
||||||
|
defn wptab() // print a table of watchpoints
|
||||||
|
{
|
||||||
|
local lst, el;
|
||||||
|
|
||||||
|
lst = wplist;
|
||||||
|
while lst do {
|
||||||
|
el = head lst;
|
||||||
|
print("\t", el[0], " ", fmt(el[1], 'A'), " ", fmt(el[1], 'a'), " ", fmt(el[2], 'd'), "\n");
|
||||||
|
lst = tail lst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defn wpdel(addr)
|
||||||
|
{
|
||||||
|
local lst, el, found, nwplist;
|
||||||
|
|
||||||
|
lst = wplist;
|
||||||
|
found = 0;
|
||||||
|
nwplist = {};
|
||||||
|
while lst do {
|
||||||
|
el = head lst;
|
||||||
|
if el[1] == addr then
|
||||||
|
found = 1;
|
||||||
|
else
|
||||||
|
nwplist = append nwplist, el;
|
||||||
|
lst = tail lst;
|
||||||
|
}
|
||||||
|
if found == 0 then {
|
||||||
|
print("no watchpoint at ", fmt(addr, 'a'), "\n");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
wplist = nwplist;
|
||||||
|
wpflush();
|
||||||
|
}
|
||||||
|
|
||||||
|
defn bytes(b)
|
||||||
|
{
|
||||||
|
local s;
|
||||||
|
|
||||||
|
s = "";
|
||||||
|
while b do {
|
||||||
|
s = s + itoa(head b, "%#.2x ");
|
||||||
|
b = tail b;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
defn wpupdate(ch) // update remembered values
|
||||||
|
{
|
||||||
|
local el, nwplist, mem, lst, i;
|
||||||
|
|
||||||
|
lst = wplist;
|
||||||
|
nwplist = {};
|
||||||
|
while lst do {
|
||||||
|
el = head lst;
|
||||||
|
i = 0;
|
||||||
|
mem = {};
|
||||||
|
while i < el[2] do {
|
||||||
|
mem = append mem, *((el[1] + i)\b);
|
||||||
|
i = i + 1;
|
||||||
|
}
|
||||||
|
if ch && el[3] != {} && el[3] != mem then {
|
||||||
|
print("\t", fmt(el[1], 'a'), "\twas ", bytes(el[3]), "\n");
|
||||||
|
print("\t", fmt(el[1], 'a'), "\tis ", bytes(mem), "\n");
|
||||||
|
}
|
||||||
|
nwplist = append nwplist, {el[0], el[1], el[2], mem};
|
||||||
|
lst = tail lst;
|
||||||
|
}
|
||||||
|
wplist = nwplist;
|
||||||
|
}
|
||||||
|
|
||||||
|
defn wpprocess() // trapped at watchpoint
|
||||||
|
{
|
||||||
|
local pts;
|
||||||
|
local el;
|
||||||
|
|
||||||
|
pts = getfields(getfields(notes[0], " ", 1)[2], ",", 1);
|
||||||
|
while pts do {
|
||||||
|
el = head pts;
|
||||||
|
el = wplist[atoi(el)];
|
||||||
|
if el != {} then {
|
||||||
|
print("\ttriggered ", el[0], " watchpoint at ", fmt(el[1], 'a'), " (", fmt(el[1], 'A'), ")\n");
|
||||||
|
}
|
||||||
|
pts = tail pts;
|
||||||
|
}
|
||||||
|
wpupdate(1);
|
||||||
|
}
|
||||||
|
|
||||||
defn cont() // continue execution
|
defn cont() // continue execution
|
||||||
{
|
{
|
||||||
local addr;
|
local addr;
|
||||||
|
@ -346,6 +475,7 @@ defn cont() // continue execution
|
||||||
step(); // Step over
|
step(); // Step over
|
||||||
*addr = bpinst;
|
*addr = bpinst;
|
||||||
}
|
}
|
||||||
|
wpupdate(0);
|
||||||
startstop(pid); // Run
|
startstop(pid); // Run
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +535,7 @@ defn win()
|
||||||
local npid, estr;
|
local npid, estr;
|
||||||
|
|
||||||
bplist = {};
|
bplist = {};
|
||||||
|
wplist = {};
|
||||||
notes = {};
|
notes = {};
|
||||||
|
|
||||||
estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
|
estr = "/sys/lib/acid/window '0 0 600 400' "+textfile;
|
||||||
|
@ -425,6 +556,7 @@ defn win2()
|
||||||
local npid, estr;
|
local npid, estr;
|
||||||
|
|
||||||
bplist = {};
|
bplist = {};
|
||||||
|
wplist = {};
|
||||||
notes = {};
|
notes = {};
|
||||||
|
|
||||||
estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
|
estr = "/sys/lib/acid/transcript '0 0 600 400' '100 100 700 500' "+textfile;
|
||||||
|
@ -443,6 +575,7 @@ defn win2()
|
||||||
defn new()
|
defn new()
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
|
wplist = {};
|
||||||
newproc(progargs);
|
newproc(progargs);
|
||||||
// Dont miss the delay slot calls
|
// Dont miss the delay slot calls
|
||||||
bpset(follow(main)[0]);
|
bpset(follow(main)[0]);
|
||||||
|
@ -565,5 +698,17 @@ defn spsrch(len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defn procattach()
|
||||||
|
{
|
||||||
|
wpflush();
|
||||||
|
}
|
||||||
|
|
||||||
|
defn dying()
|
||||||
|
{
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
derp();
|
||||||
|
}
|
||||||
|
|
||||||
progargs="";
|
progargs="";
|
||||||
print("/sys/lib/acid/port");
|
print("/sys/lib/acid/port");
|
||||||
|
|
|
@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'X';
|
bpfmt = 'X';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
|
|
@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'X';
|
bpfmt = 'X';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
|
|
@ -4,6 +4,8 @@ defn acidinit() // Called after all the init modules are loaded
|
||||||
{
|
{
|
||||||
bplist = {};
|
bplist = {};
|
||||||
bpfmt = 'X';
|
bpfmt = 'X';
|
||||||
|
wplist = {};
|
||||||
|
wpflush();
|
||||||
|
|
||||||
srcpath = {
|
srcpath = {
|
||||||
"./",
|
"./",
|
||||||
|
|
Loading…
Reference in a new issue