rsc | 0a61c07 | 2004-04-19 18:18:37 +0000 | [diff] [blame] | 1 | // trace user malloc pool - trace malloc, realloc, and free calls |
| 2 | // if trumpsbrk is set, we trace sbrkalloc and sbrkmerge too. |
| 3 | |
| 4 | _stoprunning = 0; |
| 5 | trumphexaddrs = 0; |
| 6 | trumpsbrk = 0; |
| 7 | |
| 8 | defn stopped(pid) { |
| 9 | local l; |
| 10 | local pc; |
| 11 | pc = *PC; |
| 12 | if notes then { |
| 13 | if (notes[0]!="sys: breakpoint") then |
| 14 | { |
| 15 | print(pid,": ",reason(*TRAP),"\t"); |
| 16 | print(fmt(pc,97),"\t",fmt(pc,105),"\n"); |
| 17 | print("Notes pending:\n"); |
| 18 | l = notes; |
| 19 | while l do |
| 20 | { |
| 21 | print("\t",head l,"\n"); |
| 22 | l = tail l; |
| 23 | } |
| 24 | _stoprunning = 1; |
| 25 | } |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | defn printstack() { |
| 30 | local frame, stk, pcs, lst, x; |
| 31 | |
| 32 | pcs = {*PC}; |
| 33 | stk = strace(*PC,*SP,0); |
| 34 | while stk do { |
| 35 | pcs = append pcs, stk[0][1]; |
| 36 | stk = tail stk; |
| 37 | } |
| 38 | |
| 39 | print(" #"); |
| 40 | lst = pcs; |
| 41 | while lst do { |
| 42 | if trumphexaddrs != 0 then |
| 43 | x = lst[0]\X; |
| 44 | else |
| 45 | x = lst[0]\a; |
| 46 | print(" src(", x, ");"); |
| 47 | lst = tail lst; |
| 48 | } |
| 49 | print("\n"); |
| 50 | } |
| 51 | |
| 52 | defn setuptrump() { |
| 53 | mallocPC = malloc; |
| 54 | malloczPC = mallocz; |
| 55 | freePC = free; |
| 56 | reallocPC = realloc; |
| 57 | sbrkallocPC = sbrkalloc; |
| 58 | sbrkmergePC = sbrkmerge; |
| 59 | |
| 60 | // linker might fill delay slot with first instruction |
| 61 | if objtype == "mips" then { |
| 62 | mallocPC = mallocPC+4; |
| 63 | malloczPC = malloczPC+4; |
| 64 | freePC = freePC+4; |
| 65 | reallocPC = reallocPC+4; |
| 66 | sbrkallocPC = sbrkallocPC+4; |
| 67 | sbrkmergePC = sbrkmergePC+4; |
| 68 | } |
| 69 | |
| 70 | bpset(mallocPC); |
| 71 | bpset(malloczPC); |
| 72 | bpset(freePC); |
| 73 | bpset(reallocPC); |
| 74 | if trumpsbrk then { |
| 75 | bpset(sbrkallocPC); |
| 76 | bpset(sbrkmergePC); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | defn cleantrump() { |
| 81 | stop(pid); |
| 82 | |
| 83 | bpdel(mallocPC); |
| 84 | bpdel(malloczPC); |
| 85 | bpdel(freePC); |
| 86 | bpdel(reallocPC); |
| 87 | bpdel(sbrkallocPC); |
| 88 | bpdel(sbrkmergePC); |
| 89 | } |
| 90 | |
| 91 | defn trumpflush() { |
| 92 | stop(pid); // already stopped, but flushes output |
| 93 | } |
| 94 | |
| 95 | defn new() { |
| 96 | bplist = {}; |
| 97 | newproc(progargs); |
| 98 | bpset(follow(main)[0]); |
| 99 | cont(); |
| 100 | bpdel(*PC); |
| 101 | // clear the hang bit, which is left set by newproc, so programs we fork/exec don't hang |
| 102 | printto("/proc/"+itoa(pid)+"/ctl", "nohang"); |
| 103 | } |
| 104 | |
| 105 | defn trumpfninfo() { |
| 106 | local arg0, arg1, stk, retpc, params; |
| 107 | |
| 108 | stk = strace(*PC, *SP, 0); |
| 109 | retpc = stk[0][1]; |
| 110 | params = stk[0][2]; |
| 111 | arg0 = params[0][1]; |
| 112 | arg1 = 0; |
| 113 | if tail params != {} then |
| 114 | arg1 = params[1][1]; |
| 115 | return {arg0, arg1, retpc}; |
| 116 | } |
| 117 | |
| 118 | defn trumpretval() { |
| 119 | if objtype=="386" then |
| 120 | return *AX; |
| 121 | if objtype=="mips" then |
| 122 | return *R1; |
| 123 | if objtype=="power" || objtype=="alpha" then |
| 124 | return *R0; |
| 125 | } |
| 126 | |
| 127 | defn trump() { |
| 128 | local arg0, arg1, pc, ret, x; |
| 129 | |
| 130 | stop(pid); |
| 131 | _stoprunning = 0; |
| 132 | setuptrump(); |
| 133 | while !_stoprunning do { |
| 134 | cont(); |
| 135 | if notes[0]!="sys: breakpoint" then { |
| 136 | cleantrump(); |
| 137 | return {}; |
| 138 | } |
| 139 | |
| 140 | pc = *PC; |
| 141 | x = trumpfninfo(); |
| 142 | arg0 = x[0]; |
| 143 | if pc == reallocPC || pc == sbrkmergePC then |
| 144 | arg1 = x[1]; |
| 145 | bpset(x[2]); |
| 146 | cont(); |
| 147 | bpdel(x[2]); |
| 148 | ret = trumpretval(); |
| 149 | if pc == mallocPC then |
| 150 | print(ret\X, " malloc ", arg0\D); |
| 151 | if pc == malloczPC then |
| 152 | print(ret\X, " mallocz ", arg0\D); |
| 153 | if pc == freePC then |
| 154 | print(arg0\X, " free"); |
| 155 | if pc == reallocPC then |
| 156 | print(ret\X, " realloc ", arg0\X, " ", arg1\D); |
| 157 | if pc == sbrkallocPC then |
| 158 | print(ret\X, " sbrkalloc ", arg0\D); |
| 159 | if pc == sbrkmergePC then |
| 160 | print("sbrkmerge ", arg0\X, " ", arg1\X, " = ", ret\D); |
| 161 | printstack(); |
| 162 | trumpflush(); |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | defn untrump() { |
| 167 | cleantrump(); |
| 168 | start(pid); |
| 169 | } |
| 170 | |
| 171 | print(acidfile); |