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)