Valgrind-mmt is a Valgrind modification which allows tracing application accesses to mmaped memory (which is how userspace parts of graphics drivers communicate with hardware). It was created by Dave Airlie and then extended/fixed by others.
Installation:
git clone https://github.com/envytools/valgrind.git cd valgrind ./autogen.sh ./configure --prefix=... make make install
Use:
valgrind --tool=mmt --mmt-trace-nvidia-ioctls --log-file=file-bin.log glxgears
Options:
--mmt-trace-file=path trace loads and stores to memory mapped for this file (e.g. /dev/nvidia0) (you can pass this option multiple times) --mmt-trace-all-files trace loads and stores to memory mapped for all files --mmt-trace-nvidia-ioctls trace nvidia ioctls on /dev/nvidia*, implies --mmt-trace-file on all /dev/nvidia* files --mmt-trace-nouveau-ioctls trace nouveau ioctls on /dev/dri/cardX, implies --mmt-trace-file on /dev/dri/cardX file connected to nouveau --mmt-trace-fglrx-ioctls trace fglrx ioctls, implies --mmt-trace-file on all /dev/ati/* files --mmt-trace-all-opens trace all 'open' syscalls --mmt-trace-marks send mmiotrace marks before and after ioctls --mmt-trace-stdout-stderr trace writes to stdout and stderr --mmt-ioctl-create-fuzzer= 0-disabled (default), 1-enabled (safe), 2-enabled (unsafe) --mmt-object-ctr=class,cargs sets the number of u32 constructor args(dec) for specified class(hex) --mmt-ioctl-call-fuzzer= 0-disabled (default), 1-enabled --mmt-sync-file=path emit synchronization markers in output stream and wait for replies from specified file
What to do with generated trace:
You can decode (binary) trace by:
./demmt -l file-bin.log
or translate it to text:
./mmt_bin2dedma < file-bin.log > file-txt.log
and feed it to dedma:
./dedma -m nvXX -v $(mapid) file-txt.log | less -SR
where $(mapid) is a buffer number. Note that dedma is a pretty basic tool and have unfixable bugs. Using demmt is recommended.
All decoding tools (demmt, mmt_bin2dedma and dedma) are from envytools repository.
Note: Valgrind-mmt used to output in purely text form (dedma-compatible). However, due to binary output being way more powerful, the text output was removed.
All demmt options:
-l file use "file" as input (can be compressed by: xz, bzip2, gzip) -q print only the most important data (quiet); shortcut for: -d all -e pb,shader,macro,tsc,tic,cp,classes=all,buffer-usage,nvrm-class-desc -m chipset set chipset version (default: auto-detect based on trace content and file name (nvXX...)) -c 0/1 disable/enable colors (default: 1 if stdout is a terminal) -g 0/1 = -d/-e gpu-addr (default: 0) -o 0/1 = -d/-e ioctl-raw (default: 0) -r 0/1 = -d/-e macro-rt-verbose (default: 0) -p 0/1 disable/enable pager (default: 1 if stdout is a terminal) -i 0/1 disable/enable log indentation (default: 0) -a = -d classes=all -s file in response to sync markers in input file: flush the output stream and reply by writing marker id to specified file (see: scripts/mmiotrace/mmt-app-demmt-mmiotrace.sh) -d msg_type1[,msg_type2[,msg_type3....]] - disable messages -e msg_type1[,msg_type2[,msg_type3....]] - enable messages message types: - write - memory write - read - memory read - gpu-addr - gpu address - mem = read,write - pb - push buffer - class=[all,0x...] - class decoder - tsc - texture sampler control block - tic - texture image control block - vp - vertex program - fp - fragment program - gp - geometry program - cp - compute program - tep - tcp - shader = vp,fp,gp,tep,tcp - macro-rt-verbose - verbose macro interpreter - macro-rt - macro interpreter - macro-dis - macro disasm - macro = macro-rt,macro-dis - sys_mmap - sys_mmap_details - prot & flags - sys_munmap - sys_mremap - sys_open - sys_write - sys = sys_mmap,sys_munmap,sys_mremap,sys_open,sys_write,ioctl-desc - ioctl-raw - raw ioctl data - ioctl-desc - decoded ioctl - ioctl = ioctl-raw,ioctl-desc - nvrm-ioctl=[all,name] name=create,call,host_map,etc... - nvrm-mthd=[all,0x...] - method call - nvrm-handle-desc - handle description - nvrm-class-desc - class description - nvrm-unk-0-fields - unk zero fields - nvrm-obj-tree - object tree after create and before destroy ioctls - nvrm = nvrm-ioctl=all,nvrm-mthd=all,nvrm-handle-desc,nvrm-class-desc - buffer-usage - msg - textual valgrind message - info - various informations - all - everything above
Some notes about tracing Xorg:
- Valgrind can't trace suid binaries, so you have to copy Xorg, unset its suid bit, and trace that file.
- Because of the above, you need to be root when tracing.
- X and Xorg sometimes are not the same file. Make sure you are tracing the correct file.
- Running plain Xorg binary won't load any window manager, so before tracing, start on another console:
export DISPLAY=:0; while [ true ]; do xterm; sleep 1; done
- When Valgrind crashes, Xorg leaves only black screen - you need to press Alt-SysRq-R, switch to some free console (ctrl-alt-fxx), blindly login and start normal Xorg (startx)