1*387f9dfdSAndroid Build Coastguard WorkerDemonstrations of argdist. 2*387f9dfdSAndroid Build Coastguard Worker 3*387f9dfdSAndroid Build Coastguard Worker 4*387f9dfdSAndroid Build Coastguard Workerargdist probes functions you specify and collects parameter values into a 5*387f9dfdSAndroid Build Coastguard Workerhistogram or a frequency count. This can be used to understand the distribution 6*387f9dfdSAndroid Build Coastguard Workerof values a certain parameter takes, filter and print interesting parameters 7*387f9dfdSAndroid Build Coastguard Workerwithout attaching a debugger, and obtain general execution statistics on 8*387f9dfdSAndroid Build Coastguard Workervarious functions. 9*387f9dfdSAndroid Build Coastguard Worker 10*387f9dfdSAndroid Build Coastguard WorkerFor example, suppose you want to find what allocation sizes are common in 11*387f9dfdSAndroid Build Coastguard Workeryour application: 12*387f9dfdSAndroid Build Coastguard Worker 13*387f9dfdSAndroid Build Coastguard Worker# ./argdist -p 2420 -c -C 'p:c:malloc(size_t size):size_t:size' 14*387f9dfdSAndroid Build Coastguard Worker[01:42:29] 15*387f9dfdSAndroid Build Coastguard Workerp:c:malloc(size_t size):size_t:size 16*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 17*387f9dfdSAndroid Build Coastguard Worker[01:42:30] 18*387f9dfdSAndroid Build Coastguard Workerp:c:malloc(size_t size):size_t:size 19*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 20*387f9dfdSAndroid Build Coastguard Worker[01:42:31] 21*387f9dfdSAndroid Build Coastguard Workerp:c:malloc(size_t size):size_t:size 22*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 23*387f9dfdSAndroid Build Coastguard Worker 1 size = 16 24*387f9dfdSAndroid Build Coastguard Worker[01:42:32] 25*387f9dfdSAndroid Build Coastguard Workerp:c:malloc(size_t size):size_t:size 26*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 27*387f9dfdSAndroid Build Coastguard Worker 2 size = 16 28*387f9dfdSAndroid Build Coastguard Worker[01:42:33] 29*387f9dfdSAndroid Build Coastguard Workerp:c:malloc(size_t size):size_t:size 30*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 31*387f9dfdSAndroid Build Coastguard Worker 3 size = 16 32*387f9dfdSAndroid Build Coastguard Worker[01:42:34] 33*387f9dfdSAndroid Build Coastguard Workerp:c:malloc(size_t size):size_t:size 34*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 35*387f9dfdSAndroid Build Coastguard Worker 4 size = 16 36*387f9dfdSAndroid Build Coastguard Worker^C 37*387f9dfdSAndroid Build Coastguard Worker 38*387f9dfdSAndroid Build Coastguard WorkerIt seems that the application is allocating blocks of size 16. The COUNT 39*387f9dfdSAndroid Build Coastguard Workercolumn contains the number of occurrences of a particular event, and the 40*387f9dfdSAndroid Build Coastguard WorkerEVENT column describes the event. In this case, the "size" parameter was 41*387f9dfdSAndroid Build Coastguard Workerprobed and its value was 16, repeatedly. 42*387f9dfdSAndroid Build Coastguard Worker 43*387f9dfdSAndroid Build Coastguard WorkerNow, suppose you wanted a histogram of buffer sizes passed to the write() 44*387f9dfdSAndroid Build Coastguard Workerfunction across the system: 45*387f9dfdSAndroid Build Coastguard Worker 46*387f9dfdSAndroid Build Coastguard Worker# ./argdist -c -H 'p:c:write(int fd, void *buf, size_t len):size_t:len' 47*387f9dfdSAndroid Build Coastguard Worker[01:45:22] 48*387f9dfdSAndroid Build Coastguard Workerp:c:write(int fd, void *buf, size_t len):size_t:len 49*387f9dfdSAndroid Build Coastguard Worker len : count distribution 50*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 51*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 2 |************* | 52*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 53*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 2 |************* | 54*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 0 | | 55*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 6 |****************************************| 56*387f9dfdSAndroid Build Coastguard Worker[01:45:23] 57*387f9dfdSAndroid Build Coastguard Workerp:c:write(int fd, void *buf, size_t len):size_t:len 58*387f9dfdSAndroid Build Coastguard Worker len : count distribution 59*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 60*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 11 |*************** | 61*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 62*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 4 |***** | 63*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 0 | | 64*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 28 |****************************************| 65*387f9dfdSAndroid Build Coastguard Worker 64 -> 127 : 12 |***************** | 66*387f9dfdSAndroid Build Coastguard Worker[01:45:24] 67*387f9dfdSAndroid Build Coastguard Workerp:c:write(int fd, void *buf, size_t len):size_t:len 68*387f9dfdSAndroid Build Coastguard Worker len : count distribution 69*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 70*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 21 |**************** | 71*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 72*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 6 |**** | 73*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 0 | | 74*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 52 |****************************************| 75*387f9dfdSAndroid Build Coastguard Worker 64 -> 127 : 26 |******************** | 76*387f9dfdSAndroid Build Coastguard Worker^C 77*387f9dfdSAndroid Build Coastguard Worker 78*387f9dfdSAndroid Build Coastguard WorkerIt seems that most writes fall into three buckets: very small writes of 2-3 79*387f9dfdSAndroid Build Coastguard Workerbytes, medium writes of 32-63 bytes, and larger writes of 64-127 bytes. 80*387f9dfdSAndroid Build Coastguard Worker 81*387f9dfdSAndroid Build Coastguard WorkerBut these are writes across the board -- what if you wanted to focus on writes 82*387f9dfdSAndroid Build Coastguard Workerto STDOUT? 83*387f9dfdSAndroid Build Coastguard Worker 84*387f9dfdSAndroid Build Coastguard Worker# ./argdist -c -H 'p:c:write(int fd, void *buf, size_t len):size_t:len:fd==1' 85*387f9dfdSAndroid Build Coastguard Worker[01:47:17] 86*387f9dfdSAndroid Build Coastguard Workerp:c:write(int fd, void *buf, size_t len):size_t:len:fd==1 87*387f9dfdSAndroid Build Coastguard Worker len : count distribution 88*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 89*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 90*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 91*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 1 |****************************************| 92*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 0 | | 93*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 1 |****************************************| 94*387f9dfdSAndroid Build Coastguard Worker[01:47:18] 95*387f9dfdSAndroid Build Coastguard Workerp:c:write(int fd, void *buf, size_t len):size_t:len:fd==1 96*387f9dfdSAndroid Build Coastguard Worker len : count distribution 97*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 98*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 99*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 100*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 2 |************* | 101*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 0 | | 102*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 3 |******************** | 103*387f9dfdSAndroid Build Coastguard Worker 64 -> 127 : 6 |****************************************| 104*387f9dfdSAndroid Build Coastguard Worker[01:47:19] 105*387f9dfdSAndroid Build Coastguard Workerp:c:write(int fd, void *buf, size_t len):size_t:len:fd==1 106*387f9dfdSAndroid Build Coastguard Worker len : count distribution 107*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 108*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 109*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 110*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 3 |********* | 111*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 0 | | 112*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 5 |*************** | 113*387f9dfdSAndroid Build Coastguard Worker 64 -> 127 : 13 |****************************************| 114*387f9dfdSAndroid Build Coastguard Worker^C 115*387f9dfdSAndroid Build Coastguard Worker 116*387f9dfdSAndroid Build Coastguard WorkerThe "fd==1" part is a filter that is applied to every invocation of write(). 117*387f9dfdSAndroid Build Coastguard WorkerOnly if the filter condition is true, the value is recorded. 118*387f9dfdSAndroid Build Coastguard Worker 119*387f9dfdSAndroid Build Coastguard WorkerYou can also use argdist to trace kernel functions. For example, suppose you 120*387f9dfdSAndroid Build Coastguard Workerwanted a histogram of kernel allocation (kmalloc) sizes across the system, 121*387f9dfdSAndroid Build Coastguard Workerprinted twice with 3 second intervals: 122*387f9dfdSAndroid Build Coastguard Worker 123*387f9dfdSAndroid Build Coastguard Worker# ./argdist -i 3 -n 2 -H 'p::__kmalloc(size_t size):size_t:size' 124*387f9dfdSAndroid Build Coastguard Worker[01:50:00] 125*387f9dfdSAndroid Build Coastguard Workerp::__kmalloc(size_t size):size_t:size 126*387f9dfdSAndroid Build Coastguard Worker size : count distribution 127*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 128*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 129*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 130*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 6 |****************************************| 131*387f9dfdSAndroid Build Coastguard Worker[01:50:03] 132*387f9dfdSAndroid Build Coastguard Workerp::__kmalloc(size_t size):size_t:size 133*387f9dfdSAndroid Build Coastguard Worker size : count distribution 134*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 135*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 136*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 137*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 22 |****************************************| 138*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 0 | | 139*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 0 | | 140*387f9dfdSAndroid Build Coastguard Worker 64 -> 127 : 5 |********* | 141*387f9dfdSAndroid Build Coastguard Worker 128 -> 255 : 2 |*** | 142*387f9dfdSAndroid Build Coastguard Worker 143*387f9dfdSAndroid Build Coastguard WorkerOccasionally, numeric information isn't enough and you want to capture strings. 144*387f9dfdSAndroid Build Coastguard WorkerWhat are the strings printed by puts() across the system? 145*387f9dfdSAndroid Build Coastguard Worker 146*387f9dfdSAndroid Build Coastguard Worker# ./argdist -i 10 -n 1 -C 'p:c:puts(char *str):char*:str' 147*387f9dfdSAndroid Build Coastguard Worker[01:53:54] 148*387f9dfdSAndroid Build Coastguard Workerp:c:puts(char *str):char*:str 149*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 150*387f9dfdSAndroid Build Coastguard Worker 2 str = Press ENTER to start. 151*387f9dfdSAndroid Build Coastguard Worker 152*387f9dfdSAndroid Build Coastguard WorkerIt looks like the message "Press ENTER to start." was printed twice during the 153*387f9dfdSAndroid Build Coastguard Worker10 seconds we were tracing. 154*387f9dfdSAndroid Build Coastguard Worker 155*387f9dfdSAndroid Build Coastguard WorkerWhat about reads? You could trace gets() across the system and print the 156*387f9dfdSAndroid Build Coastguard Workerstrings input by the user (note how "r" is used instead of "p" to attach a 157*387f9dfdSAndroid Build Coastguard Workerprobe to the function's return): 158*387f9dfdSAndroid Build Coastguard Worker 159*387f9dfdSAndroid Build Coastguard Worker# ./argdist -i 10 -n 1 -C 'r:c:gets():char*:(char*)$retval:$retval!=0' 160*387f9dfdSAndroid Build Coastguard Worker[02:12:23] 161*387f9dfdSAndroid Build Coastguard Workerr:c:gets():char*:$retval:$retval!=0 162*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 163*387f9dfdSAndroid Build Coastguard Worker 1 (char*)$retval = hi there 164*387f9dfdSAndroid Build Coastguard Worker 3 (char*)$retval = sasha 165*387f9dfdSAndroid Build Coastguard Worker 8 (char*)$retval = hello 166*387f9dfdSAndroid Build Coastguard Worker 167*387f9dfdSAndroid Build Coastguard WorkerSimilarly, we could get a histogram of the error codes returned by read(): 168*387f9dfdSAndroid Build Coastguard Worker 169*387f9dfdSAndroid Build Coastguard Worker# ./argdist -i 10 -c 1 -H 'r:c:read()' 170*387f9dfdSAndroid Build Coastguard Worker[02:15:36] 171*387f9dfdSAndroid Build Coastguard Workerr:c:read() 172*387f9dfdSAndroid Build Coastguard Worker retval : count distribution 173*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 29 |****************************************| 174*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 11 |*************** | 175*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 176*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 3 |**** | 177*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 2 |** | 178*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 22 |****************************** | 179*387f9dfdSAndroid Build Coastguard Worker 64 -> 127 : 5 |****** | 180*387f9dfdSAndroid Build Coastguard Worker 128 -> 255 : 0 | | 181*387f9dfdSAndroid Build Coastguard Worker 256 -> 511 : 1 |* | 182*387f9dfdSAndroid Build Coastguard Worker 512 -> 1023 : 1 |* | 183*387f9dfdSAndroid Build Coastguard Worker 1024 -> 2047 : 0 | | 184*387f9dfdSAndroid Build Coastguard Worker 2048 -> 4095 : 2 |** | 185*387f9dfdSAndroid Build Coastguard Worker 186*387f9dfdSAndroid Build Coastguard WorkerIn return probes, you can also trace the latency of the function (unless it is 187*387f9dfdSAndroid Build Coastguard Workerrecursive) and the parameters it had on entry. For example, we can identify 188*387f9dfdSAndroid Build Coastguard Workerwhich processes are performing slow synchronous filesystem reads -- say, 189*387f9dfdSAndroid Build Coastguard Workerlonger than 0.1ms (100,000ns): 190*387f9dfdSAndroid Build Coastguard Worker 191*387f9dfdSAndroid Build Coastguard Worker# ./argdist -C 'r::__vfs_read():u32:$PID:$latency > 100000' 192*387f9dfdSAndroid Build Coastguard Worker[01:08:48] 193*387f9dfdSAndroid Build Coastguard Workerr::__vfs_read():u32:$PID:$latency > 100000 194*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 195*387f9dfdSAndroid Build Coastguard Worker 1 $PID = 10457 196*387f9dfdSAndroid Build Coastguard Worker 21 $PID = 2780 197*387f9dfdSAndroid Build Coastguard Worker[01:08:49] 198*387f9dfdSAndroid Build Coastguard Workerr::__vfs_read():u32:$PID:$latency > 100000 199*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 200*387f9dfdSAndroid Build Coastguard Worker 1 $PID = 10457 201*387f9dfdSAndroid Build Coastguard Worker 21 $PID = 2780 202*387f9dfdSAndroid Build Coastguard Worker^C 203*387f9dfdSAndroid Build Coastguard Worker 204*387f9dfdSAndroid Build Coastguard WorkerIt looks like process 2780 performed 21 slow reads. 205*387f9dfdSAndroid Build Coastguard Worker 206*387f9dfdSAndroid Build Coastguard WorkerYou can print the name of the process. This is helpful for short lived processes 207*387f9dfdSAndroid Build Coastguard Workerand for easier identification of processes response. For example, we can identify 208*387f9dfdSAndroid Build Coastguard Workerthe process using the epoll I/O multiplexing system call 209*387f9dfdSAndroid Build Coastguard Worker 210*387f9dfdSAndroid Build Coastguard Worker# ./argdist -C 't:syscalls:sys_exit_epoll_wait():char*:$COMM' 211*387f9dfdSAndroid Build Coastguard Worker[19:57:56] 212*387f9dfdSAndroid Build Coastguard Workert:syscalls:sys_exit_epoll_wait():char*:$COMM 213*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 214*387f9dfdSAndroid Build Coastguard Worker 4 $COMM = b'node' 215*387f9dfdSAndroid Build Coastguard Worker[19:57:57] 216*387f9dfdSAndroid Build Coastguard Workert:syscalls:sys_exit_epoll_wait():char*:$COMM 217*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 218*387f9dfdSAndroid Build Coastguard Worker 2 $COMM = b'open5gs-sgwud' 219*387f9dfdSAndroid Build Coastguard Worker 3 $COMM = b'open5gs-sgwcd' 220*387f9dfdSAndroid Build Coastguard Worker 3 $COMM = b'open5gs-nrfd' 221*387f9dfdSAndroid Build Coastguard Worker 3 $COMM = b'open5gs-udmd' 222*387f9dfdSAndroid Build Coastguard Worker 4 $COMM = b'open5gs-scpd' 223*387f9dfdSAndroid Build Coastguard Worker 224*387f9dfdSAndroid Build Coastguard WorkerOccasionally, entry parameter values are also interesting. For example, you 225*387f9dfdSAndroid Build Coastguard Workermight be curious how long it takes malloc() to allocate memory -- nanoseconds 226*387f9dfdSAndroid Build Coastguard Workerper byte allocated. Let's go: 227*387f9dfdSAndroid Build Coastguard Worker 228*387f9dfdSAndroid Build Coastguard Worker# ./argdist -H 'r:c:malloc(size_t size):u64:$latency/$entry(size);ns per byte' -n 1 -i 10 229*387f9dfdSAndroid Build Coastguard Worker[01:11:13] 230*387f9dfdSAndroid Build Coastguard Worker ns per byte : count distribution 231*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 232*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 4 |***************** | 233*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 3 |************* | 234*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 2 |******** | 235*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 1 |**** | 236*387f9dfdSAndroid Build Coastguard Worker 32 -> 63 : 0 | | 237*387f9dfdSAndroid Build Coastguard Worker 64 -> 127 : 7 |******************************* | 238*387f9dfdSAndroid Build Coastguard Worker 128 -> 255 : 1 |**** | 239*387f9dfdSAndroid Build Coastguard Worker 256 -> 511 : 0 | | 240*387f9dfdSAndroid Build Coastguard Worker 512 -> 1023 : 1 |**** | 241*387f9dfdSAndroid Build Coastguard Worker 1024 -> 2047 : 1 |**** | 242*387f9dfdSAndroid Build Coastguard Worker 2048 -> 4095 : 9 |****************************************| 243*387f9dfdSAndroid Build Coastguard Worker 4096 -> 8191 : 1 |**** | 244*387f9dfdSAndroid Build Coastguard Worker 245*387f9dfdSAndroid Build Coastguard WorkerIt looks like a tri-modal distribution. Some allocations are extremely cheap, 246*387f9dfdSAndroid Build Coastguard Workerand take 2-15 nanoseconds per byte. Other allocations are slower, and take 247*387f9dfdSAndroid Build Coastguard Worker64-127 nanoseconds per byte. And some allocations are slower still, and take 248*387f9dfdSAndroid Build Coastguard Workermultiple microseconds per byte. 249*387f9dfdSAndroid Build Coastguard Worker 250*387f9dfdSAndroid Build Coastguard WorkerYou could also group results by more than one field. For example, __kmalloc 251*387f9dfdSAndroid Build Coastguard Workertakes an additional flags parameter that describes how to allocate memory: 252*387f9dfdSAndroid Build Coastguard Worker 253*387f9dfdSAndroid Build Coastguard Worker# ./argdist -c -C 'p::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size' 254*387f9dfdSAndroid Build Coastguard Worker[03:42:29] 255*387f9dfdSAndroid Build Coastguard Workerp::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size 256*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 257*387f9dfdSAndroid Build Coastguard Worker 1 flags = 16, size = 152 258*387f9dfdSAndroid Build Coastguard Worker 2 flags = 131280, size = 8 259*387f9dfdSAndroid Build Coastguard Worker 7 flags = 131280, size = 16 260*387f9dfdSAndroid Build Coastguard Worker[03:42:30] 261*387f9dfdSAndroid Build Coastguard Workerp::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size 262*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 263*387f9dfdSAndroid Build Coastguard Worker 1 flags = 16, size = 152 264*387f9dfdSAndroid Build Coastguard Worker 6 flags = 131280, size = 8 265*387f9dfdSAndroid Build Coastguard Worker 19 flags = 131280, size = 16 266*387f9dfdSAndroid Build Coastguard Worker[03:42:31] 267*387f9dfdSAndroid Build Coastguard Workerp::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size 268*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 269*387f9dfdSAndroid Build Coastguard Worker 2 flags = 16, size = 152 270*387f9dfdSAndroid Build Coastguard Worker 10 flags = 131280, size = 8 271*387f9dfdSAndroid Build Coastguard Worker 31 flags = 131280, size = 16 272*387f9dfdSAndroid Build Coastguard Worker[03:42:32] 273*387f9dfdSAndroid Build Coastguard Workerp::__kmalloc(size_t size, gfp_t flags):gfp_t,size_t:flags,size 274*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 275*387f9dfdSAndroid Build Coastguard Worker 2 flags = 16, size = 152 276*387f9dfdSAndroid Build Coastguard Worker 14 flags = 131280, size = 8 277*387f9dfdSAndroid Build Coastguard Worker 43 flags = 131280, size = 16 278*387f9dfdSAndroid Build Coastguard Worker^C 279*387f9dfdSAndroid Build Coastguard Worker 280*387f9dfdSAndroid Build Coastguard WorkerThe flags value must be expanded by hand, but it's still helpful to eliminate 281*387f9dfdSAndroid Build Coastguard Workercertain kinds of allocations or visually group them together. 282*387f9dfdSAndroid Build Coastguard Worker 283*387f9dfdSAndroid Build Coastguard Workerargdist also has basic support for kernel tracepoints. It is sometimes more 284*387f9dfdSAndroid Build Coastguard Workerconvenient to use tracepoints because they are documented and don't vary a lot 285*387f9dfdSAndroid Build Coastguard Workerbetween kernel versions. For example, let's trace the net:net_dev_start_xmit 286*387f9dfdSAndroid Build Coastguard Workertracepoint and print out the protocol field from the tracepoint structure: 287*387f9dfdSAndroid Build Coastguard Worker 288*387f9dfdSAndroid Build Coastguard Worker# argdist -C 't:net:net_dev_start_xmit():u16:args->protocol' 289*387f9dfdSAndroid Build Coastguard Worker[13:01:49] 290*387f9dfdSAndroid Build Coastguard Workert:net:net_dev_start_xmit():u16:args->protocol 291*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 292*387f9dfdSAndroid Build Coastguard Worker 8 args->protocol = 2048 293*387f9dfdSAndroid Build Coastguard Worker^C 294*387f9dfdSAndroid Build Coastguard Worker 295*387f9dfdSAndroid Build Coastguard WorkerNote that to discover the format of the net:net_dev_start_xmit tracepoint, you 296*387f9dfdSAndroid Build Coastguard Workeruse the tplist tool (tplist -v net:net_dev_start_xmit). 297*387f9dfdSAndroid Build Coastguard Worker 298*387f9dfdSAndroid Build Coastguard Worker 299*387f9dfdSAndroid Build Coastguard WorkerOccasionally, it is useful to filter certain expressions by string. This is not 300*387f9dfdSAndroid Build Coastguard Workertrivially supported by BPF, but argdist provides a STRCMP helper you can use in 301*387f9dfdSAndroid Build Coastguard Workerfilter expressions. For example, to get a histogram of latencies opening a 302*387f9dfdSAndroid Build Coastguard Workerspecific file, run this: 303*387f9dfdSAndroid Build Coastguard Worker 304*387f9dfdSAndroid Build Coastguard Worker# argdist -c -H 'r:c:open(char *file):u64:$latency/1000:STRCMP("test.txt",$entry(file))' 305*387f9dfdSAndroid Build Coastguard Worker[02:16:38] 306*387f9dfdSAndroid Build Coastguard Worker[02:16:39] 307*387f9dfdSAndroid Build Coastguard Worker[02:16:40] 308*387f9dfdSAndroid Build Coastguard Worker $latency/1000 : count distribution 309*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 310*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 311*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 312*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 0 | | 313*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 2 |****************************************| 314*387f9dfdSAndroid Build Coastguard Worker[02:16:41] 315*387f9dfdSAndroid Build Coastguard Worker $latency/1000 : count distribution 316*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 317*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 318*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 319*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 1 |********** | 320*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 4 |****************************************| 321*387f9dfdSAndroid Build Coastguard Worker[02:16:42] 322*387f9dfdSAndroid Build Coastguard Worker $latency/1000 : count distribution 323*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 324*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 325*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 326*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 1 |******** | 327*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 5 |****************************************| 328*387f9dfdSAndroid Build Coastguard Worker[02:16:43] 329*387f9dfdSAndroid Build Coastguard Worker $latency/1000 : count distribution 330*387f9dfdSAndroid Build Coastguard Worker 0 -> 1 : 0 | | 331*387f9dfdSAndroid Build Coastguard Worker 2 -> 3 : 0 | | 332*387f9dfdSAndroid Build Coastguard Worker 4 -> 7 : 0 | | 333*387f9dfdSAndroid Build Coastguard Worker 8 -> 15 : 1 |******** | 334*387f9dfdSAndroid Build Coastguard Worker 16 -> 31 : 5 |****************************************| 335*387f9dfdSAndroid Build Coastguard Worker 336*387f9dfdSAndroid Build Coastguard Worker 337*387f9dfdSAndroid Build Coastguard WorkerHere's a final example that finds how many write() system calls are performed 338*387f9dfdSAndroid Build Coastguard Workerby each process on the system: 339*387f9dfdSAndroid Build Coastguard Worker 340*387f9dfdSAndroid Build Coastguard Worker# argdist -c -C 'p:c:write():int:$PID;write per process' -n 2 341*387f9dfdSAndroid Build Coastguard Worker[06:47:18] 342*387f9dfdSAndroid Build Coastguard Workerwrite by process 343*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 344*387f9dfdSAndroid Build Coastguard Worker 3 $PID = 8889 345*387f9dfdSAndroid Build Coastguard Worker 7 $PID = 7615 346*387f9dfdSAndroid Build Coastguard Worker 7 $PID = 2480 347*387f9dfdSAndroid Build Coastguard Worker[06:47:19] 348*387f9dfdSAndroid Build Coastguard Workerwrite by process 349*387f9dfdSAndroid Build Coastguard Worker COUNT EVENT 350*387f9dfdSAndroid Build Coastguard Worker 9 $PID = 8889 351*387f9dfdSAndroid Build Coastguard Worker 23 $PID = 7615 352*387f9dfdSAndroid Build Coastguard Worker 23 $PID = 2480 353*387f9dfdSAndroid Build Coastguard Worker 354*387f9dfdSAndroid Build Coastguard Worker 355*387f9dfdSAndroid Build Coastguard WorkerUSAGE message: 356*387f9dfdSAndroid Build Coastguard Worker 357*387f9dfdSAndroid Build Coastguard Worker# argdist -h 358*387f9dfdSAndroid Build Coastguard Workerusage: argdist [-h] [-p PID] [-z STRING_SIZE] [-i INTERVAL] [-n COUNT] [-v] 359*387f9dfdSAndroid Build Coastguard Worker [-c] [-T TOP] [-H specifier] [-C[specifier] [-I header] 360*387f9dfdSAndroid Build Coastguard Worker 361*387f9dfdSAndroid Build Coastguard WorkerTrace a function and display a summary of its parameter values. 362*387f9dfdSAndroid Build Coastguard Worker 363*387f9dfdSAndroid Build Coastguard Workeroptional arguments: 364*387f9dfdSAndroid Build Coastguard Worker -h, --help show this help message and exit 365*387f9dfdSAndroid Build Coastguard Worker -p PID, --pid PID id of the process to trace (optional) 366*387f9dfdSAndroid Build Coastguard Worker -t TID, --tid TID id of the thread to trace (optional) 367*387f9dfdSAndroid Build Coastguard Worker -z STRING_SIZE, --string-size STRING_SIZE 368*387f9dfdSAndroid Build Coastguard Worker maximum string size to read from char* arguments 369*387f9dfdSAndroid Build Coastguard Worker -i INTERVAL, --interval INTERVAL 370*387f9dfdSAndroid Build Coastguard Worker output interval, in seconds (default 1 second) 371*387f9dfdSAndroid Build Coastguard Worker -d DURATION, --duration DURATION 372*387f9dfdSAndroid Build Coastguard Worker total duration of trace, in seconds 373*387f9dfdSAndroid Build Coastguard Worker -n COUNT, --number COUNT 374*387f9dfdSAndroid Build Coastguard Worker number of outputs 375*387f9dfdSAndroid Build Coastguard Worker -v, --verbose print resulting BPF program code before executing 376*387f9dfdSAndroid Build Coastguard Worker -c, --cumulative do not clear histograms and freq counts at each interval 377*387f9dfdSAndroid Build Coastguard Worker -T TOP, --top TOP number of top results to show (not applicable to 378*387f9dfdSAndroid Build Coastguard Worker histograms) 379*387f9dfdSAndroid Build Coastguard Worker -H specifier, --histogram specifier 380*387f9dfdSAndroid Build Coastguard Worker probe specifier to capture histogram of (see examples 381*387f9dfdSAndroid Build Coastguard Worker below) 382*387f9dfdSAndroid Build Coastguard Worker -C specifier, --count specifier 383*387f9dfdSAndroid Build Coastguard Worker probe specifier to capture count of (see examples 384*387f9dfdSAndroid Build Coastguard Worker below) 385*387f9dfdSAndroid Build Coastguard Worker -I header, --include header 386*387f9dfdSAndroid Build Coastguard Worker additional header files to include in the BPF program 387*387f9dfdSAndroid Build Coastguard Worker as either full path, or relative to current working directory, 388*387f9dfdSAndroid Build Coastguard Worker or relative to default kernel header search path 389*387f9dfdSAndroid Build Coastguard Worker 390*387f9dfdSAndroid Build Coastguard WorkerProbe specifier syntax: 391*387f9dfdSAndroid Build Coastguard Worker {p,r,t,u}:{[library],category}:function(signature)[:type[,type...]:expr[,expr...][:filter]][#label] 392*387f9dfdSAndroid Build Coastguard WorkerWhere: 393*387f9dfdSAndroid Build Coastguard Worker p,r,t,u -- probe at function entry, function exit, kernel tracepoint, 394*387f9dfdSAndroid Build Coastguard Worker or USDT probe 395*387f9dfdSAndroid Build Coastguard Worker in exit probes: can use $retval, $entry(param), $latency 396*387f9dfdSAndroid Build Coastguard Worker library -- the library that contains the function 397*387f9dfdSAndroid Build Coastguard Worker (leave empty for kernel functions) 398*387f9dfdSAndroid Build Coastguard Worker category -- the category of the kernel tracepoint (e.g. net, sched) 399*387f9dfdSAndroid Build Coastguard Worker signature -- the function's parameters, as in the C header 400*387f9dfdSAndroid Build Coastguard Worker type -- the type of the expression to collect (supports multiple) 401*387f9dfdSAndroid Build Coastguard Worker expr -- the expression to collect (supports multiple) 402*387f9dfdSAndroid Build Coastguard Worker filter -- the filter that is applied to collected values 403*387f9dfdSAndroid Build Coastguard Worker label -- the label for this probe in the resulting output 404*387f9dfdSAndroid Build Coastguard Worker 405*387f9dfdSAndroid Build Coastguard WorkerEXAMPLES: 406*387f9dfdSAndroid Build Coastguard Worker 407*387f9dfdSAndroid Build Coastguard Workerargdist -H 'p::__kmalloc(u64 size):u64:size' 408*387f9dfdSAndroid Build Coastguard Worker Print a histogram of allocation sizes passed to kmalloc 409*387f9dfdSAndroid Build Coastguard Worker 410*387f9dfdSAndroid Build Coastguard Workerargdist -p 1005 -C 'p:c:malloc(size_t size):size_t:size:size==16' 411*387f9dfdSAndroid Build Coastguard Worker Print a frequency count of how many times process 1005 called malloc 412*387f9dfdSAndroid Build Coastguard Worker with an allocation size of 16 bytes 413*387f9dfdSAndroid Build Coastguard Worker 414*387f9dfdSAndroid Build Coastguard Workerargdist -C 'r:c:gets():char*:$retval#snooped strings' 415*387f9dfdSAndroid Build Coastguard Worker Snoop on all strings returned by gets() 416*387f9dfdSAndroid Build Coastguard Worker 417*387f9dfdSAndroid Build Coastguard Workerargdist -H 'r::__kmalloc(size_t size):u64:$latency/$entry(size)#ns per byte' 418*387f9dfdSAndroid Build Coastguard Worker Print a histogram of nanoseconds per byte from kmalloc allocations 419*387f9dfdSAndroid Build Coastguard Worker 420*387f9dfdSAndroid Build Coastguard Workerargdist -C 'p::__kmalloc(size_t size, gfp_t flags):size_t:size:flags&GFP_ATOMIC' 421*387f9dfdSAndroid Build Coastguard Worker Print frequency count of kmalloc allocation sizes that have GFP_ATOMIC 422*387f9dfdSAndroid Build Coastguard Worker 423*387f9dfdSAndroid Build Coastguard Workerargdist -p 1005 -C 'p:c:write(int fd):int:fd' -T 5 424*387f9dfdSAndroid Build Coastguard Worker Print frequency counts of how many times writes were issued to a 425*387f9dfdSAndroid Build Coastguard Worker particular file descriptor number, in process 1005, but only show 426*387f9dfdSAndroid Build Coastguard Worker the top 5 busiest fds 427*387f9dfdSAndroid Build Coastguard Worker 428*387f9dfdSAndroid Build Coastguard Workerargdist -p 1005 -H 'r:c:read()' 429*387f9dfdSAndroid Build Coastguard Worker Print a histogram of error codes returned by read() in process 1005 430*387f9dfdSAndroid Build Coastguard Worker 431*387f9dfdSAndroid Build Coastguard Workerargdist -C 'r::__vfs_read():u32:$PID:$latency > 100000' 432*387f9dfdSAndroid Build Coastguard Worker Print frequency of reads by process where the latency was >0.1ms 433*387f9dfdSAndroid Build Coastguard Worker 434*387f9dfdSAndroid Build Coastguard Workerargdist -C 'r::__vfs_read():u32:$COMM:$latency > 100000' 435*387f9dfdSAndroid Build Coastguard Worker Print frequency of reads by process name where the latency was >0.1ms 436*387f9dfdSAndroid Build Coastguard Worker 437*387f9dfdSAndroid Build Coastguard Workerargdist -H 'r::__vfs_read(void *file, void *buf, size_t count):size_t:$entry(count):$latency > 1000000' 438*387f9dfdSAndroid Build Coastguard Worker Print a histogram of read sizes that were longer than 1ms 439*387f9dfdSAndroid Build Coastguard Worker 440*387f9dfdSAndroid Build Coastguard Workerargdist -H \ 441*387f9dfdSAndroid Build Coastguard Worker 'p:c:write(int fd, const void *buf, size_t count):size_t:count:fd==1' 442*387f9dfdSAndroid Build Coastguard Worker Print a histogram of buffer sizes passed to write() across all 443*387f9dfdSAndroid Build Coastguard Worker processes, where the file descriptor was 1 (STDOUT) 444*387f9dfdSAndroid Build Coastguard Worker 445*387f9dfdSAndroid Build Coastguard Workerargdist -C 'p:c:fork()#fork calls' 446*387f9dfdSAndroid Build Coastguard Worker Count fork() calls in libc across all processes 447*387f9dfdSAndroid Build Coastguard Worker Can also use funccount.py, which is easier and more flexible 448*387f9dfdSAndroid Build Coastguard Worker 449*387f9dfdSAndroid Build Coastguard Workerargdist -H 't:block:block_rq_complete():u32:args->nr_sector' 450*387f9dfdSAndroid Build Coastguard Worker Print histogram of number of sectors in completing block I/O requests 451*387f9dfdSAndroid Build Coastguard Worker 452*387f9dfdSAndroid Build Coastguard Workerargdist -C 't:irq:irq_handler_entry():int:args->irq' 453*387f9dfdSAndroid Build Coastguard Worker Aggregate interrupts by interrupt request (IRQ) 454*387f9dfdSAndroid Build Coastguard Worker 455*387f9dfdSAndroid Build Coastguard Workerargdist -C 'u:pthread:pthread_start():u64:arg2' -p 1337 456*387f9dfdSAndroid Build Coastguard Worker Print frequency of function addresses used as a pthread start function, 457*387f9dfdSAndroid Build Coastguard Worker relying on the USDT pthread_start probe in process 1337 458*387f9dfdSAndroid Build Coastguard Worker 459*387f9dfdSAndroid Build Coastguard Workerargdist -H 'p:c:sleep(u32 seconds):u32:seconds' \ 460*387f9dfdSAndroid Build Coastguard Worker -H 'p:c:nanosleep(struct timespec *req):long:req->tv_nsec' 461*387f9dfdSAndroid Build Coastguard Worker Print histograms of sleep() and nanosleep() parameter values 462*387f9dfdSAndroid Build Coastguard Worker 463*387f9dfdSAndroid Build Coastguard Workerargdist -p 2780 -z 120 \ 464*387f9dfdSAndroid Build Coastguard Worker -C 'p:c:write(int fd, char* buf, size_t len):char*:buf:fd==1' 465*387f9dfdSAndroid Build Coastguard Worker Spy on writes to STDOUT performed by process 2780, up to a string size 466*387f9dfdSAndroid Build Coastguard Worker of 120 characters 467*387f9dfdSAndroid Build Coastguard Worker 468*387f9dfdSAndroid Build Coastguard Workerargdist -I 'kernel/sched/sched.h' \ 469*387f9dfdSAndroid Build Coastguard Worker -C 'p::__account_cfs_rq_runtime(struct cfs_rq *cfs_rq):s64:cfs_rq->runtime_remaining' 470*387f9dfdSAndroid Build Coastguard Worker Trace on the cfs scheduling runqueue remaining runtime. The struct cfs_rq is defined 471*387f9dfdSAndroid Build Coastguard Worker in kernel/sched/sched.h which is in kernel source tree and not in kernel-devel 472*387f9dfdSAndroid Build Coastguard Worker package. So this command needs to run at the kernel source tree root directory 473*387f9dfdSAndroid Build Coastguard Worker so that the added header file can be found by the compiler. 474*387f9dfdSAndroid Build Coastguard Worker 475*387f9dfdSAndroid Build Coastguard Workerargdist -C 'p::do_sys_open(int dfd, const char __user *filename, int flags, 476*387f9dfdSAndroid Build Coastguard Worker umode_t mode):char*:filename:STRCMP("sample.txt", filename)' 477*387f9dfdSAndroid Build Coastguard Worker Trace open of the file "sample.txt". It should be noted that 'filename' 478*387f9dfdSAndroid Build Coastguard Worker passed to the do_sys_open is a char * user pointer. Hence parameter 479*387f9dfdSAndroid Build Coastguard Worker 'filename' should be tagged with __user for kprobes (const char __user 480*387f9dfdSAndroid Build Coastguard Worker *filename). This information distinguishes if the 'filename' should be 481*387f9dfdSAndroid Build Coastguard Worker copied from userspace to the bpf stack or from kernel space to the bpf 482*387f9dfdSAndroid Build Coastguard Worker stack. 483