Programmation avancéeXavier Redon |
#include <stdio.h> #define MAX 10 #define RESULTAT 0 #define ecrire_entier(e) printf("%d\n",e) int main(void){ int i; i=0; for(i=1;i<=MAX;i++) ecrire_entier(i); return RESULTAT; }
$ gcc -E prog.c -o prog-cpp.c $ cat prog-cpp.c # 1 "prog.c" ... # 319 "/usr/include/stdio.h" ... extern int printf (const char *__restrict __format, ...); ... # 2 "prog.c" 2 int main(void){ int i; i=0; for(i=1;i<=10;i++) printf("%d\n",i); return 0; }
$ gcc -Wall --dump-tree-original-raw prog.c $ ./ast2dot.rb prog.c.003t.original > prog-original.dot $ dot -Tpng prog-original.dot > prog-original.png
TranslationUnitDecl 0x9bcb300 <<invalid sloc>> <invalid sloc> |-TypedefDecl 0x9bcb5d0 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'char *' |-FunctionDecl 0x9bcb6c0 <prog.c:1:12> col:12 implicit referenced printf 'int (const char *, ...)' extern | |-ParmVarDecl 0x9bcb720 <<invalid sloc>> <invalid sloc> 'const char *' | `-FormatAttr 0x9bcb760 <col:12> Implicit printf 1 2 |-FunctionDecl 0x9bcb7a0 prev 0x9bcb6c0 <col:1, col:56> col:12 used printf 'int (const char *, ...)' extern | |-ParmVarDecl 0x9bcb630 <col:20, col:43> col:43 __format 'const char *restrict' | `-FormatAttr 0x9bcb820 <col:12> Inherited printf 1 2 `-FunctionDecl 0x9bcb8c0 <line:5:1, line:10:1> line:5:5 main 'int (void)' `-CompoundStmt 0x9bcbbf0 <col:15, line:10:1> |-DeclStmt 0x9bcb980 <line:6:1, col:6> | `-VarDecl 0x9bcb950 <col:1, col:5> col:5 used i 'int' |-BinaryOperator 0x9bcb9c0 <line:7:1, col:3> 'int' '=' | |-DeclRefExpr 0x9bcb990 <col:1> 'int' lvalue Var 0x9bcb950 'i' 'int' | `-IntegerLiteral 0x9bcb9a8 <col:3> 'int' 0 |-ForStmt 0x9bcbba0 <line:8:1, line:4:41> | |-BinaryOperator 0x9bcba08 <line:8:5, col:7> 'int' '=' | | |-DeclRefExpr 0x9bcb9d8 <col:5> 'int' lvalue Var 0x9bcb950 'i' 'int' | | `-IntegerLiteral 0x9bcb9f0 <col:7> 'int' 1 | |-<<<NULL>>> | |-BinaryOperator 0x9bcba60 <col:9, line:2:13> 'int' '<=' | | |-ImplicitCastExpr 0x9bcba50 <line:8:9> 'int' <LValueToRValue> | | | `-DeclRefExpr 0x9bcba20 <col:9> 'int' lvalue Var 0x9bcb950 'i' 'int' | | `-IntegerLiteral 0x9bcba38 <line:2:13> 'int' 10 | |-UnaryOperator 0x9bcba90 <line:8:16, col:17> 'int' postfix '++' | | `-DeclRefExpr 0x9bcba78 <col:16> 'int' lvalue Var 0x9bcb950 'i' 'int' | `-CallExpr 0x9bcbb48 <line:4:26, col:41> 'int' | |-ImplicitCastExpr 0x9bcbb38 <col:26> 'int (*)(const char *, ...)' <FunctionToPointerDecay> | | `-DeclRefExpr 0x9bcbaa4 <col:26> 'int (const char *, ...)' Function 0x9bcb7a0 'printf' 'int (const char *, ...)' | |-ImplicitCastExpr 0x9bcbb80 <col:33> 'const char *' <BitCast> | | `-ImplicitCastExpr 0x9bcbb70 <col:33> 'char *' <ArrayToPointerDecay> | | `-StringLiteral 0x9bcbae0 <col:33> 'char [4]' lvalue "%d\n" | `-ImplicitCastExpr 0x9bcbb90 <line:8:35> 'int' <LValueToRValue> | `-DeclRefExpr 0x9bcbb04 <col:35> 'int' lvalue Var 0x9bcb950 'i' 'int' `-ReturnStmt 0x9bcbbe0 <line:9:1, line:3:18> `-IntegerLiteral 0x9bcbbc8 <col:18> 'int' 0
(note 1 0 3 NOTE_INSN_DELETED) (note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK) (note 2 3 4 2 NOTE_INSN_FUNCTION_BEG) (note 4 2 5 3 [bb 3] NOTE_INSN_BASIC_BLOCK) (insn 5 4 6 3 (set (mem/c/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [0 i+0 S4 A32]) (const_int 0 [0])) prog-cpp.c:4 -1 (nil)) (insn 6 5 7 3 (set (mem/c/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [0 i+0 S4 A32]) (const_int 1 [0x1])) prog-cpp.c:5 -1 (nil)) (jump_insn 7 6 8 3 (set (pc) (label_ref 16)) prog-cpp.c:5 -1 (nil) -> 16) (barrier 8 7 18) (code_label 18 8 9 4 3 "" [1 uses]) (note 9 18 10 4 [bb 4] NOTE_INSN_BASIC_BLOCK) (insn 10 9 11 4 (set (reg/f:SI 59 [ D.1236 ]) (symbol_ref/f:SI ("*.LC0") [flags 0x2] <var_decl 0xb726bba0 *.LC0>)) prog-cpp.c:5 -1 (nil)) (insn 11 10 12 4 (set (reg:SI 62) (mem/c/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [0 i+0 S4 A32])) prog-cpp.c:5 -1 (nil)) (insn 12 11 13 4 (set (mem:SI (plus:SI (reg/f:SI 56 virtual-outgoing-args) (const_int 4 [0x4])) [0 S4 A32]) (reg:SI 62)) prog-cpp.c:5 -1 (nil)) (insn 13 12 14 4 (set (mem:SI (reg/f:SI 56 virtual-outgoing-args) [0 S4 A32]) (reg/f:SI 59 [ D.1236 ])) prog-cpp.c:5 -1 (nil)) (call_insn 14 13 15 4 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:SI ("printf") [flags 0x41] <function_decl 0xb7242f00 printf>) [0 S1 A8]) (const_int 8 [0x8]))) prog-cpp.c:5 -1 (nil) (nil)) (insn 15 14 16 4 (parallel [ (set (mem/c/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [0 i+0 S4 A32]) (plus:SI (mem/c/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [0 i+0 S4 A32]) (const_int 1 [0x1]))) (clobber (reg:CC 17 flags)) ]) prog-cpp.c:5 -1 (nil)) (code_label 16 15 17 5 2 "" [1 uses]) (note 17 16 19 5 [bb 5] NOTE_INSN_BASIC_BLOCK) (insn 19 17 20 5 (set (reg:CCGC 17 flags) (compare:CCGC (mem/c/i:SI (plus:SI (reg/f:SI 54 virtual-stack-vars) (const_int -4 [0xfffffffffffffffc])) [0 i+0 S4 A32]) (const_int 10 [0xa]))) prog-cpp.c:5 -1 (nil)) (jump_insn 20 19 21 5 (set (pc) (if_then_else (le (reg:CCGC 17 flags) (const_int 0 [0])) (label_ref 18) (pc))) prog-cpp.c:5 -1 (nil) -> 18) (note 21 20 22 6 [bb 6] NOTE_INSN_BASIC_BLOCK) (insn 22 21 23 6 (set (reg:SI 60 [ D.1237 ]) (const_int 0 [0])) prog-cpp.c:6 -1 (nil)) (insn 23 22 24 6 (set (reg:SI 61 [ <retval> ]) (reg:SI 60 [ D.1237 ])) prog-cpp.c:6 -1 (nil)) (jump_insn 24 23 25 6 (set (pc) (label_ref 26)) prog-cpp.c:6 -1 (nil) -> 26) (barrier 25 24 31) (note 31 25 28 7 [bb 7] NOTE_INSN_BASIC_BLOCK) (insn 28 31 29 7 (clobber (reg/i:SI 0 ax)) prog-cpp.c:7 -1 (nil)) (insn 29 28 26 7 (clobber (reg:SI 61 [ <retval> ])) prog-cpp.c:7 -1 (nil)) (code_label 26 29 32 8 1 "" [1 uses]) (note 32 26 27 8 [bb 8] NOTE_INSN_BASIC_BLOCK) (insn 27 32 30 8 (set (reg/i:SI 0 ax) (reg:SI 61 [ <retval> ])) prog-cpp.c:7 -1 (nil)) (insn 30 27 0 8 (use (reg/i:SI 0 ax)) prog-cpp.c:7 -1 (nil))
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 define i32 @main() #0 { %1 = alloca i32, align 4 %i = alloca i32, align 4 store i32 0, i32* %1 store i32 0, i32* %i, align 4 store i32 1, i32* %i, align 4 br label %2 ; <label>:2 %3 = load i32* %i, align 4 %4 = icmp sle i32 %3, 10 br i1 %4, label %5, label %11 ; <label>:5 %6 = load i32* %i, align 4 %7 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %6) br label %8 ; <label>:8 %9 = load i32* %i, align 4 %10 = add nsw i32 %9, 1 store i32 %10, i32* %i, align 4 br label %2 ; <label>:11 ret i32 0 }
schéma d’appel Linux 32 bits | schéma d’appel Linux 64 bits, paramètres entiers | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
version 32 bits | version 64 bits | |
$ gcc -Wall -fno-asynchronous-unwind-tables -S prog.c -o prog.s $ cat prog.s .file "prog.c" .section .rodata .LC0: .string "%d\n" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp # $-16 -> $0xfffffff0 subl $32, %esp movl $0, 28(%esp) movl $1, 28(%esp) jmp .L2 .L3: movl $.LC0, %eax movl 28(%esp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf addl $1, 28(%esp) .L2: cmpl $10, 28(%esp) jle .L3 movl $0, %eax leave ret | $ gcc -Wall -fno-asynchronous-unwind-tables -S prog.c -o prog.s64 $ cat prog.s64 .file "prog.c" .section .rodata .LC0: .string "%d\n" .text .globl main .type main, @function main: pushq %rbp movq %rsp, %rbp subq $16, %rsp movl $0, -4(%rbp) movl $1, -4(%rbp) jmp .L2 .L3: movl -4(%rbp), %eax movl %eax, %esi movl $.LC0, %edi movl $0, %eax call printf addl $1, -4(%rbp) .L2: cmpl $10, -4(%rbp) jle .L3 movl $0, %eax leave ret |
version 32 bits | version 64 bits | |
.file "prog2.c" .section .rodata .LC0: .string "%d\n" .text .globl ecrire_entier .type ecrire_entier, @function ecrire_entier: pushl %ebp movl %esp, %ebp subl $40, %esp movl $.LC0, %eax movl 8(%ebp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf movl %eax, -12(%ebp) movl -12(%ebp), %eax leave ret .globl main .type main, @function main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp movl $0, 28(%esp) movl $1, 28(%esp) jmp .L3 .L4: movl 28(%esp), %eax movl %eax, (%esp) call ecrire_entier addl $1, 28(%esp) .L3: cmpl $10, 28(%esp) jle .L4 movl $0, %eax leave ret | .file "prog2.c" .section .rodata .LC0: .string "%d\n" .text .globl ecrire_entier .type ecrire_entier, @function ecrire_entier: pushq %rbp movq %rsp, %rbp subq $32, %rsp movl %edi, -20(%rbp) movl -20(%rbp), %eax movl %eax, %esi movl $.LC0, %edi movl $0, %eax call printf movl %eax, -4(%rbp) movl -4(%rbp), %eax leave ret .size ecrire_entier, .-ecrire_entier .globl main .type main, @function main: pushq %rbp movq %rsp, %rbp subq $16, %rsp movl $0, -4(%rbp) movl $1, -4(%rbp) jmp .L4 .L5: movl -4(%rbp), %eax movl %eax, %edi movl $0, %eax call ecrire_entier addl $1, -4(%rbp) .L4: cmpl $10, -4(%rbp) jle .L5 movl $0, %eax leave ret |
#include <stdio.h> void addition(int a,int b){ int c=a+b; printf("a+b=%d\n",c); } int main(void){ addition(1,1); return 0; }
#include <stdio.h> unsigned int multiplier(unsigned int a,unsigned int b){ unsigned int resultat; if(a==0) resultat=0; else if(a==1) resultat=b; else resultat=b+multiplier(a-1,b); return resultat; } int main(void){ unsigned int nombre; unsigned int a=10,b=20; nombre=multiplier(a,b); printf("resultat=%u\n",nombre); return 0; }
.section .rodata # ... .text .globl multiplier .type multiplier, @function multiplier: # ... .globl main .type main, @function main: # ...
typedef struct { unsigned char e_ident[EI_NIDENT]; uint16_t e_type; uint16_t e_machine; uint32_t e_version; ElfN_Addr e_entry; ElfN_Off e_phoff; ElfN_Off e_shoff; uint32_t e_flags; uint16_t e_ehsize; uint16_t e_phentsize; uint16_t e_phnum; uint16_t e_shentsize; uint16_t e_shnum; uint16_t e_shstrndx; } ElfN_Ehdr; typedef struct { typedef struct { uint32_t p_type; uint32_t p_type; Elf32_Off p_offset; uint32_t p_flags; Elf32_Addr p_vaddr; Elf64_Off p_offset; Elf32_Addr p_paddr; Elf64_Addr p_vaddr; uint32_t p_filesz; Elf64_Addr p_paddr; uint32_t p_memsz; uint64_t p_filesz; uint32_t p_flags; uint64_t p_memsz; uint32_t p_align; uint64_t p_align; } Elf32_Phdr; } Elf64_Phdr; typedef struct { typedef struct { uint32_t sh_name; uint32_t sh_name; uint32_t sh_type; uint32_t sh_type; uint32_t sh_flags; uint64_t sh_flags; Elf32_Addr sh_addr; Elf64_Addr sh_addr; Elf32_Off sh_offset; Elf64_Off sh_offset; uint32_t sh_size; uint64_t sh_size; uint32_t sh_link; uint32_t sh_link; uint32_t sh_info; uint32_t sh_info; uint32_t sh_addralign; uint64_t sh_addralign; uint32_t sh_entsize; uint64_t sh_entsize; } Elf32_Shdr; } Elf64_Shdr;
$ gcc -Wall -fno-asynchronous-unwind-tables -c prog2.c $ readelf -h prog2.o ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (Relocatable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x0 Start of program headers: 0 (bytes into file) Start of section headers: 260 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 0 (bytes) Number of program headers: 0 Size of section headers: 40 (bytes) Number of section headers: 11 Section header string table index: 8
$ readelf -S prog2.o Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 00000000 000034 00005c 00 AX 0 0 4 [ 2] .rel.text REL 00000000 000390 000018 08 9 1 4 [ 3] .data PROGBITS 00000000 000090 000000 00 WA 0 0 4 [ 4] .bss NOBITS 00000000 000090 000000 00 WA 0 0 4 [ 5] .rodata PROGBITS 00000000 000090 000004 00 A 0 0 1 [ 6] .comment PROGBITS 00000000 000094 00001e 01 MS 0 0 1 [ 7] .note.GNU-stack PROGBITS 00000000 0000b2 000000 00 0 0 1 [ 8] .shstrtab STRTAB 00000000 0000b2 000051 00 0 0 1 [ 9] .symtab SYMTAB 00000000 0002bc 0000b0 10 10 8 4 [10] .strtab STRTAB 00000000 00036c 000023 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)
$ readelf -s prog2.o Symbol table '.symtab' contains 11 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS prog2.c 2: 00000000 0 SECTION LOCAL DEFAULT 1 3: 00000000 0 SECTION LOCAL DEFAULT 3 4: 00000000 0 SECTION LOCAL DEFAULT 4 5: 00000000 0 SECTION LOCAL DEFAULT 5 6: 00000000 0 SECTION LOCAL DEFAULT 7 7: 00000000 0 SECTION LOCAL DEFAULT 6 8: 00000000 34 FUNC GLOBAL DEFAULT 1 ecrire_entier 9: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf 10: 00000022 58 FUNC GLOBAL DEFAULT 1 main $ readelf -r prog2.o Relocation section '.rel.text' at offset 0x390 contains 3 entries: Offset Info Type Sym.Value Sym. Name 00000007 00000501 R_386_32 00000000 .rodata 00000016 00000902 R_386_PC32 00000000 printf 00000045 00000802 R_386_PC32 00000000 ecrire_entier
$ ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 \ prog2.o /usr/lib/i386-linux-gnu/crt*.o -o prog2 -lc $ readelf -h prog2 ELF Header: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Intel 80386 Version: 0x1 Entry point address: 0x804831c Start of program headers: 52 (bytes into file) Start of section headers: 1524 (bytes into file) Flags: 0x0 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 7 Size of section headers: 40 (bytes) Number of section headers: 24 Section header string table index: 21
$ readelf -l prog2 Elf file type is EXEC (Executable file) Entry point 0x804831c There are 7 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4 INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1 [Requesting program interpreter: /lib/ld-linux.so.2] LOAD 0x000000 0x08048000 0x08048000 0x00410 0x00410 R E 0x1000 LOAD 0x000410 0x08049410 0x08049410 0x000e8 0x000e8 RW 0x1000 DYNAMIC 0x000410 0x08049410 0x08049410 0x000c8 0x000c8 RW 0x4 NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame 03 .dynamic .got .got.plt .data 04 .dynamic 05 .note.ABI-tag 06
#include <stdio.h> int addition(int x,int y){ return x+y; } int main(void){ int a,b,c; printf("Donnez 3 entiers\n"); scanf("%d %d %d",&a,&b,&c); printf("%d\n",addition(a,addition(b,c))); return 0; }
$ gcc -Wall -O2 --dump-tree-einline --dump-tree-optimized \ substitution.c -o substitution
$ cat substitution.c.026t.einline2 main () { int D.1794,D.1793,D.1793,D.1790,D.1789,D.1789,D.1783,D.1782,D.1780; int a,b,c,a.13,b.12,c.11; <bb 2>: __builtin_puts (&"Donnez 3 entiers"[0]); scanf (&"%d %d %d"[0], &a, &b, &c); c.11_1 = c; b.12_2 = b; D.1790_8 = c.11_1 + b.12_2; D.1789_10 = D.1790_8; D.1780_3 = D.1789_10; a.13_4 = a; D.1794_9 = D.1780_3 + a.13_4; D.1793_11 = D.1794_9; D.1782_5 = D.1793_11; printf (&"%d\n"[0], D.1782_5); D.1783_6 = 0; return D.1783_6; } $ cat substitution.c.126t.optimized main () { int a,b,c; <bb 2>: __builtin_puts (&"Donnez 3 entiers"[0]); scanf (&"%d %d %d"[0], &a, &b, &c); printf (&"%d\n"[0], (b + c) + a); return 0; }
#include <stdio.h> #define TAILLE 10 int main(void){ int a[TAILLE]; int resultat=0; int i; for(i=0;i<TAILLE;i++) scanf("%d",&a[i]); for(i=0;i<TAILLE;i++) resultat += a[i]; return resultat; }
$ gcc -Wall -O3 --dump-tree-cunroll --dump-tree-optimized \ deroulement.c -o deroulement
$ cat deroulement.c.126t.optimized main () { int resultat.48; int resultat.46; int resultat.44; int resultat.42; int resultat.40; int resultat.38; int resultat.36; int resultat.34; int a[10]; <bb 2>: scanf (&"%d"[0], &a); scanf (&"%d"[0], &a[1]); scanf (&"%d"[0], &a[2]); scanf (&"%d"[0], &a[3]); scanf (&"%d"[0], &a[4]); scanf (&"%d"[0], &a[5]); scanf (&"%d"[0], &a[6]); scanf (&"%d"[0], &a[7]); scanf (&"%d"[0], &a[8]); scanf (&"%d"[0], &a[9]); resultat.34 = a[0] + a[1]; resultat.36 = resultat.34 + a[2]; resultat.38 = resultat.36 + a[3]; resultat.40 = resultat.38 + a[4]; resultat.42 = resultat.40 + a[5]; resultat.44 = resultat.42 + a[6]; resultat.46 = resultat.44 + a[7]; resultat.48 = resultat.46 + a[8]; return a[9] + resultat.48; }
#include <stdio.h> int puissance(int a,int b){ if(b==0) return 1; else return puissance(a,b-1)*a; } int main(void){ int a,b; scanf("%d %d",&a,&b); printf("%d\n",puissance(a,b)); return 0; }
$ gcc -Wall -O2 --dump-tree-optimized recursion.c -o recursion
$ cat recursion.c.126t.optimized puissance (a, b) { int mult_acc.13; <bb 2>: if (b == 0) goto <bb 6>; else goto <bb 5>; <bb 6>: mult_acc.13 = 1; goto <bb 4>; <bb 5>: mult_acc.13 = 1; <bb 3>: b = b + -1; mult_acc.13 = mult_acc.13 * a; if (b == 0) goto <bb 4>; else goto <bb 3>; <bb 4>: return mult_acc.13; }
$ cat ssa.c int main(void){ int a=0; int b=a; a=1; if(a==1) a++; return a+b; } $ gcc -O -Wall --dump-tree-ssa ssa.c -o ssa $ cat ssa.c.024t.ssa main () { int a,b; int D.1196; <bb 2>: a_2 = 0; b_3 = a_2; a_4 = 1; if (a_4 == 1) goto <bb 3>; else goto <bb 4>; <bb 3>: a_5 = a_4 + 1; <bb 4>: # a_1 = PHI <a_4(2), a_5(3)> D.1196_6 = a_1 + b_3; return D.1196_6; }
$ cat ssa3.c #define TAILLE 1024 int main(void){ int a[TAILLE]; int index=TAILLE/2; int resultat=0; int i; for(i=0;i<TAILLE;i++) a[i]=0; for(i=0;i<TAILLE;i++) if(i==index) a[i]++; for(i=0;i<TAILLE;i++) resultat += a[i]; return resultat; } $ gcc -O3 -Wall --dump-tree-ssa ssa3.c -o ssa3 $ cat ssa3.c.024t.ssa main () { int i; int resultat; int index; int a[1024]; int D.1210,D.1209,D.1208; int i.0; ...
#include <stdio.h> int main(void){ int a=0; printf("Coucou !\n"); a=1; return a; printf("Caché !\n"); }
$ gcc -O -Wall --dump-tree-dce code_mort.c -o code_mort
$ cat code_mort.c.079t.dce4 main () { <bb 2>: __builtin_puts (&"Coucou !"[0]); a = 1; return 1; }
int main(void){ int a=1,b=2,c=3; int d=a*c,e=d+2*b; if(e!=2) e--; return e; }
$ gcc -O -Wall --dump-tree-ccp propagation.c -o propagation
$cat propagation.c.056t.ccp2 main () { <bb 2>: return 6; }
#include <stdio.h> #define TAILLE 10 int main(void){ int a[TAILLE]; int i; int resultat=0; for(i=0;i<TAILLE;i++) a[i]=TAILLE*i; for(i=1;i<TAILLE;i++) resultat += a[i]; return resultat; }
$ gcc -Wall -O --dump-tree-ivopts --dump-tree-optimized \ complexite.c -o complexite
$ cat complexite.c.126t.optimized main () { unsigned int ivtmp.36; unsigned int ivtmp.34; unsigned int ivtmp.25; int resultat; int a[10]; <bb 2>: ivtmp.34 = (unsigned int) &a[0]; ivtmp.36 = 0; <bb 3>: MEM[index: ivtmp.34] = (int) ivtmp.36; ivtmp.34 = ivtmp.34 + 4; ivtmp.36 = ivtmp.36 + 10; if (ivtmp.34 != (unsigned int) (&a + 40)) goto <bb 3>; else goto <bb 4>; <bb 4>: ivtmp.25 = (unsigned int) &a[1]; resultat = 0; <bb 5>: resultat = resultat + MEM[index: ivtmp.25]; ivtmp.25 = ivtmp.25 + 4; if (ivtmp.34 != ivtmp.25) goto <bb 5>; else goto <bb 6>; <bb 6>: return resultat;
origine=0; for(i=0;i<TAILLE;i++) for(j=0;j<TAILLE;j++){ a[i][j]=rand(); b[i][j]=rand(); } for(i=0;i<TAILLE;i++) for(j=0;j<TAILLE;j++) origine += a[i][j]+b[i][j]; for(i=0;i<TAILLE;i++) for(j=0;j<TAILLE;j++) a[i][j]=a[i][j]+b[i][j];
S0=0; { 0<=i<=TAILLE-1, 0<=j<=TAILLE-1 } : S1[i,j] = rand(); { 0<=i<=TAILLE-1, 0<=j<=TAILLE-1 } : S2[i,j] = rand(); { 0<=i<=TAILLE-1, 0<=j<=TAILLE-1 } : S3[i,j] = ( if(i==0 && j==0) S0; else if(j==0) S3[i-1,TAILLE-1]; else S3[i,j-1] ) + S1[i,j] + S2[i,j]; { 0<=i<=TAILLE-1, 0<=j<=TAILLE-1 } : S4[i,j] = S1[i,j] + S2[i,j];
#include <stdio.h> #include <stdlib.h> #define TAILLE 1024 int main(void){ int i,j; static double a[TAILLE][TAILLE]; static double b[TAILLE][TAILLE]; for(i=0;i<TAILLE;i++) for(j=0;j<TAILLE;j++){ a[i][j]=rand(); b[i][j]=rand(); } float origine=0; for(i=0;i<TAILLE;i++) for(j=0;j<TAILLE;j++) origine += a[i][j]+b[i][j]; for(i=0;i<TAILLE;i++) for(j=0;j<TAILLE;j++) a[i][j]=a[i][j]+b[i][j]; float resultat=0; for(i=0;i<TAILLE;i++) for(j=0;j<TAILLE;j++) resultat += a[i][j]; printf("origine=%lf resultat=%lf\n",origine,resultat); return 0; }
gcc -Wall -O3 --dump-tree-all -ftree-parallelize-loops=2 -floop-parallelize-all \ matrices.c -o matrices
$ cat matrices.c.165t.optimized main () { ... .paral_data_store.a = &a; .paral_data_store.b = &b; __builtin_GOMP_parallel_start (main._loopfn.0, &.paral_data_store, 2); main._loopfn.0 (&.paral_data_store); __builtin_GOMP_parallel_end (); ... } main._loopfn.0 (void * .paral_data_param) { // Sommer les lignes de .paral_data_param.a et de .paral_data_param.b // telles que i % __builtin_omp_get_num_threads() == __builtin_omp_get_thread_num() ... }
__asm__ volatile("int $0x80" : : "a" (syscall), "b" (argument1));
__asm__ volatile("syscall" :: "a" (syscall), "D" (argument1) );
struct delai_s { int secondes; int microsecondes; };
#include <dlfcn.h> void *dlopen(const char *filename, int flag); void *dlsym(void *handle, const char *symbol); int dlclose(void *handle);
GET "LIBHDR" GLOBAL $( COUNT: 200 ALL: 201 $) LET TRY(LD, ROW, RD) BE TEST ROW = ALL THEN COUNT := COUNT + 1 ELSE $( LET POSS = ALL & ~(LD | ROW | RD) UNTIL POSS = 0 DO $( LET P = POSS & -POSS POSS := POSS - P TRY(LD + P << 1, ROW + P, RD + P >> 1) $) $) LET START() = VALOF $( ALL := 1 FOR I = 1 TO 12 DO $( COUNT := 0 TRY(0, 0, 0) WRITEF("%I2-QUEENS PROBLEM HAS %I5 SOLUTIONS*N", I, COUNT) ALL := 2 * ALL + 1 $) RESULTIS 0 $)
main( ) { auto c; while (1) { while ( (c=getchar()) != ' ') if (putchar(c) == '*n') exit(); putchar( '*n' ); while ( (c=getchar()) == ' '); /* skip blanks */ if (putchar(c)=='*n') exit(); /* done when newline */ } }
/* Exemple de C classique */ /* Compiler par gcc -traditional -Wall kr.c -o kr */ position(string,c) char *string; char c; { char *p=string; while(*p!=c && *p!='\0') p++; if(*p!='\0') return p-string; else return -1; } main() { char *string="hello, world"; printf("w is at %d\n",position(string,'w')); printf("A is at %d\n",position(string,'A')); }
/* Exemple de C ANSI (c89 ou c90) */ /* Compiler par gcc -ansi -pedantic -Wall ansi.c -o ansi */ #include <stdio.h> #define suffix(name,suffix) name##suffix long double suffix(addition,_lg)(long double,void *,int); int main(void) { long double d=0; long double c=10000000.0L; float f=1.0; d=suffix(addition,_lg)(d,&c,sizeof c); d=suffix(addition,_lg)(d,&f,sizeof f); printf("result=%Lf\n",d); return 0; } long double suffix(addition,_lg)(long double d,void *x,int size) { if(size==sizeof d) d+=*((long double *)x); if(size==sizeof(double)) d+=*((double *)x); if(size==sizeof(float)) d+=*((float *)x); return d; }
// Exemple de c99 // Compiler par gcc -std=c99 -Wall c99.c -o c99 #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <stdbool.h> #define erreur(...) { fprintf(stderr,__VA_ARGS__) ; exit(EXIT_FAILURE); } int32_t premier(uint32_t n){ bool crible[n*n+1]; for(uint32_t i=0;i<=n*n;i++) crible[i]=true; for(uint32_t i=2;i<=n;i++) if(crible[i]){ uint32_t j=i*i; while(j<=n*n){ crible[j]=false; j += i; } } int32_t result=-1; for(int32_t i=n*n;i>=0;i--) if(crible[i]){ result=i; break; } return result; } int main(void){ uint32_t n; if(scanf("%d",&n)!=1) erreur("Echec de lecture du nombre\n"); printf("premier -> %d\n",premier(n)); return 0; }
// Exemple de c11 (ou c1x) // Compiler par gcc -std=c1x -Wall c11.c -o c11 // au 28/02/2014 echec sur _Generic // au 17/03/2017 _Generic fonctionne // Compiler par clang -std=c1x -Wall c11.c -o c11 // au 28/02/2014 echec sur _Noreturn, bug sur _Generic // au 17/03/2017 fonctionne en cherchant beaucoup // Echec de verification des limites avec gcc et clang #include <stdio.h> #include <stdlib.h> #include <stdint.h> typedef union { uint32_t mot; struct { uint8_t octet1; uint8_t octet2; uint8_t octet3; uint8_t octet4; }; uint8_t octet[4]; } tranchoir; #define ecrire(x) \ printf(_Generic(x,char *:"%s",char[sizeof(x)]:"%s",float:"%f",int:"%d",unsigned char:"%02x"),x) _Noreturn void die(char *message){ ecrire(message); exit(EXIT_FAILURE); } int main(void){ uint32_t entier; ecrire("Donnez un entier :\n"); if(scanf("%x",&entier)!=1) die("Echec de lecture !\n"); tranchoir t; t.mot=entier; ecrire("O"); ecrire(1); ecrire("="); ecrire(t.octet1); ecrire("\n"); ecrire("O"); ecrire(2); ecrire("="); ecrire(t.octet2); ecrire("\n"); ecrire("O"); ecrire(3); ecrire("="); ecrire(t.octet3); ecrire("\n"); ecrire("O"); ecrire(4); ecrire("="); ecrire(t.octet4); ecrire("\n"); for(uint8_t i=0;i<=4;i++) { ecrire("O"); ecrire(i); ecrire("="); ecrire(t.octet[i]); ecrire(i==3?"\n":", "); } return 0; }
$ ./c11 Donnez un entier : ca11efa5 O00=a5, O01=ef, O02=11, O03=ca
#include <stdlib.h> main(void){ exit(0); }
$ gcc main.c -o main $ gcc -std=c99 main.c -o main /tmp/main.c:2:1: warning: return type defaults to ‘int’ main(void){ exit(0); }
int main(void){ }
$ gcc -Wall -ansi retour.c -o retour_ansi retour.c: In function ‘main’: retour.c:1:1: warning: control reaches end of non-void function [-Wreturn-type] $ gcc -Wall -std=c99 retour.c -o retour_c99 $ gcc -Wall retour.c -o retour retour.c: In function ‘main’: retour.c:1:1: warning: control reaches end of non-void function [-Wreturn-type] $ ./retour_ansi ; echo $? 212 $ ./retour_c99 ; echo $? 0
int main(void){ printf("Bonjour !\n"); return 0; }
$ clang -Wall implicite.c -o implicite implicite.c:2:1: warning: implicitly declaring C library function 'printf' with type 'int (const char *, ...)' implicite.c:2:1: note: please include the header <stdio.h> or explicitly provide a declaration for 'printf' $ g++ -Wall implicite.c -o implicite implicite.c: In function ‘int main()’: implicite.c:2:35: error: ‘printf’ was not declared in this scope
#include <stdio.h> #include <string.h> #ifdef PROTOTYPE_INCOMPLET int f(); #endif #ifdef PROTOTYPE_COMPLET int f(void); #endif int main(void){ printf("%d\n",f("abc")); return 0; } int f(void){ return 42; }
$ gcc -std=c99 -Wall void.c -o void void.c: In function ‘main’: void.c:10:1: warning: implicit declaration of function ‘f’ [-Wimplicit-function-declaration] $ gcc -Wall -DPROTOTYPE_INCOMPLET void.c -o void $ gcc -Wall -DPROTOTYPE_COMPLET void.c -o void void.c: In function ‘main’: void.c:10:1: error: too many arguments to function
#include <stdio.h> int v1; int f(void){ static int v2; return v2++; } int main(void){ int v3; printf("v1=%d\n",v1); printf("v2=%d\n",f()); printf("encore v2=%d\n",f()); printf("v3=%d\n",v3); return 0; }
$ gcc -Wall init.c -o init init.c: In function ‘main’: init.c:9:7: warning: ‘v3’ is used uninitialized in this function [-Wuninitialized] $ ./init v1=0 v2=0 encore v2=1 v3=-1215623180
#include <stdio.h> int v1; int f(int v2){ return v1+v2; } int main(void){ int v3=v1++,v4=v1; printf("v3=%d v3=%d\n",v3++,v3); printf("v4=%d\n",v4); printf("f=%d\n",f(v1++)); v1=v1++; printf("v1=%d\n",v1); return 0; }
$ gcc -Wall effets.c -o effets effets.c: In function ‘main’: effets.c:6:26: warning: operation on ‘v3’ may be undefined [-Wsequence-point] effets.c:9:3: warning: operation on ‘v1’ may be undefined [-Wsequence-point] $ ./effets v3=0 v3=1 v4=1 f=3 v1=3
#include <stdio.h> typedef struct truc_s { char c1; char c2 ; int e1; long int e2; } truc_t; int main(void){ truc_t t; printf("taille=%d(%d)\n",(int)sizeof t,(int)sizeof(struct truc_s)); return 0; }
tutur01$ arch ; ./tailles i686 taille=12(12) zabeth14$ arch ; ./tailles x86_64 taille=16(16)
// Affiche les arguments d'un programme C // Compiler avec gcc -Wall -g -std=c99 -o arguments arguments.c #include <stdio.h> int main(int argc,char *argv[]){ printf("Nombre d'arguments : %d\n",argc); printf("Chemin de l'exécutable : '%s'\n",argv[0]); for(int i=1;i<argc;i++) printf("Argument n°%d : '%s'\n",i,argv[i]); return 0; }
$ ./arguments un dix "vingt et un" Nombre d'arguments : 4 Chemin de l'exécutable : './arguments' Argument n°1 : 'un' Argument n°2 : 'dix' Argument n°3 : 'vingt et un'
// Affiche les variables d'environnement // Compiler avec gcc -Wall -g -std=c99 -o variables variables.c #include <stdio.h> #include <stdlib.h> #define MAX_NOM 1024 extern char **environ; int main(void){ while(*environ!=NULL){ char nom[MAX_NOM]; if(sscanf(*environ,"%[^=]",nom)==1) printf("Variable %s -> '%s'\n",nom,getenv(nom)); environ++; } return 0; }
// Implante les executables true et false // Compiler avec gcc -Wall -g -o booleen booleen.c // Installer avec ln -s booleen true; ln -s booleen false #include <stdio.h> #include <string.h> int main(int argc,char *argv[]){ char *base=strrchr(argv[0],'/'); if(base==NULL) base=argv[0]; if(strcmp(base,"true")==0) return 0; else return 1; }
$ true ; echo $? 0 $ false ; echo $? 1 $ if true ; then echo VRAI ; else echo FAUX ; fi VRAI $ if false ; then echo VRAI ; else echo FAUX ; fi FAUX
#include <stdlib.h> void *calloc(size_t nmemb, size_t size); void *malloc(size_t size); void free(void *ptr); void *realloc(void *ptr, size_t size);
#include <stdio.h> #include <stdlib.h> int main(void){ int *n=malloc(sizeof(int)); *n=42; return *n; }
$ od -Ax -tx1 /boot/boot.0800 000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 0001c0 01 00 83 fe bf 28 3f 00 00 00 aa 8e 87 00 00 00 0001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa 000200 $
$ od -Ax -tx1 /etc/motd 000000 0a 42 69 65 6e 76 65 6e 75 65 20 73 75 72 20 6c 000010 65 73 20 6d 61 63 68 69 6e 65 73 20 64 65 20 50 000020 6f 6c 79 74 65 63 68 27 4c 69 6c 6c 65 2e 0a 0a 000030 $ od -Ax -tx1 /mnt/Window/win.ini 000000 3b 20 66 6f 72 20 31 36 2d 62 69 74 20 61 70 70 000010 20 73 75 70 70 6f 72 74 0d 0a 5b 66 6f 6e 74 73 000020 5d 0d 0a 5b 65 78 74 65 6e 73 69 6f 6e 73 5d 0d 000030 0a 5b 6d 63 69 20 65 78 74 65 6e 73 69 6f 6e 73 000040 5d 0d 0a 5b 66 69 6c 65 73 5d 0d 0a 5b 4d 61 69 000050 6c 5d 0d 0a 4d 41 50 49 3d 31 0d 0a 00005c
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname,int flags,mode_t mode); int close(int fd);
#include <unistd.h> ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count);
#include <sys/types.h> #include <unistd.h> off_t lseek(int fd, off_t offset, int whence);
#include <sys/ioctl.h> int ioctl(int d, int request, ...);
// Programme de copie de fichiers // Compiler avec : gcc -Wall -g copie.c -o copie #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define MAX_BLOC 2048 int main(int argc,char *argv[]){ if(argc!=3){ fprintf(stderr,"Syntaxe : %s <original> <copie>\n",argv[0]); exit(EXIT_FAILURE); } char *original=argv[1]; char *copie=argv[2]; int dorig=open(original,O_RDONLY); if(dorig<0){ fprintf(stderr,"Impossible d'ouvrir '%s' en lecture !\n",original); exit(EXIT_FAILURE); } int dcopie=open(copie,O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if(dcopie<0){ fprintf(stderr,"Impossible d'ouvrir '%s' en écriture !\n",copie); exit(EXIT_FAILURE); } int taille; unsigned char bloc[MAX_BLOC]; while((taille=read(dorig,bloc,MAX_BLOC))>0) if(write(dcopie,bloc,taille)!=taille){ fprintf(stderr,"Echec d'écriture sur '%s' !\n",copie); exit(EXIT_FAILURE); } close(dorig); close(dcopie); return 0; }
$ stty -F /dev/ttyACM0 9600 cs8 \ -hupcl -icrnl -ixon -opost -onlcr -isig -icanon \ -iexten -echo -echoe -echok -echoctl -echoke ignbrk
#include <stdio.h> FILE *fopen(const char *path, const char *mode); FILE *fdopen(int fd, const char *mode); int fclose(FILE *fp);
#include <stdio.h> int fprintf(FILE *stream, const char *format, ...); int fscanf(FILE *stream, const char *format, ...); char *fgets(char *s, int size, FILE *stream); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
#include <stdio.h> int fseek(FILE *stream, long offset, int whence); long ftell(FILE *stream); void rewind(FILE *stream);
// Programme de conversion de fichiers // Compiler avec : gcc -Wall -g conversion.c -o conversion #include <stdio.h> #include <stdlib.h> #define FORMAT_CHAINE "%%%ds %%f %%%ds %%c %%%d[^\n]" #define FORMAT_NOMBRE 5 #define TAILLE_COMPTE 16 #define TAILLE_DATE 16 #define TAILLE_COMMENTAIRE 64 #define MAX_FORMAT 64 #define MAX_LIGNE 1024 typedef struct { char compte[TAILLE_COMPTE]; float somme; char date[TAILLE_DATE]; char etat; char commentaire[TAILLE_COMMENTAIRE]; } enregistrement; int main(int argc,char *argv[]){ if(argc!=3){ fprintf(stderr,"Syntaxe : %s <fichier texte> <fichier binaire>\n",argv[0]); exit(EXIT_FAILURE); } char *texte=argv[1]; char *binaire=argv[2]; FILE *ftexte=fopen(texte,"r"); if(ftexte==NULL){ fprintf(stderr,"Impossible d'ouvrir '%s' en lecture !\n",texte); exit(EXIT_FAILURE); } FILE *fbinaire=fopen(binaire,"w+"); if(fbinaire==NULL){ fprintf(stderr,"Impossible d'ouvrir '%s' en écriture !\n",binaire); exit(EXIT_FAILURE); } char format[MAX_FORMAT]; sprintf(format,FORMAT_CHAINE,TAILLE_COMPTE-1,TAILLE_DATE-1,TAILLE_COMMENTAIRE-1); char ligne[MAX_LIGNE]; while(fgets(ligne,MAX_LIGNE,ftexte)!=NULL){ enregistrement e; int nombre=sscanf(ligne,format,e.compte,&e.somme,e.date,&e.etat,&e.commentaire); if(nombre!=FORMAT_NOMBRE){ fprintf(stderr,"Mauvais format : %s",ligne); exit(EXIT_FAILURE); } if(fwrite(&e,sizeof e,1,fbinaire)!=1){ fprintf(stderr,"Echec d'écriture sur '%s' !\n",binaire); exit(EXIT_FAILURE); } } fclose(ftexte); fclose(fbinaire); return 0; }
solid name ... facet normal ni nj nk outer loop vertex v1x v1y v1z vertex v2x v2y v2z vertex v3x v3y v3z endloop endfacet ... endsolid name
struct STL_header_s { uint8_t void[80]; uint32_t nb_triangles; } struct STL_triangle_s { float n[3]; float v1[3]; float v2[3]; float v3[3]; uint16_t count; }
~
utilisateur/depot ;
~
/.ssh/id_rsa.pub pour votre dépôt ;
OBJETS = puissance.o multiplier.o BIBLIOTHEQUE = operations.a AR = ar r CFLAGS += -Wall -g
$(BIBLIOTHEQUE): $(OBJETS) $(AR) $(BIBLIOTHEQUE) $(OBJETS) puissance.o: puissance.c $(CC) $(CFLAGS) -c puissance.c multiplier.o: multiplier.c $(CC) $(CFLAGS) -c multiplier.c
$(BIBLIOTHEQUE): $(OBJETS) $(AR) $@ $+
%.o: %.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
SOURCES = $(wildcard *.c) OBJETS = $(SOURCES:.c=.o) BIBLIOTHEQUES = -L ../Localbib -lbib EXECUTABLE = projet CFLAGS += -Wall -I ../Localbib all: $(EXECUTABLE) $(EXECUTABLE): $(OBJETS) $(CC) -o $@ $^ $(BIBLIOTHEQUES) clean: rm -rf $(EXECUTABLE) *.o
SOURCES = $(wildcard *.c) OBJETS = $(SOURCES:.c=.o) BIBLIOTHEQUE = libbib.a AR = ar r CFLAGS += -Wall all: $(BIBLIOTHEQUE) $(BIBLIOTHEQUE): $(OBJETS) $(AR) $@ $^ $(OBJETS): bibliotheque.h clean: rm -rf *.o *.a core
REPERTOIRES = Main Bibliotheque COMPILE = $(REPERTOIRES:%=all-%) DEVERMINE = $(REPERTOIRES:%=debug-%) NETTOYAGE = $(REPERTOIRES:%=clean-%) export CFLAGS += -Wall all: $(COMPILE) $(COMPILE): $(MAKE) -C $(@:all-%=%) debug: $(DEVERMINE) $(DEVERMINE): CFLAGS += -g -DDEVERMINE $(DEVERMINE): $(MAKE) -C $(@:debug-%=%) clean: $(NETTOYAGE) $(NETTOYAGE): $(MAKE) -C $(@:clean-%=%) clean all-Main: all-Bibliotheque debug-Main: debug-Bibliotheque .PHONY: $(COMPILE) $(DEVERMINE) $(NETTOYAGE) .PHONY: all debug clean
$ gcc -Wall -g segfault.c -o segfault $ gdb ./segfault GNU gdb 6.8-debian ... (gdb) run Starting program: ./segfault Program received signal SIGSEGV, Segmentation fault. 0xb77ee9b7 in memcpy () from /lib/libc.so.6 (gdb) backtrace #0 0xb77ee9b7 in memcpy () from /lib/libc.so.6 #1 0x08048400 in main () at segfault.c:6 (gdb) list 1 #include <stdio.h> 2 #include <string.h> 3 4 int main(void){ 5 char *chaine; 6 strcpy(chaine,"Bouuuuuuuum !!!!!!!"); 7 printf("%s\n",chaine); 8 return 0; 9 } (gdb) break 6 Breakpoint 1 at 0x80483e5: file segfault.c, line 6. (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: ./segfault Breakpoint 1, main () at segfault.c:6 6 strcpy(chaine,"Bouuuuuuuum !!!!!!!"); (gdb) (gdb) print/x chaine $4 = 0xb7717775 (gdb) quit The program is running. Exit anyway? (y or n) y
$ gcc -Wall -g boucle.c -o boucle $ gdb ./boucle GNU gdb 6.8-debian ... (gdb) break main Breakpoint 1 at 0x80483c2: file boucle.c, line 9. (gdb) run Starting program: ./boucle Breakpoint 1, main () at boucle.c:9 9 for(i=0;i<10;i++) tab[i]=carre(i); (gdb) watch i Hardware watchpoint 3: i (gdb) continue Continuing. Hardware watchpoint 4: i Old value = 134513753 New value = 0 0x080483e1 in main () at boucle.c:9 9 for(i=0;i<10;i++) tab[i]=carre(i); (gdb) c Continuing. Hardware watchpoint 4: i Old value = 0 New value = 1 0x080483e1 in main () at boucle.c:9 9 for(i=0;i<10;i++) tab[i]=carre(i); (gdb) next Hardware watchpoint 4: i Old value = 2 New value = 3 0x080483e1 in main () at boucle.c:9 9 for(i=0;i<10;i++) tab[i]=carre(i); (gdb) step carre (n=4) at boucle.c:4 4 int carre(int n){ return n*n; } (gdb) print n $3 = 3 (gdb) c Continuing. Hardware watchpoint 4: i Old value = 3 New value = 4 0x080483e1 in main () at boucle.c:9 9 for(i=0;i<10;i++) tab[i]=carre(i); (gdb) print i $4 = 4 (gdb) quit The program is running. Exit anyway? (y or n) y
rex@monet:/tmp/Debug$ valgrind ./segfault ==8756== Memcheck, a memory error detector ==8756== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==8756== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==8756== Command: ./segfault ==8756== ==8756== Use of uninitialised value of size 4 ==8756== at 0x804840A: main (segfault.c:6) ...
$ cat -b debordement.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #define MAX_ALLOC 10 4 int main(void){ 5 char *tab=malloc(MAX_ALLOC*sizeof(char)); 6 int i; 7 for(i=1;i<=MAX_ALLOC;i++) tab[i]=i; 8 for(i=1;i<=MAX_ALLOC;i++) printf("%d\n",tab[i]); 9 return 0; 10 } $ valgrind ./debordement ==5345== Memcheck, a memory error detector ... ==5345== Invalid write of size 1 ==5345== at 0x804847D: main (debordement.c:7) ==5345== Address 0x41a8032 is 0 bytes after a block of size 10 alloc'd ==5345== at 0x4028308: malloc (vg_replace_malloc.c:263) ==5345== by 0x8048460: main (debordement.c:5) ...
$ cat -b allocfree.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #define NB_CHAINES 10 4 #define MAX_CHAINE 1024 5 int main(void){ 6 char **tab=malloc(NB_CHAINES*sizeof(char *)); 7 int i; 8 for(i=0;i<NB_CHAINES;i++){ 9 tab[i]=malloc(MAX_CHAINE*sizeof(char)); 10 sprintf(tab[i],"%d",i); 11 } 12 for(i=0;i<NB_CHAINES;i++) 13 printf("%s\n",tab[i]); 14 return 0; $ valgrind --leak-check=full ./allocfree ==5405== Memcheck, a memory error detector ... ==5405== HEAP SUMMARY: ==5405== in use at exit: 10,280 bytes in 11 blocks ==5405== total heap usage: 11 allocs, 0 frees, 10,280 bytes allocated ==5405== ==5405== 10,280 (40 direct, 10,240 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2 ==5405== at 0x4028308: malloc (vg_replace_malloc.c:263) ==5405== by 0x8048491: main (allocfree.c:6) ==5405== ==5405== LEAK SUMMARY: ==5405== definitely lost: 40 bytes in 1 blocks ==5405== indirectly lost: 10,240 bytes in 10 blocks ==5405== possibly lost: 0 bytes in 0 blocks ==5405== still reachable: 0 bytes in 0 blocks ==5405== suppressed: 0 bytes in 0 blocks ...
$ cat -b doublefree.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 int main(void){ 4 int *x=malloc(sizeof(int)); 5 int *y=x; 6 *x=3; 7 printf("x=%d y=%d\n",*x,*y); 8 free(x); 9 free(y); 10 return 0; 11 } $ valgrind ./doublefree ==3889== Memcheck, a memory error detector ... ==3889== Invalid free() / delete / delete[] / realloc() ==3889== at 0x402750C: free (vg_replace_malloc.c:427) ==3889== by 0x80484DE: main (doublefree.c:9) ==3889== Address 0x41a8028 is 0 bytes inside a block of size 4 free'd ==3889== at 0x402750C: free (vg_replace_malloc.c:427) ==3889== by 0x80484D2: main (doublefree.c:8) ...
$ cat -b bornes.c 1 #include <stdio.h> 2 int main(void){ 3 char tab[10]; 4 int i; 5 for(i=1;i<=10;i++) tab[i]=i; 6 for(i=1;i<=10;i++) printf("%d\n",tab[i]); 7 return 0; 8 } $ valgrind ./bornes ==5277== Memcheck, a memory error detector ... ==5277== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6)
$ strace ./embryon > /dev/null execve("./embryon", ["./embryon"], [/* 29 vars */]) = 0 write(1, "Bonjour !\n\0", 11) = 11 _exit(0)
$ strace -f bash ... getgid32() = 1000 access("/bin/cat", R_OK) = 0 rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0 pipe([3, 4]) = 0 clone( child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb7594728) = 4724 Process 4724 attached [pid 4723] setpgid(4724, 4724) = 0 [pid 4723] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 4724] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 [pid 4723] rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 ... [pid 4724] execve("/bin/cat", ["cat", "/etc/hosts"], [/* 28 vars */]) = 0 ... [pid 4724] open("/etc/hosts", O_RDONLY|O_LARGEFILE) = 3
# lsof +c15 +D /var/log COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rsyslogd 2332 root 1w REG 8,17 379544 131088 /var/log/syslog rsyslogd 2332 root 2w REG 8,17 144756 132190 /var/log/kern.log rsyslogd 2332 root 5w REG 8,17 98952 132213 /var/log/messages rsyslogd 2332 root 6w REG 8,17 49862 132212 /var/log/debug rsyslogd 2332 root 7w REG 8,17 231211 132189 /var/log/daemon.log rsyslogd 2332 root 8w REG 8,17 256 132200 /var/log/lpr.log rsyslogd 2332 root 9w REG 8,17 21817 132191 /var/log/auth.log rsyslogd 2332 root 10w REG 8,17 388 132195 /var/log/user.log gdm-simple-slav 2629 root 1u REG 8,17 499 131102 /var/log/gdm3/:0-slave.log gdm-simple-slav 2629 root 2u REG 8,17 499 131102 /var/log/gdm3/:0-slave.log Xorg 2660 root 0r REG 8,17 29683 131105 /var/log/Xorg.0.log Xorg 2660 root 2w REG 8,17 20553 131127 /var/log/gdm3/:0.log cupsd 2909 root 4u REG 8,17 641 131538 /var/log/cups/access_log cupsd 2909 root 5u REG 8,17 742 131677 /var/log/cups/error_log cupsd 2909 root 6u REG 8,17 0 131111 /var/log/cups/page_log console-kit-dae 3299 root 8w REG 8,17 11983 131108 /var/log/ConsoleKit/history gdm-session-wor 3556 root 1w REG 8,17 499 131102 /var/log/gdm3/:0-slave.log gdm-session-wor 3556 root 2w REG 8,17 499 131102 /var/log/gdm3/:0-slave.log $ tty /dev/pts/0 $ lsof /dev/pts/0 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME gnome-ter 3705 pifou 17w CHR 136,0 0t0 3 /dev/pts/0 bash 3818 pifou 0r CHR 136,0 0t0 3 /dev/pts/0 bash 3818 pifou 1u CHR 136,0 0t0 3 /dev/pts/0 bash 3818 pifou 2u CHR 136,0 0t0 3 /dev/pts/0 bash 3818 pifou 255u CHR 136,0 0t0 3 /dev/pts/0 lsof 4026 pifou 0u CHR 136,0 0t0 3 /dev/pts/0 lsof 4026 pifou 1u CHR 136,0 0t0 3 /dev/pts/0 lsof 4026 pifou 2u CHR 136,0 0t0 3 /dev/pts/0 # lsof /tmp/.X11-unix/X0 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Xorg 2660 root 3u unix 0xf7335940 0t0 6763 /tmp/.X11-unix/X0
$ ./repeter & [1] 4099 Bonjour $ gdb GNU gdb (GDB) 7.4.1-debian Copyright (C) 2012 Free Software Foundation, Inc. ... (gdb) attach 4099 Attaching to process 4099 ... 0xb77cd424 in __kernel_vsyscall () (gdb) list 1 #include <stdio.h> 2 #include <unistd.h> 3 int main(void){ 4 while(1){ sleep(5); printf("Bonjour\n"); } 5 return 0; 6 } (gdb) where #0 0xb77cd424 in __kernel_vsyscall () #1 0xb76f5300 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82 #2 0xb76f5150 in __sleep (seconds=0) at ../sysdeps/unix/sysv/linux/sleep.c:138 #3 0x08048461 in main () at repeter.c:4 (gdb) break 4 Breakpoint 1 at 0x8048455: file repeter.c, line 4. (gdb) c Continuing. Bonjour Breakpoint 1, main () at repeter.c:4 4 while(1){ sleep(5); printf("Bonjour\n"); } (gdb) c Continuing. Bonjour Breakpoint 1, main () at repeter.c:4 4 while(1){ sleep(5); printf("Bonjour\n"); } (gdb) detach Detaching from program: ./repeter, process 4099 (gdb) quit $ pidof repeter 4099 $ lsof -p 4099 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME repeter 4099 pifou cwd DIR 8,17 4096 414993 /home/pifou/Exercices/Debug repeter 4099 pifou rtd DIR 8,17 4096 2 / repeter 4099 pifou txt REG 8,17 5888 399080 /home/pifou/Exercices/Debug/repeter repeter 4099 pifou mem REG 8,17 1437864 524645 /lib/i386-linux-gnu/i686/cmov/libc-2.13.so repeter 4099 pifou mem REG 8,17 117960 525200 /lib/i386-linux-gnu/ld-2.13.so repeter 4099 pifou 0u CHR 136,0 0t0 3 /dev/pts/0 repeter 4099 pifou 1u CHR 136,0 0t0 3 /dev/pts/0 repeter 4099 pifou 2u CHR 136,0 0t0 3 /dev/pts/0 $ strace -p 4099 Process 4099 attached - interrupt to quit restart_syscall(<... resuming interrupted call ...>) = 0 write(1, "Bonjour\n", 8) = 8 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({5, 0}, 0xbfa2bdc4) = 0
struct personne_s { char nom[MAX_NOM]; char prenom[MAX_NOM]; int age; long long noss; };
typedef struct { char nom[MAX_NOM]; char prenom[MAX_NOM]; int age; long long noss; } personne_t;
struct personne_s moi={"REDON","Xavier",45,1681086424242}; personne_t encore=moi;
struct personne_s moi={.noss=1681086424242,.nom="REDON"}; personne_t encore=moi;
struct personne_s moi; bzero(&moi,sizeof moi); strcpy(moi.nom,"REDON"); moi.noss=1681086424242;
struct personne_s *moi=calloc(1,sizeof moi); strcpy(moi->nom,"REDON"); // equivalent strcpy((*moi).nom,"REDON"); moi->noss=1681086424242; // equivalent (*moi).noss=1681086424242;
typedef struct { unsigned char chiffre_dizaine : 4; unsigned char chiffre_unite : 4; } octet_t;
#define CHIFFRE_DIZAINE(octet) (((octet)>>4)&0x0f) #define CHIFFRE_UNITE(octet) ((octet)&0x0f)
struct figure_s { enum { point,cercle,rectangle } type; int x,y; union { struct { int r ; } cercle; struct { int l,h ; } rectangle; } specifique; };
#pragma pack(1) ... #pragma pack()
#include <avr/io.h> // for the input/output register #include <util/delay.h> // for _delay_ms function int main(void){ DDRB |= 0x0f; // pins 8 to 11 as outputs DDRD &= 0x83; // pins 2 to 6 as inputs PORTD |= 0x7c; // pull-up activated on pins 2 to 6 while(1){ if((PIND&0x7c)==0x7c) PORTB=0x00; else PORTB=0x0f; _delay_ms(50); } }
avr-gcc -Wall -mmcu=atmega328p -DF_CPU=16000000 -Os test.c -o test avr-objcopy -j .text -j .data -O ihex test test.hex avrdude -F -v -p atmega328p -c stk500v1 -b 115200 -P /dev/ttyACM0 -U flash:w:test.hex
question www.polytech-lille.fr | nc -u beuvry.escaut.net 53 | reponse
typedef struct { element_t contenu[MAX_ELEMENTS]; int nombre; } liste_t; liste_t liste={{},0};
typedef struct { element_t *contenu; int nombre; int alloue; } liste_t; liste_t liste={NULL,0,0};
typedef struct cellule_s { element_t contenu; struct cellule_s *suivant; } liste_t; liste_t *liste=NULL;
struct fonction_s { float (*x)(float); float (*y)(float); float (*z)(float); float t_min; float t_max; float t_pas; float taille; }
typedef struct cellule_s { element_t contenu; struct cellule_s *suivant; struct cellule_s *precedent; } liste_t; liste_t *liste=NULL;
typedef struct noeud_s { element_t contenu; struct noeud_s *droit; struct noeud_s *gauche; } arbre_t; arbre_t *arbre=NULL;
typedef struct noeud_s { element_t contenu; struct noeud_s **noeuds; } graphe_t; graphe_t *graphe=NULL;
Ce document a été traduit de LATEX par HEVEA