It would probably not be an exaggeration to say Emacs has myriad commands out of the box (with the standard distribution) and probably no single person knows them all. The key to being productive with Emacs is learning the commands you need without spending too much time learning commands that you don't.
When Emacs starts it reads an initialization file, .emacs, from the user's home directory. This file is used to turn on certain features, load optional packages, set preferred keybindings, etc.. A .emacs file is provided for those working with me.
Students will have to work on large programs spanning many files. A very common frustration is not knowing what a function does or where it is used. The same holds for variables, structures, and other program elements. Several commands can be used to quickly find these, including occur, p-smart-grep, and hi-lock.
You are using Emacs to edit a C program and would like to see all places that variable "decode_pos" is used in that file:
A debugger is a program for finding bugs. Learning a few basic debugger commands might take about 20 minutes; this is too long for most people because (1) they will find the bug in five minutes and (2) that will be the last bug they encounter. If you are one of the rare exceptions, read on.
The procedures here are for running gdb, the GNU debugger, under Emacs. It is also possible, though less convenient, to run gdb from a command line.
To learn gdb follow the steps below.
Arg 0 = "buggy" Arg 1 = "first" Arg 2 = "second"
#include <stdio.h> int main(int argv, char **argc) { int i; for(i=0; i<=argv; i++) printf("Arg %2d = \"%s\"\n",i,argc[i]); return 0; }
[drop] % gcc buggy.c -o buggy -g
Current directory is /home/faculty/koppel/students/web/ GNU gdb 6.1 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc-sun-solaris2.8"... (gdb)
(gdb) run one two Starting program: /home/faculty/koppel/students/web/buggy Arg 0 = "/home/faculty/koppel/students/web/buggy" Arg 1 = "one" Arg 2 = "two" Program received signal SIGSEGV, Segmentation fault. 0xff2b3218 in strlen () from /usr/lib/libc.so.1 (gdb)
(gdb) where #0 0xff2b3218 in strlen () from /usr/lib/libc.so.1 #1 0xff306520 in _doprnt () from /usr/lib/libc.so.1 #2 0xff30815c in printf () from /usr/lib/libc.so.1 #3 0x000106d8 in main (argv=1, argc=0xffbeecb4) at buggy.c:8 (gdb)
(gdb) frame 3 #3 0x000106d8 in main (argv=1, argc=0xffbeecb4) at buggy.c:6 (gdb)
Think: Hmmm, there can't be a bug in strlen because that's a widely used and very simple library function and so most problems would be discovered and fixed by now. The printf function is more complicated, maybe that had the bug. But I'm not doing something very fancy with it and printf is widely used so any bug with a simple format string would probably have been fixed by now too. Maybe it's something about the arguments that are being passed. The format string must be okay because it worked in the first iteration, so it's something about i or argc[i]. It's probably not i because printf should be able to print any integer. Okay, let's have a look at what i and argc[i] are.
Print the values of i, argc[i], and argc[2] using the print command as shown below:
(gdb) print i $1 = 3 (gdb) print argc[i] $2 = 0x0 (gdb) print argc[2] $3 = 0xffbeee64 "two" (gdb)
for(i=0; i<argv; i++)
[drop] % gcc buggy.c -o buggy -g
(gdb) run one two The program being debugged has been started already. Start it from the beginning? (y or n) y `/home/faculty/koppel/students/web/buggy' has changed; re-reading symbols. Starting program: /home/faculty/koppel/students/web/buggy one two Arg 0 = "/home/faculty/koppel/students/web/buggy" Arg 1 = "one" Arg 2 = "two" Program exited normally. (gdb)
Further information can be found at the cvs Web site.
[drop] %/home/smith/myprojects [drop] %cd ~/myprojects/cvs checkout: Updating see U see/README cvs checkout: Updating see/doc ... U see/src/shade-spix/reguse.h U see/src/shade-spix/reguse2.h U see/src/shade-spix/spixtypes.h [drop] %cvs co see
Shade is a package for analyzing the dynamic instruction stream of SPARC (Sun) programs running on Solaris. Analysis can be simple, such as counting the number of load instructions executed, of moderate complexity, such as evaluating the prediction accuracy of a branch predictor, or complex, such as determining the performance of a particular pipelined implementation.
Shade comes with several analyzers, programs for analyzing instruction streams, and users can write their own. See the Shade User's Manual for documentation on analyzers that come with Shade.
For a typical homework assignment one will have to modify an existing analyzer, or perhaps write a new one. A set of files will be provided for each homework assignment, including analyzer source code and a makefile.echo pwd | icount
Analyzer: icount Version: Shade and Spixtools V5.33A, V9 SPARC Solaris Uname: drop sun4u SunOS 5.8 Generic_108528-24 Start: Mon Nov 10 16:17:03 2003 Application: /bin/pwd /home/faculty/koppel/teach/tca03/shade/hw3 Application Instructions: 557466 Stop: Mon Nov 10 16:17:04 2003 Instructions: 557466 Time: 0.060 usr 0.010 sys 0.140 real 49.978% Speed: 7963.800 KIPS
icount pwd
sum
Hello.0.000000 Sum in: 45 0.000000Here is the traced output of sum. The output of sum comes first, followed by the trace output. (Other times the trace and the traced program output will be mixed.)
echo sum | rtrace
Hello.0.000000 Sum in: 45 0.000000 _start+0 : Insn Num Insn PC Assembler ! Register and Other Values 1 0x00010078 or %g0,0,%fp ! 0x0,0,0x0 2 0x0001007c lduw [%sp+64],%l0 ! [0xffffcbc0+64],0x1 3 0x00010080 add %sp,68,%l1 ! 0xffffcbc0,68,0xffffcc04 4 0x00010084 sub %sp,32,%sp ! 0xffffcbc0,32,0xffffcba0 5 0x00010088 orcc %g0,%g1,%g0 ! 0x0,0x0,0x0 6 0x0001008c be 0x1009c (_start+9 ) ! 7 0x00010090 or %g0,%g1,%o0 ! 0x0,0x0,0x0 _start+9 : 8 0x0001009c sethi %hi(0x32800),%o0 ! %hi(0x32800),0x32800 9 0x000100a0 or %o0,904,%o0 ! 0x32800,904,0x32b88 10 0x000100a4 call 0x102e8 (atexit+0 ) ! Executed 3241 instructions.
echo sum | rtrace 1000 20
Hello.0.000000 Sum in: 45 0.000000 _doprnt+1283 : Insn Num Insn PC Assembler ! Register and Other Values 1000 0x00011bb0 add %i4,1,%i4 ! 0x0,1,0x1 1001 0x00011bb4 add %i3,1,%i3 ! 0xffffc370,1,0xffffc371 1002 0x00011bb8 ba 0x11bcc (_doprnt+1290 ) ! 1003 0x00011bbc lduw [%sp+152],%o1 ! [0xffffbd08+152],0x30 _doprnt+1290 : 1004 0x00011bcc lduw [%sp+92],%o0 ! [0xffffbd08+92],0xffffc592 1005 0x00011bd0 stb %o1,[%o0] ! 0x30,[0xffffc592] 1006 0x00011bd4 add %o0,1,%o0 ! 0xffffc592,1,0xffffc593 1007 0x00011bd8 lduw [%sp+184],%g1 ! [0xffffbd08+184],0x5 1008 0x00011bdc stw %o0,[%sp+92] ! 0xffffc593,[0xffffbd08+92] 1009 0x00011be0 subcc %g1,1,%o0 ! 0x5,1,0x4 1010 0x00011be4 stw %o0,[%sp+184] ! 0x4,[0xffffbd08+184] 1011 0x00011be8 bpos,a 0x11b80 (_doprnt+1271 ) ! 1012 0x00011bec lduw [%fp-1228],%o0 ! [0xffffca40-1228],0x1 _doprnt+1271 : 1013 0x00011b80 add %o0,1,%o0 ! 0x1,1,0x2 1014 0x00011b84 subcc %o0,0,%g0 ! 0x2,0,0x0 1015 0x00011b88 ble 0x11bc0 (_doprnt+1287 ) ! _doprnt+1274 : 1016 0x00011b8c stw %o0,[%fp-1228] ! 0x2,[0xffffca40-1228] 1017 0x00011b90 ldsb [%i3],%o0 ! [0xffffc371],0x30 1018 0x00011b94 subcc %o0,0,%g0 ! 0x30,0,0x0 1019 0x00011b98 be,a 0x11bc4 (_doprnt+1288 ) ! Executed 1019 instructions.
echo sum | rtrace 20 main
Hello.0.000000 Sum in: 45 0.000000 main+0 : Insn Num Insn PC Assembler ! Register and Other Values 94 0x0001020c save %sp,-128,%sp ! 0xffffcba0,-128,0xffffcb20 95 0x00010210 stw %i0,[%fp+68] ! 0x1,[0xffffcba0+68] 96 0x00010214 stw %i1,[%fp+72] ! 0xffffcc04,[0xffffcba0+72] 97 0x00010218 stw %g0,[%fp-24] ! 0x0,[0xffffcba0-24] 98 0x0001021c sethi %hi(0x4ac00),%o1 ! %hi(0x4ac00),0x4ac00 99 0x00010220 or %o1,904,%o0 ! 0x4ac00,904,0x4af88 100 0x00010224 sethi %hi(0x2400),%o2 ! %hi(0x2400),0x2400 101 0x00010228 or %o2,784,%o1 ! 0x2400,784,0x2710 102 0x0001022c stw %o1,[%o0] (traceamt) ! 0x2710,[0x4af88+0x0] 103 0x00010230 stw %g0,[%fp-20] ! 0x0,[0xffffcba0-20] 104 0x00010234 lduw [%fp-20],%o0 ! [0xffffcba0-20],0x0 105 0x00010238 subcc %o0,9,%g0 ! 0x0,9,0x0 106 0x0001023c ble 0x1024c (main+16 ) ! 107 0x00010240 nop ! main+16 : 108 0x0001024c lduw [%fp-24],%o0 ! [0xffffcba0-24],0x0 109 0x00010250 lduw [%fp-20],%o1 ! [0xffffcba0-20],0x0 main+18 : 110 0x00010254 add %o0,%o1,%o0 ! 0x0,0x0,0x0 111 0x00010258 stw %o0,[%fp-24] ! 0x0,[0xffffcba0-24] 112 0x0001025c lduw [%fp-20],%o0 ! [0xffffcba0-20],0x0 113 0x00010260 add %o0,1,%o1 ! 0x0,1,0x1 Executed 3241 instructions.
traceamt
in
sum is assigned or referenced, with a limit of 20 instructions:
echo sum | rtrace traceamt 5 20
Hello.0.000000 Sum in: 45 0.000000 main+8 : Insn Num Insn PC Assembler ! Register and Other Values 102 0x0001022c stw %o1,[%o0] (traceamt) ! 0x2710,[0x4af88+0x0] 103 0x00010230 stw %g0,[%fp-20] ! 0x0,[0xffffcba0-20] 104 0x00010234 lduw [%fp-20],%o0 ! [0xffffcba0-20],0x0 105 0x00010238 subcc %o0,9,%g0 ! 0x0,9,0x0 106 0x0001023c ble 0x1024c (main+16 ) ! main+27 : 242 0x00010278 stw %g0,[%o0] (traceamt) ! 0x0,[0x4af88+0x0] 243 0x0001027c ldf [%fp+68], f2 ! [0xffffcba0+68], 244 0x00010280 fitod f2, f4 ! , 245 0x00010284 stdf f4,[%fp-16] ! ,[0xffffcba0-16] 246 0x00010288 ldd [%fp-16],%o2 ! [0xffffcba0-16],0x0 Executed 3241 instructions.
subcc
with a non-zero destination register. Or maybe
you've figured out a solution to the homework assignment. Either
way you need to write and run an analyzer, follow the steps below.
make
gcc -I/data4/koppel/shadekit/shade.v9.elf/src/include -I/data4/koppel/shadekit/shade.v9.elf/spixtools/src/include -g -c pred.c gcc -dn -Wl,-M,/data4/koppel/shadekit/shade.v9.elf/lib/mapfile -o pred pred.o /data4/koppel/shadekit/shade.v9.elf/lib/libshade.a /data4/koppel/shadekit/shade.v9.elf/spixtools/lib/libspix.a
David M. Koppelman - koppel@ece.lsu.edu | Modified 15 Jun 2004 12:07 (1707 UTC) |