This file is indexed.

/usr/share/doc/HOWTO/fr-html/GCC-HOWTO.html is in doc-linux-fr-html 2013.01-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<meta name="generator" content=
"HTML Tidy for Linux (vers 25 March 2009), see www.w3.org">
<meta name="GENERATOR" content="LinuxDoc-Tools 0.9.69">
<title>GCC HOWTO pour Linux</title>
</head>
<body>
<h1>GCC HOWTO pour Linux</h1>
<h2>par Daniel Barlow
<code>&lt;dan@detached.demon.co.uk&gt;</code></h2>
v1.17, 28 f&eacute;vrier 1996
<hr>
<em>(Adaptation fran&ccedil;aise par Eric Dumas
<code>&lt;dumas@freenix.fr&gt;</code>, 8 Avril 1996). Ce document
pr&eacute;sente la mani&egrave;re de configurer le compilateur GNU
C et les biblioth&egrave;ques de d&eacute;veloppement sous Linux.
Il donne un aper&ccedil;u de la compilation, de l'&eacute;dition de
liens, de l'ex&eacute;cution et du d&eacute;bogage de programmes
sous Linux. Bon nombre de passages de ce document sont
emprunt&eacute;s &agrave; la FAQ GCC r&eacute;dig&eacute;e par
Mitch D'Souza's et au HowTo ELF. Ceci est la premi&egrave;re
version publique (en d&eacute;pit du num&eacute;ro de version : en
fait, &ccedil;a vient de RCS). N'h&eacute;sitez pas &agrave; me
joindre pour toute remarque.</em>
<hr>
<h2><a name="s1">1. Pr&eacute;liminaires</a></h2>
<h2><a name="index.1"></a> <a name="index.0"></a> <a name=
"ss1.1">1.1 ELF et a.out</a></h2>
<p>Le d&eacute;veloppement de Linux est actuellement dans une phase
de transition. En r&eacute;sum&eacute;, il existe deux formats de
binaires que Linux reconna&icirc;t et ex&eacute;cute, et cela
d&eacute;pend de la mani&egrave;re dont votre syst&egrave;me est
configur&eacute; : vous pouvez avoir les deux, l'un ou l'autre. En
lisant ce document, vous pourrez savoir quels binaires votre
syst&egrave;me est capable de g&eacute;rer.</p>
<p><a name="index.2"></a></p>
<p>Comment le savoir ? Utilisez la commande <code>file</code> (par
exemple, <code>file /bin/bash</code>). Pour un programme ELF, cette
commande va vous r&eacute;pondre quelque chose dans lequel se
trouve le mot ELF. Dans le cas d'un programme en a.out, il vous
indiquera quelque chose comme <code>Linux/i386</code>.</p>
<p>Les diff&eacute;rences entre ELF et a.out sont
d&eacute;taill&eacute;es plus tard dans ce document. ELF est le
nouveau format et il est consid&eacute;r&eacute; comme &eacute;tant
meilleur.</p>
<h2><a name="index.3"></a> <a name="ss1.2">1.2 Du c&ocirc;t&eacute;
du copyright</a></h2>
<p>Le copyright et autres informations l&eacute;gales peuvent
&ecirc;tre trouv&eacute;s &agrave; la <em>fin</em> de ce document,
avec les avertissements conventionnels concernant la mani&egrave;re
de poser des questions sur Usenet pour &eacute;viter d'avoir
&agrave; r&eacute;v&eacute;ler votre ignorance du langage C en
annon&ccedil;ant des bogues qui n'en sont pas, etc.</p>
<h2><a name="ss1.3">1.3 Typographie</a></h2>
<p>Si vous lisez ce document au format Postscript, dvi, ou HTML,
vous pouvez voir quelques diff&eacute;rence entre les styles
d'&eacute;criture alors que les gens qui consultent ce document au
format texte pur ne verront aucune diff&eacute;rence. En
particulier, les noms de fichiers, le nom des commandes, les
messages donn&eacute;s par les programmes et les codes sources
seront &eacute;crits avec le style suivant : <code>style
d'&eacute;criture</code>, alors que les noms de variables entre
autres choses seront en <em>italique</em>.</p>
<p>Vous aurez &eacute;galement un index. Avec les formats dvi ou
postscript, les chiffres dans l'index correspondent au
num&eacute;ros de paragraphes. Au format HTML, il s'agit d'une
num&eacute;rotation s&eacute;quentielle pour que vous puissiez
cliquer dessus. Avec le format texte, ce ne sont que des nombres.
Il vous est donc conseill&eacute; de prendre un autre format que le
format texte !</p>
<p>L'interpr&eacute;teur de commande (<em>shell</em>)
utilis&eacute; dans les exemples sera la Bourne shell (plut&ocirc;t
que le C-Shell). Les utilisateurs du C-Shell utiliseront
plut&ocirc;t :</p>
<blockquote>
<pre>
<code>% setenv soif JD
</code>
</pre></blockquote>
l&agrave; o&ugrave; j'ai &eacute;crit
<blockquote>
<pre>
<code>$ soif=JD; export soif
</code>
</pre></blockquote>
<p>Si l'invite (<em>prompt</em> dans la langue de Shakespeare) est
<code>#</code> plut&ocirc;t que <code>$</code>, la commande ne
fonctionnera que si elle est ex&eacute;cut&eacute;e au nom de Root.
Bien sur, je d&eacute;cline toute responsabilit&eacute; de ce qui
peut se produire sur votre syst&egrave;me lors de
l'ex&eacute;cution de ces exemples. Bonne chance
<code>:-)</code></p>
<h2><a name="s2">2. O&ugrave; r&eacute;cup&eacute;rer de la
documentation et les programmes ?</a></h2>
<h2><a name="ss2.1">2.1 Ce document</a></h2>
<p>Ce document fait partie de la s&eacute;rie des HOWTO pour Linux,
et il est donc disponible ainsi que ces coll&egrave;gues dans les
r&eacute;pertoires HowTo pour Linux, comme sur <a href=
"http://sunsite.unc.edu/pub/linux/docs/HOWTO/">http://sunsite.unc.edu/pub/linux/docs/HOWTO/</a>.
La version HTML peut &eacute;galement &ecirc;tre consult&eacute;e
sur <a href=
"http://ftp.linux.org.uk/~barlow/howto/gcc-howto.html">http://ftp.linux.org.uk/~barlow/howto/gcc-howto.html</a>.</p>
<p>Note du traducteur : vous pouvez obtenir tous les HowTos en
langue anglaise et fran&ccedil;aise sur
<code>ftp.ibp.fr:/pub/linux</code>. Les versions fran&ccedil;aises
se trouvent dans le r&eacute;pertoire
<code>/pub/linux/french/HOWTO</code>.</p>
<h2><a name="index.4"></a> <a name="ss2.2">2.2 Autres
documentation</a></h2>
<p>La documentation officielle pour gcc se trouve dans les sources
de la distribution (voir plus bas) sous la forme de fichiers
texinfo et de fichiers <code>.info</code>. Si vous poss&eacute;dez
une connexion rapide, un CD-ROM ou une certaine patience, vous
pouvez d&eacute;sarchiver la documentation et l'installer dans le
r&eacute;pertoire <code>/usr/info</code>. Sinon, vous pouvez
toujours les trouver sur <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a>, mais ce
n'est pas n&eacute;cessairement toujours la derni&egrave;re
version.</p>
<p><a name="index.5"></a></p>
<p>Il existe deux sources de documentation pour la libc. La libc
GNU est fournie avec des fichiers info qui d&eacute;crivent assez
pr&eacute;cis&eacute;ment la libc Linux sauf pour la partie des
entr&eacute;es-sorties. Vous pouvez &eacute;galement trouver sur
<a href="ftp://sunsite.unc.edu/pub/Linux/docs/">sunsite</a> des
documents &eacute;crits pour Linux ainsi que la description de
certaines appels syst&egrave;mes (section 2) et certaines fonctions
de la libc (section 3).</p>
<p>Note du traducteur : un b&eacute;mol concernant cette partie...
La libc Linux n'est pas GNU et tend &agrave; &ecirc;tre
relativement diff&eacute;rente sur certains points.</p>
<h2><a name="index.6"></a> <a name="ss2.3">2.3 GCC</a></h2>
<p>Il existe deux types de r&eacute;ponses</p>
<p>(a) La distribution officielle de GCC pour Linux peut toujours
&ecirc;tre r&eacute;cup&eacute;r&eacute;e sous la forme de binaires
(d&eacute;j&agrave; compil&eacute;e) sur <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/</a>.
Vous pouvez la trouver sur le miroir fran&ccedil;ais <a href=
"ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp://ftp.ibp.fr:/pub/linux/packages/GCC/</a>.
A l'heure o&ugrave; j'&eacute;cris ces lignes, la derni&egrave;re
version est gcc 2.7.2 (<code>gcc-2.7.2.bin.tar.gz</code>).</p>
<p>(b) La derni&egrave;re distribution des sources de GCC de la
<em>Free Software Foundation</em> peut-&ecirc;tre
r&eacute;cup&eacute;r&eacute;e sur <a href=
"ftp://prep.ai.mit.edu/pub/gnu/">prep.ai.mit.edu</a> ou <a href=
"ftp://ftp.ibp.fr/pub/gnu/">ftp.ibp.fr</a>. Ce n'est pas toujours
la m&ecirc;me version que celle pr&eacute;sent&eacute;e ci-dessus.
Les mainteneurs de GCC pour Linux ont rendu la compilation de GCC
plus facile gr&acirc;ce &agrave; l'utilisation du script
<code>configure</code> qui effectue la configuration d'une
mani&egrave;re automatique. Regardez dans <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a> ou
<a href="ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp.ibp.fr</a>
pour r&eacute;cup&eacute;rer d'&eacute;ventuels patches.</p>
<p>Quelle que soit la complexit&eacute; de votre programme, vous
aurez &eacute;galement besoin de la <em>libc</em>.</p>
<h2><a name="index.7"></a> <a name="ss2.4">2.4 Les fichiers
d'en-t&ecirc;te et la biblioth&egrave;que C</a></h2>
<p>Ce que vous allez trouver dans ce paragraphe d&eacute;pend</p>
<ul>
<li>de votre syst&egrave;me (ELF ou a.out) ;</li>
<li>du type de binaire que vous d&eacute;sirez
g&eacute;n&eacute;rer.</li>
</ul>
Si vous &ecirc;tes en train de mettre &agrave; jour votre libc 4 en
libc 5, vous devriez consulter le ELF HowTo qui se trouve au
m&ecirc;me endroit que ce document.
<p>Les libc sont disponibles sur <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a> ou
<a href="ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp.ibp.fr</a>.
Voici une description des fichiers situ&eacute;s dans ce
r&eacute;pertoire :</p>
<dl>
<dt><b><code>libc-5.2.18.bin.tar.gz</code></b></dt>
<dd>
<p>--- biblioth&egrave;ques dynamiques et statiques ELF plus les
fichiers d'en-t&ecirc;te pour la biblioth&egrave;que C et la
biblioth&egrave;que math&eacute;matique.</p>
</dd>
<dt><b><code>libc-5.2.18.tar.gz</code></b></dt>
<dd>
<p>--- Code source pour la biblioth&egrave;que ci-dessus. Vous
aurez &eacute;galement besoin du paquetage <code>.bin.</code> pour
avoir les fichiers d'en-t&ecirc;te. Si vous h&eacute;sitez entre
compiler la biblioth&egrave;que C vous-m&ecirc;me et utiliser les
binaires, la bonne r&eacute;ponse est dans la majorit&eacute; des
cas est d'utiliser les binaires. Toutefois, si vous d&eacute;sirer
utiliser NYS (NdT : NYS != NIS) ou bien les mots de passe
<em>shadow</em>, vous devrez recompiler la libc par
vous-m&ecirc;me.</p>
</dd>
<dt><b><code>libc-4.7.5.bin.tar.gz</code></b></dt>
<dd>
<p>--- biblioth&egrave;ques dynamiques et statiques a.out pour la
version 4.7.5 de la libc. Cette biblioth&egrave;que a
&eacute;t&eacute; con&ccedil;ue pour pouvoir coexister avec le
paquetage de la libc 5 d&eacute;crit ci-dessus, mais c'est
uniquement n&eacute;cessaire si vous d&eacute;sirez utiliser ou
d&eacute;velopper des programmes au format a.out.</p>
</dd>
</dl>
<h2><a name="index.11"></a> <a name="index.10"></a> <a name=
"index.9"></a> <a name="index.8"></a> <a name="ss2.5">2.5 Outils
associ&eacute;s (as, ld, ar, strings, etc.)</a></h2>
<p>Ces outils se trouvent comme les biblioth&egrave;ques dans le
r&eacute;pertoire <a href=
"ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/">tsx-11</a>, et
<a href="ftp://ftp.ibp.fr:/pub/linux/packages/GCC/">ftp.ibp.fr</a>.
La version actuelle est
<code>binutils-2.6.0.2.bin.tar.gz</code>.</p>
<p>Il est utile de remarquer que ces outils ne sont disponibles
qu'au format ELF, que la libc actuelle est ELF et que la libc a.out
ne pose pas de probl&egrave;me lorsqu'elle est utilis&eacute;e avec
la libc ELF. Le d&eacute;veloppement de la libc est relativement
rapide et &agrave; moins que n'ayez de bonnes raisons pour utiliser
le format a.out, vous &ecirc;tes encourag&eacute;s &agrave; suivre
le mouvement.</p>
<h2><a name="s3">3. Installation et configuration de GCC</a></h2>
<h2><a name="index.14"></a> <a name="index.13"></a> <a name=
"index.12"></a> <a name="ss3.1">3.1 Les versions de GCC</a></h2>
<p>Vous pouvez savoir quelle est la version de GCC que vous
poss&eacute;dez en tapant <code>gcc -v</code> lors de l'invite.
C'est &eacute;galement une bonne technique pour savoir si votre
configuration est ELF ou a.out. Sur mon syst&egrave;me, cela donne
ceci :</p>
<blockquote>
<pre>
<code>$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-zorglub-linux/2.7.2/specs
gcc version 2.7.2
</code>
</pre></blockquote>
<p>Les mots-clefs &agrave; remarquer</p>
<ul>
<li><code>i486</code>. Cela vous indique que la version de gcc que
vous utilisez a &eacute;t&eacute; compil&eacute;e pour &ecirc;tre
utilis&eacute;e sur un processeur 486 --- mais vous pouvez avoir un
autre processeur comme un 386 ou un Pentium (586). Tous ces
processeurs peuvent ex&eacute;cuter le code compil&eacute; avec
n'importe quel processeur. La seule diff&eacute;rence r&eacute;side
dans le fait que le code 486 rajoute un peu de code &agrave;
certains endroits pour aller plus vite sur un 486. Cela n'a pas
d'effet n&eacute;faste c&ocirc;t&eacute; performance sur un 386
mais cela rend les ex&eacute;cutables un peu plus importants.</li>
<li><code>zorglub</code>. Ce n'est pas r&eacute;ellement important,
et il s'agit g&eacute;n&eacute;ralement d'un commentaire (comme
<code>slackware</code> or <code>debian</code>) ou m&ecirc;me, cela
peut-&ecirc;tre vide (lorsque vous avez comme nom de
r&eacute;pertoire <code>i486-linux</code>). Si vous construisez
votre propre gcc, vous pouvez fixer ce param&egrave;tre selon vos
d&eacute;sirs, comme je l'ai fait. <code>:-)</code></li>
<li><code>linux</code>. Cela peut &ecirc;tre &agrave; la place
<code>linuxelf</code> ou <code>linuxaout</code> et en fait, la
signification varie en fonction de la version que vous
poss&eacute;dez.
<ul>
<li><code>linux</code> signifie ELF si la version est 2.7.0 ou
sup&eacute;rieure, sinon, c'est du a.out.</li>
<li><code>linuxaout</code> signifie a.out. Cela a &eacute;t&eacute;
introduit comme cible lorsque le format des binaires a
chang&eacute; de a.out vers ELF dans <b>Linux</b>. Normalement,
vous ne verrez plus de <code>linuxaout</code> avec une version de
gcc sup&eacute;rieure &agrave; 2.7.0. <a name="index.15"></a></li>
<li><code>linuxelf</code> est d&eacute;pass&eacute;. Il s'agit
g&eacute;n&eacute;ralement de gcc version 2.6.3 configur&eacute;
pour g&eacute;n&eacute;rer des ex&eacute;cutables ELF. Notez que
gcc 2.6.3 est connu pour g&eacute;n&eacute;rer de nombreuses
erreurs lorsqu'il produit du code ELF --- une mise &agrave; jour
est tr&egrave;s fortement recommand&eacute;e.</li>
</ul>
</li>
<li><code>2.7.2</code> est le num&eacute;ro de la version de
GCC.</li>
</ul>
<p>Donc, en r&eacute;sum&eacute;, nous poss&eacute;dons gcc 2.7.2
qui g&eacute;n&egrave;re du code ELF. <em>Quelle surprise</em>
(NdT: En fran&ccedil;ais dans le texte) !</p>
<h2><a name="ss3.2">3.2 A quel endroit s'installe GCC ?</a></h2>
<p>Si vous avez install&eacute; gcc sans regarder, ou bien si vous
l'avez eu &agrave; partir d'une distribution, vous pouvez avoir
envie de savoir o&ugrave; il se trouve dans votre arborescence. Les
mots clefs permettant cela sont</p>
<ul>
<li>
<code>/usr/lib/gcc-lib/</code><em>machine-cible</em><code>/</code><em>version</em><code>/</code>
(et ses sous-r&eacute;pertoires) est g&eacute;n&eacute;ralement
l'endroit o&ugrave; se trouve le plus souvent le compilateur. Ceci
inclut les ex&eacute;cutables qui r&eacute;alisent la compilation
ainsi que certaines biblioth&egrave;ques et quelques fichiers
d'en-t&ecirc;te.</li>
<li><code>/usr/bin/gcc</code> est le lanceur du compilateur ---
c'est en fait le programme que vous lancez. Il peut &ecirc;tre
utilis&eacute; avec plusieurs versions de gcc lorsque vous
poss&eacute;dez plusieurs r&eacute;pertoires install&eacute;s (voir
plus bas). Pour trouver la version par d&eacute;faut
utilis&eacute;e, lancez <code>gcc -v</code>. Pour forcer
l'utilisation d'une autre version, lancez <code>gcc -V</code>
<em>version</em>. Par exemple,
<blockquote>
<pre>
<code># gcc -v
Reading specs from /usr/lib/gcc-lib/i486-zorglub-linux/2.7.2/specs
gcc version 2.7.2
# gcc -V 2.6.3 -v
Reading specs from /usr/lib/gcc-lib/i486-zorglub-linux/2.6.3/specs
gcc driver version 2.7.2 executing gcc version 2.6.3
</code>
</pre></blockquote>
</li>
<li>
<code>/usr/</code><em>machine-cible</em><code>/(bin|lib|include)/</code>.
Si vous avez install&eacute; plusieurs cibles possibles (par
exemple a.out et elf, ou bien un compilateur crois&eacute;, les
biblioth&egrave;ques, les binutils (<code>as</code>,
<code>ld</code>, etc.) et les fichiers d'en-t&ecirc;te pour les
cibles diff&eacute;rente de celle par d&eacute;faut peuvent
&ecirc;tre trouv&eacute;s &agrave; cet endroit. M&ecirc;me si vous
n'avez qu'une seule version de gcc install&eacute;e, vous devriez
toutefois trouver &agrave; cet endroit un certain nombre de
fichiers. Si ce n'est pas la cas, regardez dans
<code>/usr/(bin|lib|include)</code>.</li>
<li><code>/lib/</code>, <code>/usr/lib</code> et autres sont les
r&eacute;pertoires pour les biblioth&egrave;ques pour le
syst&egrave;me initial. Vous aurez &eacute;galement besoin du
programme <code>/lib/cpp</code> pour un grand nombre d'applications
(X l'utilise beaucoup) --- soit vous le copiez &agrave; partir de
<code>/usr/lib/gcc-lib/</code><em>machine-cible</em><code>/</code><em>version</em><code>/</code>,
soit vous faites pointer un lien symbolique dessus. <a name=
"index.16"></a></li>
</ul>
<h2><a name="index.17"></a> <a name="ss3.3">3.3 O&ugrave; se
trouvent les fichiers d'en-t&ecirc;te ?</a></h2>
<p>Si l'on excepte les fichier fichiers d'en-t&ecirc;te que vous
installez dans le r&eacute;pertoire
<code>/usr/local/include</code>, il y a en fait trois types de
fichiers d'en-t&ecirc;te :</p>
<ul>
<li>La grande majorit&eacute; des fichiers situ&eacute;s dans le
r&eacute;pertoire <code>/usr/include/</code> et dans ses
sous-r&eacute;pertoires proviennent du paquetage de la libc dont
s'occupe H.J. Lu. Je dis bien la "grande majorit&eacute;" car vous
pouvez avoir &eacute;galement certains fichiers provenant d'autres
sources (par exemple des biblioth&egrave;ques <code>curses</code>
et <code>dbm</code>), ceci est d'autant plus vrai si vous
poss&eacute;dez une distribution de la libc r&eacute;cente
(o&ugrave; les biblioth&egrave;ques curses et dbm ne sont pas
int&eacute;gr&eacute;es). <a name="index.18"></a> <a name=
"index.19"></a></li>
<li>Les r&eacute;pertoires <code>/usr/include/linux</code> et
<code>/usr/include/asm</code> (pour les fichiers
<code>&lt;linux/*.h&gt;</code> et <code>&lt;asm/*.h&gt;</code>)
doivent &ecirc;tre des liens symboliques vers les
r&eacute;pertoires <code>linux/include/linux</code> et
<code>linux/include/asm</code> situ&eacute;s dans les sources du
noyau. Vous devrez installer ces sources si vous d&eacute;sirez
pouvoir d&eacute;velopper : ces sources ne sont pas utilis&eacute;s
uniquement pour compiler le noyau. Il est probable que vous ayez
besoin de lancer la commande suivante <code>make config</code> dans
le r&eacute;pertoire des sources du noyau apr&egrave;s les avoir
install&eacute;s. Beaucoup de fichiers ont besoin du fichier
d'en-t&ecirc;te <code>&lt;linux/autoconf.h&gt;</code> qui n'existe
pas sans cette commande. Il est &agrave; noter que dans certaines
versions du noyau, le r&eacute;pertoire <code>asm</code> est en
fait un lien symbolique qui n'est cr&eacute;&eacute; qu'avec
l'ex&eacute;cution de <code>make config</code>. Donc, si vous
installez les sources du noyau dans le r&eacute;pertoire
<code>/usr/src/linux</code>, il suffit de faire :
<blockquote>
<pre>
<code>$ cd /usr/src/linux
$ su
# make config
[repondez aux questions. A moins que vous ne recompiliez votre
noyau, les reponses importent peu]
# cd /usr/include
# ln -s ../src/linux/include/linux .
# ln -s ../src/linux/include/asm .
</code>
</pre></blockquote>
<a name="index.20"></a> <a name="index.21"></a> <a name=
"index.22"></a> <a name="index.23"></a> <a name=
"index.24"></a></li>
<li>Les fichiers tels que <code>&lt;float.h&gt;</code>,
<code>&lt;limits.h&gt;</code>, <code>&lt;varargs.h&gt;</code>,
<code>&lt;stdarg.h&gt;</code> et <code>&lt;stddef.h&gt;</code>
changent en fonction de la version du compilateur, et peuvent
&ecirc;tre trouv&eacute;s dans le r&eacute;pertoire
<code>/usr/lib/gcc-lib/i486-box-linux/2.7.2/include/</code> pour la
version <code>2.7.2</code>.</li>
</ul>
<h2><a name="ss3.4">3.4 Construire un compilateur
crois&eacute;</a></h2>
<h3>Linux comme plate-forme de destination</h3>
<p>Nous supposons que vous avez r&eacute;cup&eacute;r&eacute; les
sources de gcc, et normalement, il vous suffit de suivre les
instructions donn&eacute;es dans le fichier <code>INSTALL</code>
situ&eacute; dans les sources de gcc. Ensuite, il suffit de lancer
<code>configure --target=i486-linux --host=XXX</code> sur une
plateforme <code>XXX</code>, puit un <code>make</code> devrait
compiler gcc correctement. Il est &agrave; noter que vous aurez
besoin des fichiers d'en-t&ecirc;te de Linux, ainsi que les sources
de l'assembleur et du l'&eacute;diteur de liens crois&eacute;s que
vous pouvez trouver sur <a href=
"ftp://tsx-11.mit.edu/pub/linux/packages/GCC/">ftp://tsx-11.mit.edu/pub/linux/packages/GCC/</a>
ou <a href=
"ftp://ftp.ibp.fr/pub/linux/GCC/">ftp://ftp.ibp.fr/pub/linux/GCC/</a>.</p>
<h3>Linux comme plate-forme origine et MSDOS comme destination</h3>
<p>Arggg. Apparemment, cela est possible en utilisant le paquetage
&laquo; emx &raquo; ou l'extension &laquo; go &raquo;. Regardez
<a href=
"ftp://sunsite.unc.edu/pub/Linux/devel/msdos">ftp://sunsite.unc.edu/pub/Linux/devel/msdos</a>
pour plus d'informations.</p>
<p>Je n'ai pas test&eacute; cela et je ne pense pas le faire !</p>
<h2><a name="s4">4. Portage et compilation</a></h2>
<h2><a name="index.25"></a> <a name="ss4.1">4.1 Symboles
d&eacute;finis automatiquement</a></h2>
<p>Vous pouvez trouver quels symboles votre version de gcc
d&eacute;finit automatiquement en le lan&ccedil;ant avec l'option
<code>-v</code>. Par exemple cela donne &ccedil;a chez moi :</p>
<blockquote>
<pre>
<code>$ echo 'main(){printf("Bonjour !\n");}' | gcc -E -v -
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
gcc version 2.7.2
 /usr/lib/gcc-lib/i486-box-linux/2.7.2/cpp -lang-c -v -undef
-D__GNUC__=2 -D__GNUC_MINOR__=7 -D__ELF__ -Dunix -Di386 -Dlinux
-D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__i386
-D__linux -Asystem(unix) -Asystem(posix) -Acpu(i386)
-Amachine(i386) -D__i486__ -
</code>
</pre></blockquote>
Si vous &eacute;crivez du code qui utilise des
sp&eacute;cificit&eacute;s Linux, il est souhaitable
d'impl&eacute;menter le code non portable de la mani&egrave;re
suivante
<blockquote>
<pre>
<code>#ifdef __linux__
/* ... code linux ... */
#endif /* linux */
</code>
</pre></blockquote>
<p>Utilisez <code>__linux__</code> pour cela, et <em>pas</em>
<code>linux</code>. Bien que cette macro soit d&eacute;finie, ce
n'est pas une sp&eacute;cification POSIX.</p>
<h2><a name="ss4.2">4.2 Options de compilation</a></h2>
<p>La documentation des options de compilation se trouve dans les
pages <em>info</em> de gcc (sous Emacs, utilisez <code>C-h i</code>
puis s&eacute;lectionnez l'option `gcc'). Votre distribution peut
ne pas avoir install&eacute; la documentation ou bien vous pouvez
en avoir une ancienne. Dans ce cas, la meilleure chose &agrave;
faire est de r&eacute;cup&eacute;rer les sources de gcc depuis
<a href=
"ftp://prep.ai.mit.edu/pub/gnu">ftp://prep.ai.mit.edu/pub/gnu</a>
ou l'un des ses nombreux miroirs dont <a href=
"ftp://ftp.ibp.fr/pub/gnu">ftp://ftp.ibp.fr/pub/gnu</a>.</p>
<p>La page de manuel gcc (<code>gcc.1</code>) est en principe,
compl&egrave;tement d&eacute;pass&eacute;e. Cela vous met en garde
si vous d&eacute;sirez la consulter.</p>
<h3><a name="index.27"></a> <a name="index.26"></a> Options de
compilation</h3>
<p>gcc peut r&eacute;aliser un certain nombre d'optimisations sur
le code g&eacute;n&eacute;r&eacute; en ajoutant l'option
<code>-O</code><em>n</em> &agrave; la ligne de commandes, o&ugrave;
<em>n</em> est un chiffre. La valeur de <em>n</em>, et son effet
exact, d&eacute;pend de la version de gcc, mais s'&eacute;chelonne
normalement entre 0 (aucune optimisation) et 2 (un certain nombre)
ou 3 (toutes les optimisations possibles).</p>
<p>En interne, gcc interpr&egrave;te les options telles que
<code>-f</code> et <code>-m</code>. Vous pouvez voir exactement ce
qu'effectue le niveau sp&eacute;cifi&eacute; dans l'option
<code>-O</code> en lan&ccedil;ant gcc avec l'option <code>-v</code>
et l'option (non document&eacute;e) <code>-Q</code>. Par exemple,
l'option <code>-O2</code>, effectue les op&eacute;rations suivantes
sur ma machine :</p>
<blockquote>
<pre>
<code>enabled: -fdefer-pop -fcse-follow-jumps -fcse-skip-blocks
-fexpensive-optimizations
         -fthread-jumps -fpeephole -fforce-mem -ffunction-cse -finline
         -fcaller-saves -fpcc-struct-return -frerun-cse-after-loop
         -fcommon -fgnu-linker -m80387 -mhard-float -mno-soft-float
         -mno-386 -m486 -mieee-fp -mfp-ret-in-387
</code>
</pre></blockquote>
<p>Utiliser un niveau d'optimisation sup&eacute;rieur &agrave;
celui que le compilateur supporte (par exemple <code>-O6</code>)
aura le m&ecirc;me effet qu'utiliser le plus haut niveau
g&eacute;r&eacute;. Distribuer du code o&ugrave; la compilation est
configur&eacute;e de cette mani&egrave;re est une tr&egrave;s
mauvaise id&eacute;e -- si d'autres optimisations sont
incorpor&eacute;es dans de versions futures, vous (ou d'autres
utilisateurs) pouvez vous apercevoir que cela ne compile plus, ou
bien que le code g&eacute;n&eacute;r&eacute; ne fait pas les
actions d&eacute;sir&eacute;es.</p>
<p><a name="index.28"></a> Les utilisateurs de gcc 2.7.0 &agrave;
2.7.2 devraient noter qu'il y a un bogue dans l'option
<code>-O2</code>. Plus pr&eacute;cis&eacute;ment, la <em>strength
reduction</em> ne fonctionne pas. Un patch a &eacute;t&eacute;
impl&eacute;ment&eacute; pour r&eacute;soudre ce probl&egrave;me,
mais vous devez alors recompiler gcc. Sinon, vous devrez toujours
compiler avec l'option <code>-fno-strength-reduce</code>.</p>
<h3>Sp&eacute;cification du processeur</h3>
<p>Il existe d'autres options <code>-m</code> qui ne sont pas
positionn&eacute;es lors de l'utilisation de <code>-O</code> mais
qui sont n&eacute;anmoins utiles dans certains cas. C'est le cas
pour les options <code>-m386</code> et <code>-m486</code>, qui
indiquent &agrave; gcc de g&eacute;n&eacute;rer un code plus ou
moins optimis&eacute; pour l'un ou l'autre type de processeur. Le
code continuera &agrave; fonctionner sur les deux processeurs. Bien
que le code pour 486 soit plus important, il ne ralentit pas
l'ex&eacute;cution du programme sur 386.</p>
<p>Il n'existe pas actuellement de <code>-mpentium</code> ou
<code>-m586</code>. Linus a sugg&eacute;r&eacute; l'utilisation des
options <code>-m486 -malign-loops=2 -malign-jumps=2
-malign-functions=2</code>, pour exploiter les optimisations du 486
tout en perdant de la place due aux probl&egrave;mes d'alignements
(dont le Pentium n'a que faire). Michael Meissner (de Cygnus) nous
dit :</p>
<blockquote>&laquo; Mon avis est que l'option
<code>-mno-strength-reduce</code> permet d'obtenir un code plus
rapide sur un x86 (nota : je ne parle pas du bogue <em>strength
reduction</em>, qui est un autre probl&egrave;me). Cela s'explique
en raison du peu de registres dont disposent ces processeurs (et la
m&eacute;thode de GCC qui consiste &agrave; grouper les registres
dans l'ordre inverse au lieu d'utiliser d'autres registres
n'arrange rien). La <em>strength reduction</em> consiste en fait
&agrave; rajouter des registres pour remplacer les multiplications
par des additions. Je suspecte &eacute;galement
<code>-fcaller-saves</code> de ne pas arranger la situation.
&raquo;</blockquote>
<blockquote>Une autre id&eacute;e est que
<code>-fomit-frame-pointer</code> n'est pas obligatoirement une
bonne id&eacute;e. D'un c&ocirc;t&eacute;, cela peut signifier
qu'un autre registre est disponible pour une allocation. D'un autre
c&ocirc;t&eacute;, vue la mani&egrave;re dont les processeurs x86
codent leur jeu d'instruction, cela peut signifier que la pile des
adresses relatives prend plus de place que les adresses de
fen&ecirc;tres relatives, ce qui signifie en clair que moins de
cache est disponible pour l'ex&eacute;cution du processus. Il faut
pr&eacute;ciser que l'option <code>-fomit-frame-pointer</code>,
signifie que le compilateur doit constamment ajuster le pointeur de
pile apr&egrave;s les appels, alors qu'avec une fen&ecirc;tre, il
peut laisser plusieurs appels dans la pile.</blockquote>
<p>Le mot final sur le sujet provient de Linus :</p>
<blockquote>Remarquez que si vous voulez des performances
maximales, ne me croyez pas : testez ! Il existe tellement
d'options de gcc, et il est possible que cela ne soit une
r&eacute;elle optimisation que pour vous.</blockquote>
<h3><a name="index.33"></a> <a name="index.32"></a> <a name=
"index.31"></a> <a name="index.30"></a> <a name="index.29"></a>
<code>Internal compiler error: cc1 got fatal signal 11</code></h3>
<p>Signal 11 correspond au signal SIGSEGV, ou bien <em>segmentation
violation</em>. Normalement, cela signifie que le programme s'est
m&eacute;lang&eacute; les pointeurs et a essay&eacute;
d'&eacute;crire l&agrave; o&ugrave; il n'en a pas le droit. Donc,
cela pourrait &ecirc;tre un bug de gcc.</p>
<p>Toutefois, gcc est un logiciel assez test&eacute; et assez
remarquable de ce c&ocirc;t&eacute;. Il utilise un grand nombre de
structures de donn&eacute;es complexes, et un nombre impressionnant
de pointeurs. En r&eacute;sum&eacute;, c'est le plus pointilleux
des testeurs de m&eacute;moire existants. Si vous <em>n'arrivez pas
&agrave; reproduire le bogue</em> --- si cela ne s'arr&ecirc;te pas
au m&ecirc;me endroit lorsque vous retentez la compilation ---
c'est plut&ocirc;t un probl&egrave;me avec votre machine
(processeur, m&eacute;moire, carte m&egrave;re ou bien cache).
<b>N'annoncez pas</b> la d&eacute;couverte d'un nouveau bogue si
votre ordinateur traverse tous les tests du BIOS, ou s'il
fonctionne correctement sous Windows ou autre : ces tests ne valent
rien. Il en va de m&ecirc;me si le noyau s'arr&ecirc;te lors du
`<code>make zImage</code>' ! `<code>make zImage</code>' doit
compiler plus de 200 fichiers, et il en faut bien moins pour
arriver &agrave; faire &eacute;chouer une compilation.</p>
<p>Si vous arrivez &agrave; reproduire le bogue et (mieux encore)
&agrave; &eacute;crire un petit programme qui permet de mettre en
&eacute;vidence cette erreur, alors vous pouvez envoyer le code
soit &agrave; la FSF, soit dans la liste linux-gcc. Consultez la
documentation de gcc pour plus de d&eacute;tails concernant les
informations n&eacute;cessaires.</p>
<h2><a name="ss4.3">4.3 Portabilit&eacute;</a></h2>
<p>Cette phrase a &eacute;t&eacute; dite un jour : si quelque chose
n'a pas &eacute;t&eacute; port&eacute; vers Linux alors ce n'est
pas important de l'avoir :-).</p>
<p>Plus s&eacute;rieusement, en g&eacute;n&eacute;ral seules
quelques modifications mineures sont n&eacute;cessaires car Linux
r&eacute;pond &agrave; 100% aux sp&eacute;cifications POSIX. Il est
g&eacute;n&eacute;ralement sympathique d'envoyer &agrave; l'auteur
du programme les modifications effectu&eacute;es pour que le
programme fonctionne sur Linux, pour que lors d'une future version,
un `make' suffise pour g&eacute;n&eacute;rer
l'ex&eacute;cutable.</p>
<h3>Sp&eacute;cificit&eacute;s BSD (notamment
<code>bsd_ioctl</code>, <code>daemon</code> et
<code>&lt;sgtty.h&gt;</code>)</h3>
<p>Vous pouvez compiler votre programme avec l'option
<code>-I/usr/include/bsd</code> et faire l'&eacute;dition de liens
avec <code>-lbsd</code> (en ajoutant
<code>-I/usr/include/bsd</code> &agrave; la ligne
<code>CFLAGS</code> et <code>-lbsd</code> &agrave; la ligne
<code>LDFLAGS</code> dans votre fichier <code>Makefile</code>). Il
est &eacute;galement n&eacute;cessaire de ne <b>pas</b> ajouter
<code>-D__USE_BSD_SIGNAL</code> si vous voulez que les signaux BSD
fonctionnent car vous les avez inclus automatiquement avec la ligne
<code>-I/usr/include/bsd</code> et en incluant le fichier
d'en-t&ecirc;te <code>&lt;signal.h&gt;</code>.</p>
<h3><a name="index.38"></a> <a name="index.37"></a> <a name=
"index.36"></a> <a name="index.35"></a> <a name="index.34"></a>
Signaux <em>manquants</em> (<code>SIGBUS</code>,
<code>SIGEMT</code>, <code>SIGIOT</code>, <code>SIGTRAP</code>,
<code>SIGSYS</code>, etc.)</h3>
<p>Linux respecte les sp&eacute;cifications POSIX. Ces signaux n'en
font pas partie (cf. ISO/IEC 9945-1:1990 - IEEE Std 1003.1-1990,
paragraphe B.3.3.1.1) :</p>
<blockquote>&laquo; Les signaux SIGBUS, SIGEMT, SIGIOT, SIGTRAP, et
SIGSYS ont &eacute;t&eacute; omis de la norme POSIX.1 car leur
comportement est d&eacute;pendant de l'impl&eacute;mentation et
donc ne peut &ecirc;tre r&eacute;pertori&eacute; d'une
mani&egrave;re satisfaisante. Certaines impl&eacute;mentations
peuvent fournir ces signaux mais doivent documenter leur effet
&raquo;</blockquote>
<p>La mani&egrave;re la plus &eacute;l&eacute;gante de
r&eacute;gler ce probl&egrave;me est de red&eacute;finir ces
signaux &agrave; <code>SIGUNUSED</code>. La mani&egrave;re
<em>normale</em> de proc&eacute;der est d'entourer le code avec les
<code>#ifdef</code> appropri&eacute;s :</p>
<blockquote>
<pre>
<code>#ifdef SIGSYS
/* ... code utilisant les signaux non posix  .... */
#endif
</code>
</pre></blockquote>
<h3><a name="index.39"></a> Code K &amp; R</h3>
<p>GCC est un compilateur ANSI, or il existe beaucoup de code qui
ne soit pas ANSI.</p>
<p>Il n'y a pas grand chose &agrave; faire, sauf rajouter l'option
<code>-traditional</code> lors de la compilation. Il effectue
certaines v&eacute;rifications suppl&eacute;mentaires. Consultez
les pages info gcc.</p>
<p>Notez que l'option <code>-traditional</code> a pour unique effet
de changer la forme du langage accept&eacute; par gcc. Par exemple,
elle active l'option <code>-fwritable-strings</code>, qui
d&eacute;place toutes les cha&icirc;nes de caract&egrave;res vers
l'espace de donn&eacute;es (depuis l'espace de texte, o&ugrave;
elle ne peuvent pas &ecirc;tre modifi&eacute;es). Ceci augmente la
taille de la m&eacute;moire occup&eacute;e par le programme.</p>
<h3><a name="index.41"></a> <a name="index.40"></a> Les symboles du
pr&eacute;processeur produisent un conflit avec les prototypes du
code</h3>
<p>Un des probl&egrave;mes fr&eacute;quents se produit lorsque
certaines fonctions standards sont d&eacute;finies comme macros
dans les fichiers d'en-t&ecirc;te de Linux et le
pr&eacute;processeur refusera de traiter des prototypes identiques.
Par exemple, cela peut arriver avec <code>atoi()</code> et
<code>atol()</code>.</p>
<h3><a name="index.42"></a> <code>sprintf()</code></h3>
<p>Parfois, soyez prudent lorsque vous effectuez un portage
&agrave; partir des sources de programmes fonctionnant sous SunOs,
surtout avec la fonction <code>sprintf(string, fmt, ...)</code> car
elle renvoie un pointeur sur la cha&icirc;ne de caract&egrave;res
alors que Linux (suivant la norme ANSI) retourne le nombre de
caract&egrave;res recopi&eacute;s dans la cha&icirc;ne de
caract&egrave;res.</p>
<h3><a name="index.49"></a> <a name="index.48"></a> <a name=
"index.47"></a> <a name="index.46"></a> <a name="index.45"></a>
<a name="index.44"></a> <a name="index.43"></a> <code>fcntl</code>
et ses copains. O&ugrave; se trouve la d&eacute;finition de
<code>FD_*</code> et compagnie ?</h3>
<p>Dans <code>&lt;sys/time.h&gt;</code>. Si vous utilisez
<code>fcntl</code> vous voudrez probablement inclure
<code>&lt;unistd.h&gt;</code> &eacute;galement, pour avoir le
prototype de la fonction.</p>
<p>D'une mani&egrave;re g&eacute;n&eacute;rale, la page de manuel
pour une fonction donne la liste des fichiers d'en-t&ecirc;te
&agrave; inclure.</p>
<h3><a name="index.50"></a> Le timeout de <code>select()</code>.
Les programmes commencent dans un &eacute;tat d'attente active</h3>
<p>A une certaine &eacute;poque, le param&egrave;tre timeout de la
fonction <code>select()</code> &eacute;tait utilis&eacute; en
lecture seule. C'est pourquoi la page de manuel comporte une mise
en garde :</p>
<blockquote>select() devrait retourner normalement le temps
&eacute;coul&eacute; depuis le timeout initial, s'il s'est
d&eacute;clench&eacute;, en modifiant la valeur point&eacute;e par
le param&egrave;tre <code>time</code>. Cela sera peut-&ecirc;tre
impl&eacute;ment&eacute; dans les versions ult&eacute;rieures du
syst&egrave;me. Donc, il n'est pas vraiment prudent de supposer que
les donn&eacute;es point&eacute;es ne seront pas modifi&eacute;es
lors de l'appel &agrave; select().</blockquote>
<p>Mais tout arrive avec le temps ! Lors d'un retour de
<code>select()</code>, l'argument <code>timeout</code> recevra le
temps &eacute;coul&eacute; depuis la derni&egrave;re
r&eacute;ception de donn&eacute;es. Si aucune donn&eacute;e n'est
arriv&eacute;e, la valeur sera nulle, et les futurs appels &agrave;
cette fonction utilisant le m&ecirc;me <code>timeout</code> auront
pour r&eacute;sultat un retour imm&eacute;diat.</p>
<p>Pour r&eacute;soudre le probl&egrave;me, il suffit de mettre la
valeur <code>timeout</code> dans la structure &agrave; chaque appel
de <code>select()</code>. Le code initial &eacute;tait</p>
<blockquote>
<pre>
<code>      struct timeval timeout;
      timeout.tv_sec = 1; 
      timeout.tv_usec = 0;
      while (some_condition)
            select(n,readfds,writefds,exceptfds,&amp;timeout); 
</code>
</pre></blockquote>
et doit devenir :
<blockquote>
<pre>
<code>      struct timeval timeout;
      while (some_condition) 
      {
            timeout.tv_sec = 1; 
            timeout.tv_usec = 0;
            select(n,readfds,writefds,exceptfds,&amp;timeout);
      }
</code>
</pre></blockquote>
<p>Certaines versions de Mosaic &eacute;taient connues &agrave; une
certaine &eacute;poque pour avoir ce probl&egrave;me.</p>
<p>La vitesse de rotation du globe terrestre &eacute;tait
inversement proportionnelle &agrave; la vitesse de transfert des
donn&eacute;es !</p>
<h3><a name="index.52"></a> <a name="index.51"></a> Appels
syst&egrave;mes interrompus</h3>
<h3>Symptomes :</h3>
<p>Lorsqu'un processus est arr&ecirc;t&eacute; avec un Ctrl-Z et
relanc&eacute; - ou bien lorsqu'un autre signal est
d&eacute;clench&eacute; dans une situation diff&eacute;rente : par
exemple avec un Ctrl-C, la terminaison d'un processus, etc, on dit
qu'il y a &laquo; interruption d'un appel syst&egrave;me &raquo; ,
ou bien &laquo; write : erreur inconnue &raquo; ou des trucs de ce
genre.</p>
<h3>Probl&egrave;mes :</h3>
<p>Les syst&egrave;mes POSIX v&eacute;rifient les signaux plus
souvent que d'autres Unix plus anciens. Linux peux lancer les
gestionnaires de signaux :</p>
<ul>
<li>d'une mani&egrave;re asynchrone (sur un top d'horloge)</li>
<li>lors d'un retour de n'importe quel appel syst&egrave;me</li>
<li>pendant l'ex&eacute;cution des appels syst&egrave;mes suivants
: <code>select()</code>, <code>pause()</code>,
<code>connect()</code>, <code>accept()</code>, <code>read()</code>
sur des terminaux, des sockets, des pipes ou des fichiers
situ&eacute;s dans <code>/proc</code>, <code>write()</code> sur des
terminaux, des sockets, des pipes ou des imprimantes,
<code>open()</code> sur des FIFOs, des lignes PTYs ou
s&eacute;ries, <code>ioctl()</code> sur des terminaux,
<code>fcntl()</code> avec la commande <code>F_SETLKW</code>,
<code>wait4()</code>, <code>syslog()</code>, et toute
op&eacute;ration d'ordre TCP ou NFS.</li>
</ul>
<p>Sur d'autres syst&egrave;mes d'exploitation, il est possible que
vous ayez &agrave; inclure dans cette cat&eacute;gorie les appels
syst&egrave;mes suivants : <code>creat()</code>,
<code>close()</code>, <code>getmsg()</code>, <code>putmsg()</code>,
<code>msgrcv()</code>, <code>msgsnd()</code>, <code>recv()</code>,
<code>send()</code>, <code>wait()</code>, <code>waitpid()</code>,
<code>wait3()</code>, <code>tcdrain()</code>,
<code>sigpause()</code>, <code>semop()</code>.</p>
<p>Si un signal (que le programme d&eacute;sire traiter) est
lanc&eacute; pendant l'ex&eacute;cution d'un appel syst&egrave;me,
le gestionnaire est lanc&eacute;. Lorsque le gestionnaire du signal
se termine, l'appel syst&egrave;me d&eacute;tecte qu'il a
&eacute;t&eacute; interrompu et se termine avec la valeur -1 et
<code>errno = EINTR</code>. Le programme n'est pas forc&eacute;ment
au courant de ce qui s'est pass&eacute; et donc s'arr&ecirc;te.</p>
<p>Vous pouvez choisir deux solutions pour r&eacute;soudre ce
probl&egrave;me.</p>
<p>(1)Dans tout gestionnaire de signaux que vous mettez en place,
ajoutez l'option <code>SA_RESTART</code> au niveau de
<em>sigaction</em>. Par exemple, modifiez</p>
<blockquote>
<pre>
<code>  signal (signal_id, mon_gestionnaire_de_signaux);
</code>
</pre></blockquote>
en
<blockquote>
<pre>
<code>  signal (signal_id, mon_gestionnaire_de_signaux);
  { 
        struct sigaction sa;
        sigaction (signal_id, (struct sigaction *)0, &amp;sa);
#ifdef SA_RESTART
        sa.sa_flags |= SA_RESTART;
#endif
#ifdef SA_INTERRUPT
        sa.sa_flags &amp;= ~ SA_INTERRUPT;
#endif
        sigaction (signal_id, &amp;sa, (struct sigaction *)0);
  }
</code>
</pre></blockquote>
<p>Notez que lors de certains appels syst&egrave;mes vous devrez
souvent regarder si <code>errno</code> n'a pas &eacute;t&eacute;
positionn&eacute;e &agrave; <code>EINTR</code> par vous m&ecirc;me
comme avec <code>read()</code>, <code>write()</code>,
<code>ioctl()</code>, <code>select()</code>, <code>pause()</code>
et <code>connect()</code>.</p>
<p>(2) A la recherche de <code>EINTR</code> :</p>
<p>Voici deux exemples avec <code>read()</code> et
<code>ioctl()</code>,</p>
<p>Voici le code original utilisant <code>read()</code></p>
<blockquote>
<pre>
<code>int result;
while (len &gt; 0) 
{ 
  result = read(fd,buffer,len);
  if (result &lt; 0) 
        break;
  buffer += result; 
  len -= result;
}
</code>
</pre></blockquote>
et le nouveau code
<blockquote>
<pre>
<code>int result;
while (len &gt; 0) 
{ 
  result = read(fd,buffer,len);
  if (result &lt; 0) 
  { 
        if (errno != EINTR) 
                break; 
  }
  else 
  { 
        buffer += result; 
        len -= result; 
  }
}
</code>
</pre></blockquote>
Voici un code utilisant <code>ioctl()</code>
<blockquote>
<pre>
<code>int result;
result = ioctl(fd,cmd,addr);
</code>
</pre></blockquote>
et cela devient
<blockquote>
<pre>
<code>int result;
do 
{ 
   result = ioctl(fd,cmd,addr); 
}
while ((result == -1) &amp;&amp; (errno == EINTR));
</code>
</pre></blockquote>
<p>Il faut remarquer que dans certaines versions d'Unix de type BSD
on a l'habitude de relancer l'appel syst&egrave;me. Pour
r&eacute;cup&eacute;rer les interruptions d'appels syst&egrave;mes,
vous devez utiliser les options <code>SV_INTERRUPT</code> ou
<code>SA_INTERRUPT</code>.</p>
<h3><a name="index.56"></a> <a name="index.55"></a> <a name=
"index.54"></a> <a name="index.53"></a> Les cha&icirc;nes et leurs
acc&egrave;s en &eacute;critures (ou les programmes qui provoquent
des &laquo; segmentation fault &raquo; d'une mani&egrave;re
al&eacute;atoire)</h3>
<p>GCC a une vue optimiste en ce qui concerne ses utilisateurs, en
croyant qu'ils respectent le fait qu'une cha&icirc;ne dite
constante l'est r&eacute;ellement. Donc, il les range dans la zone
<em>texte(code)</em> du programme, o&ugrave; elles peuvent
&ecirc;tre charg&eacute;es puis d&eacute;charg&eacute;es &agrave;
partir de l'image binaire de l'ex&eacute;cutable situ&eacute;e sur
disque (ce qui &eacute;vite d'occuper de l'espace disque). Donc,
toute tentative d'&eacute;criture dans cette cha&icirc;ne provoque
un &laquo; segmentation fault &raquo;.</p>
<p>Cela peut poser certains probl&egrave;mes avec d'anciens codes,
par exemple ceux qui utilisent la fonction <code>mktemp()</code>
avec une cha&icirc;ne constante comme argument.
<code>mktemp()</code> essaye d'&eacute;crire dans la cha&icirc;ne
pass&eacute;e en argument.</p>
<p>Pour r&eacute;soudre ce probl&egrave;me,</p>
<ol>
<li>compilez avec l'option <code>-fwritable-strings</code> pour
indiquer &agrave; gcc de mettre les cha&icirc;nes constantes dans
l'espace de donn&eacute;es</li>
<li>r&eacute;&eacute;crire les diff&eacute;rentes parties du code
pour allouer une cha&icirc;ne non constante puis effectuer un
strcpy des donn&eacute;es dedans avant d'effectuer l'appel.</li>
</ol>
<h3><a name="index.57"></a> Pourquoi l'appel &agrave;
<code>execl()</code> &eacute;choue ?</h3>
<p>Tout simplement parce que vous l'utilisez mal. Le premier
argument d'<code>execl</code> est le programme que vous
d&eacute;sirez ex&eacute;cuter. Le second et ainsi de suite sont en
fait le &eacute;l&eacute;ments du tableau <code>argv</code> que
vous appelez. Souvenez-vous que <code>argv[0]</code> est
traditionnellement fix&eacute; m&ecirc;me si un programme est
lanc&eacute; sans argument. Vous devriez donc &eacute;crire :</p>
<blockquote>
<pre>
<code>execl("/bin/ls","ls",NULL);
</code>
</pre></blockquote>
et pas
<blockquote>
<pre>
<code>execl("/bin/ls", NULL);
</code>
</pre></blockquote>
<p>Lancer le programme sans argument est consid&eacute;r&eacute;
comme &eacute;tant une demande d'affichage des biblioth&egrave;ques
dynamiques associ&eacute;es au programme, si vous utilisez le
format a.out. ELF fonctionne d'une mani&egrave;re
diff&eacute;rente.</p>
<p>(Si vous d&eacute;sirez ces informations, il existe des outils
plus simples; consultez la section sur le chargement dynamique, ou
la page de manuel de <code>ldd</code>).</p>
<h2><a name="s5">5. D&eacute;boguer et optimiser</a></h2>
<h2><a name="index.58"></a> <a name="ss5.1">5.1 Etude
pr&eacute;ventive du code (lint)</a></h2>
<p>Il n'existe pas de lint qui soit r&eacute;ellement utilisable,
tout simplement parce que la grande majorit&eacute; des
d&eacute;veloppeurs sont satisfaits des messages d'avertissement de
gcc. Il est probable que l'option la plus utile est l'option
<code>-Wall</code> --- qui a pour effet d'afficher tous les
avertissements possibles.</p>
<p>Il existe une version du domaine public du programme lint que
vous pouvez trouver &agrave; l'adresse suivante : <a href=
"ftp://larch.lcs.mit.edu/pub/Larch/lclint">ftp://larch.lcs.mit.edu/pub/Larch/lclint</a>.
Je ne sais pas ce qu'elle vaut.</p>
<h2><a name="index.59"></a> <a name="ss5.2">5.2
D&eacute;boguer</a></h2>
<h3><a name="index.62"></a> <a name="index.61"></a> <a name=
"index.60"></a> Comment rendre d&eacute;bogable un programme ?</h3>
<p>Vous devez compiler et effectuer l'&eacute;dition de liens avec
l'option <code>-g</code>, et sans l'option
<code>-fomit-frame-pointer</code>. En fait, vous ne devez compiler
que les modules que vous avez besoin de d&eacute;boguer.</p>
<p>Si vous poss&eacute;dez un syst&egrave;me a.out, les
biblioth&egrave;ques dynamiques sont compil&eacute;es avec l'option
<code>-fomit-frame-pointer</code>, que gcc ne peut pas
g&eacute;rer. Lorsque vous compilez avec l'option <code>-g</code>,
alors par d&eacute;faut vous effectuez une &eacute;dition de liens
statique, ce qui permet de r&eacute;soudre le probl&egrave;me.</p>
<p>Si l'&eacute;diteur de liens &eacute;choue avec un message
disant qu'il n'arrive pas &agrave; trouver la biblioth&egrave;que
libg.a, c'est que vous ne poss&eacute;dez pas la
biblioth&egrave;que <code>/usr/lib/libg.a</code>, qui est la
biblioth&egrave;que C standard permettant le d&eacute;bogage. Cette
biblioth&egrave;que est fournie dans le paquetage des binaires de
la libc., ou (dans les nouvelles versions) vous aurez besoin de
r&eacute;cup&eacute;rer le source et de le compiler
vous-m&ecirc;me. Vous n'avez pas r&eacute;ellement besoin de cela
en fait, vous pouvez faire un lien logique vers
<code>/usr/lib/libc.a</code></p>
<h3><a name="index.63"></a> Comment r&eacute;duire la taille des
ex&eacute;cutables ?</h3>
<p>Bon nombre de produits GNU sont fournis pour compiler avec
l'option <code>-g</code>, ce qui g&eacute;n&egrave;re des
ex&eacute;cutables d'une taille tr&egrave;s importante (et souvent
l'&eacute;dition de liens s'effectue d'une mani&egrave;re
statique). Ce n'est pas une id&eacute;e lumineuse...</p>
<p>Si le programme poss&egrave;de le script <code>configure</code>
g&eacute;n&eacute;r&eacute; par autoconf, vous pouvez modifier les
options de d&eacute;bogage en effectuant un <code>./configure
CFLAGS=</code> ou <code>./configure CFLAGS=-O2</code>. Sinon, vous
pouvez aller modifier le Makefile. Bien s&ucirc;r, si vous utilisez
le format ELF, l'&eacute;dition de liens sera effectu&eacute;e de
mani&egrave;re dynamique m&ecirc;me avec l'option <code>-g</code>.
Dans ce cas, vous pouvez effectuer un strip sur
l'ex&eacute;cutable.</p>
<h3><a name="index.64"></a> Programmes disponibles</h3>
<p>Beaucoup de gens utilisent <b>gdb</b>, que vous pouvez
r&eacute;cup&eacute;rer sur le site <a href=
"ftp://prep.ai.mit.edu/pub/gnu">prep.ai.mit.edu</a>, sous une forme
binaire sur <a href=
"ftp://tsx-11.mit.edu/pub/linux/packages/GCC">tsx-11</a> ou sur
sunsite. <b>xxgdb</b> est une surcouche X de gdb (c.a.d. que vous
avez besoin de gdb pour utiliser xxgdb). Les sources peuvent
&ecirc;tre r&eacute;cup&eacute;r&eacute;s sur <a href=
"ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz">ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz</a></p>
<p>Il existe &eacute;galement le d&eacute;bogueur <b>UPS</b> qui a
&eacute;t&eacute; port&eacute; par Rick Sladkey. Il fonctionne sous
X &eacute;galement, mais &agrave; la diff&eacute;rence d'xxgdb, ce
n'est qu'une surcouche X pour un d&eacute;bogueur en mode en texte.
Il poss&egrave;de certaines caract&eacute;ristiques tr&egrave;s
int&eacute;ressantes et si vous utilisez beaucoup ce genre
d'outils, vous l'essayerez s&ucirc;rement. Les patches ainsi que
des versions pr&eacute;compil&eacute;es pour Linux peuvent
&ecirc;tre trouv&eacute;es sur <a href=
"ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/">ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/</a>,
et les sources peuvent &ecirc;tre r&eacute;cup&eacute;r&eacute;s
sur <a href=
"ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z">ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z</a>.</p>
<p>Un autre outil que vous pouvez trouver utile pour
d&eacute;boguer est &laquo; <b>strace</b> &raquo; , qui affiche les
appels syst&egrave;mes que le processus lance. Il poss&egrave;de
d'autres caract&eacute;ristiques telles que donner les chemins
d'acc&egrave;s o&ugrave; ont &eacute;t&eacute; compil&eacute;s les
binaires, donner les temps pass&eacute;s dans chacun des appels
syst&egrave;mes, et il vous permet &eacute;galement de
conna&icirc;tre les r&eacute;sultats des appels. La derni&egrave;re
version de strace (actuellement la version 3.0.8) peut &ecirc;tre
trouv&eacute;e sur <a href=
"ftp://ftp.std.com/pub/jrs/">ftp://ftp.std.com/pub/jrs/</a>.</p>
<h3>Programmes en t&acirc;che de fond (d&eacute;mon)</h3>
<p>Les d&eacute;mons lancent typiquement un <code>fork()</code>
d&egrave;s leur lancement et terminent donc le p&egrave;re. Cela
fait une session de d&eacute;boguage tr&egrave;s courte.</p>
<p>La mani&egrave;re la plus simple de r&eacute;soudre ce
probl&egrave;me est de poser un point d'arr&ecirc;t sur
<code>fork</code>, et lorsque le programme s'arr&ecirc;te, forcer
le retour &agrave; 0.</p>
<blockquote>
<pre>
<code>(gdb) list 
1       #include &lt;stdio.h&gt;
2
3       main()
4       {
5         if(fork()==0) printf("child\n");
6         else printf("parent\n");
7       }
(gdb) break fork
Breakpoint 1 at 0x80003b8
(gdb) run
Starting program: /home/dan/src/hello/./fork 
Breakpoint 1 at 0x400177c4

Breakpoint 1, 0x400177c4 in fork ()
(gdb) return 0
Make selected stack frame return now? (y or n) y
#0  0x80004a8 in main ()
    at fork.c:5
5         if(fork()==0) printf("child\n");
(gdb) next
Single stepping until exit from function fork, 
which has no line number information.
child
7       }
</code>
</pre></blockquote>
<h3>Fichiers core</h3>
<p>Lorsque Linux se lance, il n'est g&eacute;n&eacute;ralement pas
configur&eacute; pour produire des fichiers core. Si vous les
voulez vous devez utiliser votre shell pour &ccedil;a en faisant
sous csh (ou tcsh) :</p>
<blockquote>
<pre>
<code>% limit core unlimited
</code>
</pre></blockquote>
avec sh, bash, zsh, pdksh, utilisez
<blockquote>
<pre>
<code>$ ulimit -c unlimited
</code>
</pre></blockquote>
<p>Si vous voulez pousser le vice &agrave; nommer votre fichier
core (par exemple si vous utilisez un d&eacute;bogueur
bogu&eacute;... ce qui est un comble) vous pouvez simplement
modifier le noyau. Editez les fichiers
<code>fs/binfmt_aout.c</code> et <code>fs/binfmt_elf.c</code> (dans
les nouveaux noyaux, vous devrez chercher ailleurs) :</p>
<blockquote>
<pre>
<code>        memcpy(corefile,"core.",5);
#if 0
        memcpy(corefile+5,current-&gt;comm,sizeof(current-&gt;comm));
#else
        corefile[4] = '\0';
#endif
</code>
</pre></blockquote>
<p>et changez les <code>0</code> par des <code>1</code>.</p>
<h2><a name="ss5.3">5.3 Caract&eacute;ristiques du
programme</a></h2>
<p>Il est possible d'examiner un peu le programme pour savoir quels
sont les appels de fonctions qui sont effectu&eacute;s le plus
souvent ou bien qui prennent du temps. C'est une bonne
mani&egrave;re d'optimiser le code en d&eacute;terminant l&agrave;
o&ugrave; l'on passe le plus de temps. Vous devez compiler tous les
objets avec l'option <code>-p</code>, et pour mettre en forme la
sortie &eacute;cran, vous aurez besoin du programme
<code>gprof</code> (situ&eacute; dans les <code>binutils</code>).
Consultez les pages de manuel <code>gprof</code> pour plus de
d&eacute;tails.</p>
<h2><a name="s6">6. Edition de liens</a></h2>
<p>Entre les deux formats de binaires incompatibles,
biblioth&egrave;ques statiques et dynamiques, on peut comparer
l'op&eacute;ration d'&eacute;dition de lien en fait &agrave; un jeu
ou l'on se demanderait qu'est-ce qui se passe lorsque je lance le
programme ? Cette section n'est pas vraiment simple...</p>
<p>Pour dissiper la confusion qui r&egrave;gne, nous allons nous
baser sur ce qui se passe lors d'ex&eacute;cution d'un programme,
avec le chargement dynamique. Vous verrez &eacute;galement la
description de l'&eacute;dition de liens dynamiques, mais plus
tard. Cette section est d&eacute;di&eacute;e &agrave;
l'&eacute;dition de liens qui intervient &agrave; la fin de la
compilation.</p>
<h2><a name="ss6.1">6.1 Biblioth&egrave;ques partag&eacute;es
contre biblioth&egrave;ques statiques</a></h2>
<p>La derni&egrave;re phase de construction d'un programme est de
r&eacute;aliser l'&eacute;dition de liens, ce qui consiste &agrave;
assembler tous les morceaux du programme et de chercher ceux qui
sont manquants. Bien &eacute;videment, beaucoup de programmes
r&eacute;alisent les m&ecirc;mes op&eacute;rations comme ouvrir des
fichiers par exemple, et ces pi&egrave;ces qui r&eacute;alisent ce
genre d'op&eacute;rations sont fournies sous la forme de
biblioth&egrave;ques. Sous Linux, ces biblioth&egrave;ques peuvent
&ecirc;tre trouv&eacute;es dans les r&eacute;pertoires
<code>/lib</code> et<code>/usr/lib/</code> entre autres.</p>
<p><a name="index.65"></a> <a name="index.66"></a></p>
<p>Lorsque vous utilisez une biblioth&egrave;que statique,
l'&eacute;diteur de liens cherche le code dont votre programme a
besoin et en effectue une copie dans le programme physique
g&eacute;n&eacute;r&eacute;. Pour les biblioth&egrave;ques
partag&eacute;es, c'est le contraire : l'&eacute;diteur de liens
laisse du code qui lors du lancement du programme chargera
automatiquement la biblioth&egrave;que. Il est &eacute;vident que
ces biblioth&egrave;ques permettent d'obtenir un ex&eacute;cutable
plus petit; elles permettent &eacute;galement d'utiliser moins de
m&eacute;moire et moins de place disque. Linux effectue par
d&eacute;faut une &eacute;dition de liens dynamique s'il peut
trouver les biblioth&egrave;ques de ce type sinon, il effectue une
&eacute;dition de liens statique. Si vous obtenez des binaires
statiques alors que vous les voulez dynamiques v&eacute;rifiez que
les biblioth&egrave;ques existent (<code>*.sa</code> pour le format
a.out, et <code>*.so</code> pour le format ELF) et que vous
poss&eacute;dez les droits suffisants pour y acc&eacute;der
(lecture).</p>
<p>Sous Linux, les biblioth&egrave;ques statiques ont pour nom
<code>libnom.a</code>, alors que les biblioth&egrave;ques
dynamiques sont appel&eacute;es <code>libnnom.so.x.y.z</code>
o&ugrave; <code>x.y.z</code> repr&eacute;sente le num&eacute;ro de
version. Les biblioth&egrave;ques dynamiques ont souvent des liens
logiques qui pointent dessus, et qui sont tr&egrave;s importants.
Normalement, les biblioth&egrave;ques standards sont livr&eacute;es
sous la double forme dynamique et statique.</p>
<p>Vous pouvez savoir de quelles biblioth&egrave;ques dynamiques un
programme a besoin en utilisant la commande <code>ldd</code>
(<em>List Dynamic Dependencies</em>)</p>
<blockquote>
<pre>
<code>$ ldd /usr/bin/lynx
        libncurses.so.1 =&gt; /usr/lib/libncurses.so.1.9.6
        libc.so.5 =&gt; /lib/libc.so.5.2.18
</code>
</pre></blockquote>
<p>Cela indique sur mon syst&egrave;me que l'outil
<code>lynx</code> (outil WWW) a besoin des biblioth&egrave;ques
dynamiques <code>libc.so.5</code> (la biblioth&egrave;que C) et de
<code>libncurses.so.1</code> (n&eacute;cessaire pour le
contr&ocirc;le du terminal). Si un programme ne poss&egrave;de pas
de d&eacute;pendances, <code>ldd</code> indiquera `<em>statically
linked</em>' (&eacute;dition de liens statique).</p>
<h2><a name="index.69"></a> <a name="index.68"></a> <a name=
"index.67"></a> <a name="ss6.2">6.2 A la recherche des fonctions...
ou dans quelle biblioth&egrave;que se trouve la fonction
<code>sin()</code> ?')</a></h2>
<p><code>nm</code> <em>nomdebiblioth&egrave;que</em> vous donne
tous les symboles r&eacute;f&eacute;renc&eacute;s dans la
biblioth&egrave;que. Cela fonctionne que cela soit du code statique
ou dynamique. Supposez que vous vouliez savoir o&ugrave; se trouve
d&eacute;finie la fonction <code>tcgetattr()</code> :</p>
<blockquote>
<pre>
<code>$ nm libncurses.so.1 |grep tcget
         U tcgetattr
</code>
</pre></blockquote>
<p>La lettre <code>U</code> vous indique que c'est ind&eacute;fini
(<em>Undefined</em>) --- cela indique que la biblioth&egrave;que
ncurses l'utilise mais ne la d&eacute;finit pas. Vous pouvez
&eacute;galement faire :</p>
<blockquote>
<pre>
<code>$ nm libc.so.5 | grep tcget
00010fe8 T __tcgetattr
00010fe8 W tcgetattr
00068718 T tcgetpgrp
</code>
</pre></blockquote>
<p>La lettre `<code>W</code>' indique que le symbole est
d&eacute;fini mais de telle mani&egrave;re qu'il peut &ecirc;tre
surcharg&eacute; par une autre d&eacute;finition de la fonction
dans une autre biblioth&egrave;que (W pour <em>weak</em> : faible).
Une d&eacute;finition normale est marqu&eacute;e par la lettre
`<code>T</code>' (comme pour <code>tcgetpgrp</code>).</p>
<p><a name="index.70"></a></p>
<p>La r&eacute;ponse &agrave; la question situ&eacute;e dans le
titre est <code>libm.(so|a)</code>. Toutes les fonctions
d&eacute;finies dans le fichier d'en-t&ecirc;te
<code>&lt;math.h&gt;</code> sont impl&eacute;ment&eacute;es dans la
biblioth&egrave;que math&eacute;matique donc vous devrez effectuer
l'&eacute;dition de liens gr&acirc;ce &agrave;
<code>-lm</code>.</p>
<h2><a name="ss6.3">6.3 Trouver les fichiers</a></h2>
<p>Supposons que vous ayez le message d'erreur suivant de la part
de l'&eacute;diteur de liens :</p>
<p><code>ld: Output file requires shared library
`libfoo.so.1`</code></p>
<p>La strat&eacute;gie de recherche de fichiers de ld ou de ses
copains diff&egrave;re de la version utilis&eacute;e, mais vous
pouvez &ecirc;tre s&ucirc;r que les fichiers situ&eacute;s dans le
r&eacute;pertoire <code>/usr/lib</code> seront trouv&eacute;s. Si
vous d&eacute;sirez que des fichiers situ&eacute;s &agrave; un
endroit diff&eacute;rent soient trouv&eacute;s, il est
pr&eacute;f&eacute;rable d'ajouter l'option <code>-L</code>
&agrave; gcc ou ld.</p>
<p>Si cela ne vous aide pas clairement, v&eacute;rifiez que vous
avez le bon fichier &agrave; l'endroit sp&eacute;cifi&eacute;. Pour
un syst&egrave;me a.out, effectuer l'&eacute;dition de liens avec
<code>-ltruc</code> implique que ld recherche les
biblioth&egrave;ques <code>libtruc.sa</code> (biblioth&egrave;ques
partag&eacute;es), et si elle n'existe pas, il recherche
<code>libtruc.a</code> (statique). Pour le format ELF, il cherche
<code>libtruc.so</code> puis <code>libtruc.a</code>.
<code>libtruc.so</code> est g&eacute;n&eacute;ralement un lien
symbolique vers <code>libtruc.so.x</code>.</p>
<h2><a name="ss6.4">6.4 Compiler votre propre
biblioth&egrave;que</a></h2>
<h3>Num&eacute;ro de la version</h3>
<p>Comme tout programme, les biblioth&egrave;ques ont tendance
&agrave; avoir quelques bogues qui sont corrig&eacute;s au fur et
&agrave; mesure. De nouvelles fonctionnalit&eacute;s sont
ajout&eacute;es et qui peuvent changer l'effet de celles qui
existent ou bien certaines anciennes peuvent &ecirc;tres
supprim&eacute;es. Cela peut &ecirc;tre un probl&egrave;me pour les
programmes qui les utilisent.</p>
<p>Donc, nous introduisons la notion de num&eacute;ro de version.
Nous r&eacute;pertorions les modifications effectu&eacute;es dans
la biblioth&egrave;ques comme &eacute;tant soit mineures soit
majeures. Cela signifie qu'une modification mineure ne peut pas
modifier le fonctionnement d'un programme (en bref, il continue
&agrave; fonctionner comme avant). Vous pouvez identifier le
num&eacute;ro de la version de la biblioth&egrave;que en regardant
son nom (en fait c'est un mensonge pour les biblioth&egrave;ques
ELF... mais continuez &agrave; faire comme si !) :
<code>libtruc.so.1.2</code> a pour version majeure 1 et mineure 2.
Le num&eacute;ro de version mineur peut &ecirc;tre plus ou moins
&eacute;lev&eacute; --- la biblioth&egrave;que C met un
num&eacute;ro de patch, ce qui produit un nom tel que
<code>libc.so.5.2.18</code>, et c'est &eacute;galement courant d'y
trouver des lettres ou des blancs soulign&eacute;s ou tout autre
caract&egrave;re ASCII affichable.</p>
<p>Une des principales diff&eacute;rences entre les formats ELF et
a.out se trouve dans la mani&egrave;re de construire la
biblioth&egrave;que partag&eacute;e. Nous traiterons les
biblioth&egrave;ques partag&eacute;es en premier car c'est plus
simple.</p>
<h3><a name="index.71"></a> ELF, qu'est-ce que c'est ?</h3>
<p>ELF (<em>Executable and Linking Format</em>) est format de
binaire initialement con&ccedil;u et d&eacute;velopp&eacute; par
USL (<em>UNIX System Laboratories</em>) et utilis&eacute; dans les
syst&egrave;mes Solaris et System R4. En raison de sa
facilit&eacute; d'utilisation par rapport &agrave; l'ancien format
dit a.out qu'utilisait Linux, les d&eacute;veloppeurs de GCC et de
la biblioth&egrave;que C ont d&eacute;cid&eacute; l'ann&eacute;e
derni&egrave;re de basculer tout le syst&egrave;me sous le format
ELF. ELF est d&eacute;sormais le format binaire standard sous
Linux.</p>
<h3>ELF, le retour !</h3>
<p>Ce paragraphe provient du groupe
'/news-archives/comp.sys.sun.misc'.</p>
<blockquote>ELF (<em>Executable Linking Format</em>) est le &laquo;
nouveau et plus performant &raquo; format de fichier introduit dans
SVR4. ELF est beaucoup plus puissant que le sacro-saint format
COFF, dans le sens o&ugrave; il est extensible. ELF voit un fichier
objet comme une longue liste de sections (plut&ocirc;t qu'un
tableau de taille fixe d'&eacute;l&eacute;ments). Ces sections,
&agrave; la diff&eacute;rence de COFF ne se trouvent pas &agrave;
un endroit constant et ne sont pas dans un ordre particulier, etc.
Les utilisateurs peuvent ajouter une nouvelle section &agrave; ces
fichiers objets s'il d&eacute;sirent y mettre de nouvelles
donn&eacute;es. ELS poss&egrave;de un format de d&eacute;bogage
plus puissant appel&eacute; DWARF (<em>Debugging With Attribute
Record Format</em>) - par encore enti&egrave;rement
g&eacute;r&eacute; par Linux (mais on y travaille !). Une liste
cha&icirc;n&eacute;e de &laquo; DWARF DIEs &raquo; (ou
<em>Debugging Information Entries</em> - NdT... le lecteur aura
s&ucirc;rement not&eacute; le jeu de mot assez noir : dwarf = nain;
dies = morts) forment la section <em>.debug</em> dans ELF. Au lieu
d'avoir une liste de petits enregistrements d'information de taille
fixes, les DWARF DIEs contiennent chacun une longue liste complexe
d'attributs et sont &eacute;crits sous la forme d'un arbre de
donn&eacute;es. Les DIEs peuvent contenir une plus grande
quantit&eacute; d'information que la section <em>.debug</em> du
format COFF ne le pouvait (un peu comme les graphes
d'h&eacute;ritages du C++).</blockquote>
<blockquote>Les fichiers ELF sont accessibles gr&acirc;ce &agrave;
la biblioth&egrave;que d'acc&egrave;s de SVR4 (Solaris 2.0
peut-&ecirc;tre ?), qui fournit une interface simple et rapide aux
parties les plus complexes d'ELF. Une des aubaines que permet la
biblioth&egrave;que d'acc&egrave;s ELF est que vous n'avez jamais
besoin de conna&icirc;tre les m&eacute;andres du format ELF. Pour
acc&eacute;der &agrave; un fichier Unix, on utilise un Elf *,
retourn&eacute; par un appel &agrave; elf_open(). Ensuite, vous
effectuez des appels &agrave; elf_foobar() pour obtenir les
diff&eacute;rents composants au lieu d'avoir &agrave; triturer le
fichier physique sur le disque (chose que beaucoup d'utilisateurs
de COFF ont fait...).</blockquote>
<p>Les arguments pour ou contre ELF, et les probl&egrave;mes
li&eacute;s &agrave; la mise &agrave; jour d'un syst&egrave;me
a.out vers un syst&egrave;me ELF sont d&eacute;crits dans le
ELF-HOWTO et je ne veux pas effectuer de copier coller ici (NdT: ce
HowTo est &eacute;galement traduit en fran&ccedil;ais). Ce HowTo se
trouve au m&ecirc;me endroit que les autres.</p>
<h3>Les biblioth&egrave;que partag&eacute;es ELF</h3>
<p>Pour construire <code>libtruc.so</code> comme une
biblioth&egrave;que dynamique, il suffit de suivre les
&eacute;tapes suivantes :</p>
<blockquote>
<pre>
<code>$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libtruc.so.1 -o libtruc.so.1.0 *.o
$ ln -s libtruc.so.1.0 libtruc.so.1
$ ln -s libtruc.so.1 libtruc.so
$ LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH
</code>
</pre></blockquote>
<p>Cela va g&eacute;n&eacute;rer une biblioth&egrave;que
partag&eacute;e appel&eacute;e <code>libtruc.so.1.0</code>, les
liens appropri&eacute;s pour ld (<code>libtruc.so</code>) et le
chargeur dynamique (<code>libtruc.so.1</code>) pour le trouver.
Pour tester, nous ajoutons le r&eacute;pertoire actuel &agrave; la
variable d'environnement <code>LD_LIBRARY_PATH</code>.</p>
<p><a name="index.72"></a></p>
<p>Lorsque vous &ecirc;tes satisfait et que la biblioth&egrave;que
fonctionne, vous n'avez plus qu'&agrave; la d&eacute;placer dans le
r&eacute;pertoire par exemple, <code>/usr/local/lib</code>, et de
recr&eacute;er les liens appropri&eacute;s. Le lien de
<code>libtruc.so.1</code> sur <code>libtruc.so.1.0</code> est
enregistr&eacute; par <code>ldconfig</code>, qui sur bon nombre de
syst&egrave;mes est lanc&eacute; lors du processus
d'amor&ccedil;age. Le lien <code>libfoo.so</code> doit &ecirc;tre
mis &agrave; jour &agrave; la main. Si vous faites attention lors
de la mise &agrave; jour de la biblioth&egrave;que la chose la plus
simple &agrave; r&eacute;aliser est de cr&eacute;er le lien
<code>libfoo.so -&gt; libfoo.so.1</code>, pour que ldconfig
conserve les liens actuels. Si vous ne faites pas cela, vous aurez
des probl&egrave;mes plus tard. Ne me dites pas que l'on ne vous a
pas pr&eacute;venu !</p>
<blockquote>
<pre>
<code>$ /bin/su
# cp libtruc.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libtruc.so.1 libtruc.so )
</code>
</pre></blockquote>
<h3><a name="index.74"></a> <a name="index.73"></a> Les
num&eacute;ros de version, les noms et les liens</h3>
<p>Chaque biblioth&egrave;que poss&egrave;de un nom propre
(<em>soname</em>). Lorsque l'&eacute;diteur de liens en trouve un
qui correspond &agrave; un nom cherch&eacute;, il enregistre le nom
de la biblioth&egrave;que dans le code binaire au lieu d'y mettre
le nom du fichier de la biblioth&egrave;que. Lors de
l'ex&eacute;cution, le chargeur dynamique va alors chercher un
fichier ayant pour nom le nom propre de la biblioth&egrave;que, et
pas le nom du fichier de la biblioth&egrave;que. Par exemple, une
biblioth&egrave;que ayant pour nom <code>libtruc.so</code> peut
avoir comme nom propre <code>libbar.so</code>, et tous les
programmes li&eacute;s avec vont alors chercher
<code>libbar.so</code> lors de leur ex&eacute;cution.</p>
<p>Cela semble &ecirc;tre une nuance un peu pointilleuse mais c'est
la clef de la compr&eacute;hension de la coexistence de plusieurs
versions diff&eacute;rentes de la m&ecirc;me biblioth&egrave;que
sur le m&ecirc;me syst&egrave;me. On a pour habitude sous Linux
d'appeler une biblioth&egrave;que <code>libtruc.so.1.2</code> par
exemple, et de lui donner comme nom propre
<code>libtruc.so.1</code>. Si cette biblioth&egrave;que est
rajout&eacute;e dans un r&eacute;pertoire standard (par exemple
dans <code>/usr/lib</code>), le programme <code>ldconfig</code> va
cr&eacute;er un lien symbolique entre <code>libtruc.so.1 -&gt;
libtruc.so.1.2</code> pour que l'image appropri&eacute;e soit
trouv&eacute;e lors de l'ex&eacute;cution. Vous aurez
&eacute;galement besoin d'un lien symbolique <code>libtruc.so -&gt;
libtruc.so.1</code> pour que ld trouve le nom propre lors de
l'&eacute;dition de liens.</p>
<p>Donc, lorsque vous corrigez des erreurs dans la
biblioth&egrave;que ou bien lorsque vous ajoutez de nouvelles
fonctions (en fait, pour toute modification qui n'affecte pas
l'ex&eacute;cution des programmes d&eacute;j&agrave; existants),
vous reconstruisez la biblioth&egrave;que, conservez le nom propre
tel qu'il &eacute;tait et changez le nom du fichier. Lorsque vous
effectuez des modifications que peuvent modifier le
d&eacute;roulement des programmes existants, vous pouvez tout
simplement incr&eacute;menter le nombre situ&eacute; dans le nom
propre --- dans ce cas, appelez la nouvelle version de la
biblioth&egrave;que <code>libtruc.so.2.0</code>, et donnez-lui
comme nom propre <code>libtruc.so.2</code>. Maintenant, faites
pointer le lien de <code>libfoo.so</code> vers la nouvelle version
et tout est bien dans le meilleur des mondes !</p>
<p>Il est utile de remarquer que vous n'&ecirc;tes pas
oblig&eacute; de nommer les biblioth&egrave;ques de cette
mani&egrave;re, mais c'est une bonne convention. Elf vous donne une
certaine libert&eacute; pour nommer des biblioth&egrave;ques tant
et si bien que cela peut perturber certains utilisateurs, mais cela
ne veut pas dire que vous &ecirc;tes oblig&eacute; de le faire.</p>
<p>R&eacute;sum&eacute; : supposons que choisissiez d'adopter la
m&eacute;thode traditionnelle avec les mises &agrave; jour majeures
qui peuvent ne pas &ecirc;tre compatibles avec les versions
pr&eacute;c&eacute;dentes et les mises &agrave; jour mineures qui
ne posent pas ce probl&egrave;me. Il suffit de cr&eacute;er la
biblioth&egrave;que de cette mani&egrave;re :</p>
<blockquote>
<pre>
<code>gcc -shared -Wl,-soname,libtruc.so.majeur -o libtruc.so.majeur.mineur
</code>
</pre></blockquote>
et tout devrait &ecirc;tre parfait !
<h3>a.out. Le bon vieux format</h3>
<p>La facilit&eacute; de construire des biblioth&egrave;que
partag&eacute;es est la raison principale de passer &agrave; ELF.
Ceci dit, il est toujours possible de cr&eacute;er des
biblioth&egrave;ques dynamiques au format a.out.
R&eacute;cup&eacute;rez le fichier archive <a href=
"ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz">
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz</a>
et lisez les 20 pages de documentation que vous trouverez dedans
apr&egrave;s l'avoir d&eacute;sarchiv&eacute;. Je n'aime pas avoir
l'air d'&ecirc;tre aussi partisan, mais il est clair que je n'ai
jamais aim&eacute; ce format :-).</p>
<h3><a name="index.76"></a> <a name="index.75"></a> ZMAGIC contre
QMAGIC</h3>
<p>QMAGIC est le format des ex&eacute;cutables qui ressemble un peu
aux vieux binaires a.out (&eacute;galement connu comme ZMAGIC),
mais qui laisse la premi&egrave;re page libre. Cela permet plus
facilement de r&eacute;cup&eacute;rer les adresses non
affect&eacute;es (comme NULL) dans l'intervalle 0-4096 (NdT : Linux
utilise des pages de 4Ko).</p>
<p>Les &eacute;diteurs de liens d&eacute;suets ne g&egrave;rent que
le format ZMAGIC, ceux un peu moins rustiques g&egrave;rent les
deux, et les plus r&eacute;cents uniquement le QMAGIC. Cela importe
peu car le noyau g&egrave;re les deux types.</p>
<p>La commande <code>file</code> est capable d'identifier si un
programme est de type QMAGIC.</p>
<h3>Gestion des fichiers</h3>
<p>Une biblioth&egrave;que dynamique a.out (DLL) est
compos&eacute;e de deux fichiers et d'un lien symbolique. Supposons
que l'on utilise la biblioth&egrave;que <em>truc</em>, les fichiers
seraient les suivants : <code>libtruc.sa</code> et
<code>libtruc.so.1.2</code>; et le lien symbolique aurait pour nom
<code>libtruc.so.1</code> et pointerait sur le dernier des
fichiers. Mais &agrave; quoi servent-ils ?</p>
<p>Lors de la compilation, <code>ld</code> cherche
<code>libtruc.sa</code>. C'est le fichier de description de la
biblioth&egrave;que : il contient toutes les donn&eacute;es
export&eacute;es et les pointeurs vers les fonctions
n&eacute;cessaires pour l'&eacute;dition de liens.</p>
<p>Lors de l'ex&eacute;cution, le chargeur dynamique cherche
<code>libtruc.so.1</code>. C'est un lien symbolique plut&ocirc;t
qu'un r&eacute;el fichier pour que les biblioth&egrave;ques
puissent &ecirc;tre mise &agrave; jour sans avoir &agrave; casser
les applications qui utilisent la biblioth&egrave;que. Apr&egrave;s
la mise &agrave; jour, disons que l'on est pass&eacute; &agrave; la
version <code>libfoo.so.1.3</code>, le lancement de ldconfig va
positionner le lien. Comme cette op&eacute;ration est atomique,
aucune application fonctionnant n'aura de probl&egrave;me.</p>
<p>Les biblioth&egrave;ques DLL (Je sais que c'est une
tautologie... mais pardon !) semblent &ecirc;tre tr&egrave;s
souvent plus importantes que leur &eacute;quivalent statique. En
fait, c'est qu'elles r&eacute;servent de la place pour les
extensions ult&eacute;rieures sous la simple forme de trous qui
sont fait de telle mani&egrave;re qu'ils n'occupent pas de place
disque (NdT : un peu comme les fichiers <code>core</code>).
Toutefois, un simple appel &agrave; <code>cp</code> ou &agrave;
<code>makehole</code> les remplira... Vous pouvez effectuer une
op&eacute;ration de <code>strip</code> apr&egrave;s la construction
de la biblioth&egrave;que, comme les adresses sont &agrave; des
endroits fixes. <b>Ne faites pas la m&ecirc;me op&eacute;ration
avec les biblioth&egrave;ques ELF !</b></p>
<h3>&laquo; libc-lite &raquo; ?</h3>
<p>Une &laquo; libc-lite &raquo; (contraction de <em>libc</em> et
<em>little</em>) est une version &eacute;pur&eacute;e et
r&eacute;duite de la biblioth&egrave;que libc construite de telle
mani&egrave;re qu'elle puisse tenir sur une disquette avec un
certain nombre d'outil Unix. Elle n'inclut pas curses, dbm,
termcap, ... Si votre <code>/lib/libc.so.4</code> est li&eacute;e
avec une biblioth&egrave;que de ce genre il est tr&egrave;s
fortement conseill&eacute; de la remplacer avec une version
compl&egrave;te.</p>
<h3>Edition de liens : probl&egrave;me courants</h3>
<p>Envoyez-les moi !</p>
<dl>
<dt><b>Des programmes statiques lorsque vous les voulez
partag&eacute;s</b></dt>
<dd>
<p><a name="index.77"></a> <a name="index.78"></a></p>
<p>V&eacute;rifiez que vous avez les bons liens pour que
<code>ld</code> puisse trouver les biblioth&egrave;ques
partag&eacute;es. Pour ELF cela veut dire que
<code>libtruc.so</code> est un lien symbolique sur son image, pour
a.out un fichier <code>libtruc.sa</code>. Beaucoup de personnes ont
eu ce probl&egrave;me apr&egrave;s &ecirc;tre pass&eacute;s des
outils ELF 2.5 &agrave; 2.6 (<code>binutils</code>) --- la
derni&egrave;re version effectue une recherche plus intelligente
pour les biblioth&egrave;ques dynamiques et donc ils n'avaient pas
cr&eacute;&eacute; tous les liens symboliques n&eacute;cessaires.
Cette caract&eacute;ristique avait &eacute;t&eacute;
supprim&eacute;e pour des raisons de compatibilit&eacute; avec
d'autres architectures et parce qu'assez souvent cela ne marchait
pas bien. En bref, cela posait plus de probl&egrave;mes qu'autre
chose.</p>
</dd>
<dt><b>Le programme `mkimage' n'arrive pas &agrave; trouver
libgcc</b></dt>
<dd>
<p><a name="index.79"></a></p>
<p>Comme <code>libc.so.4.5.x</code> et suivantes, libgcc n'est pas
une biblioth&egrave;que partag&eacute;e. Vous devez remplacer les
`<code>-lgcc</code>' sur la ligne de commande par <code>`gcc
-print-libgcc-file-name`</code> (entre quotes)</p>
<p>Egalement, d&eacute;truisez tous les fichiers situ&eacute;s dans
<code>/usr/lib/libgcc*</code>. C'est important.</p>
</dd>
<dt><b>Le message <code>__NEEDS_SHRLIB_libc_4 multiply
defined</code></b></dt>
<dd>
<p>Sont une cons&eacute;quence du m&ecirc;me probl&egrave;me.</p>
</dd>
<dt><b>Le message ``Assertion failure'' appara&icirc;t lorsque vous
reconstruisez une DLL</b></dt>
<dd>
<p>Ce message &eacute;nigmatique signifie qu'un
&eacute;l&eacute;ment de votre table <em>jump</em> a
d&eacute;pass&eacute; la table car trop peu de place &eacute;tait
r&eacute;serv&eacute;e dans le fichier <code>jump.vars</code> file.
Vous pouvez trouver le(s) coupable(s) en lan&ccedil;ant la commande
<code>getsize</code> fournie dans le paquetage tools-2.17.tar.gz.
La seule solution est de passer &agrave; une nouvelle version
majeure, m&ecirc;me si elle sera incompatible avec les
pr&eacute;c&eacute;dentes.</p>
</dd>
<dt><b><code>ld: output file needs shared library
libc.so.4</code></b></dt>
<dd>
<p>Cela arrive lorsque vous effectuez l'&eacute;dition de liens
avec des biblioth&egrave;ques diff&eacute;rentes de la libc (comme
les biblioth&egrave;ques X) et que vous utilisez l'option
<code>-g</code> sans utiliser l'option <code>-static</code>.</p>
<p>Les fichiers <code>.sa</code> pour les biblioth&egrave;ques
dynamiques ont un symbole non r&eacute;solu
<code>_NEEDS_SHRLIB_libc_4</code> qui est d&eacute;fini dans
<code>libc.sa</code>. Or, lorsque vous utilisez <code>-g</code>
vous faites l'&eacute;dition de liens avec <code>libg.a</code> ou
<code>libc.a</code> et donc ce symbole n'est jamais
d&eacute;fini.</p>
<p>Donc, pour r&eacute;soudre le probl&egrave;me, ajoutez l'option
<code>-static</code> lorsque vous compilez avec l'option
<code>-g</code>, ou n'utilisez pas <code>-g</code> lors de
l'&eacute;dition de liens !</p>
</dd>
</dl>
<h2><a name="s7">7. Chargement dynamique</a></h2>
<p><em>Ce paragraphe est en fait un peu court : il sera
&eacute;tendu dans une version ult&eacute;rieure d&egrave;s que
j'aurai r&eacute;cup&eacute;r&eacute; le HowTo ELF</em></p>
<h2><a name="ss7.1">7.1 Concepts</a></h2>
<p>Linux poss&egrave;de des biblioth&egrave;ques dynamiques, comme
on vous le r&eacute;p&egrave;te depuis le d&eacute;but de ce
document ! Or, il existe un syst&egrave;me pour reporter le travail
d'association des noms des symboles et de leur adresse dans la
biblioth&egrave;que, qui est normalement effectu&eacute; lors de
l'&eacute;dition de liens en l'effectuant lors du chargement du
programme.</p>
<h2><a name="ss7.2">7.2 Messages d'erreur</a></h2>
<p>Envoyez moi vos erreurs ! Je n'en fait pas grand chose sauf les
ins&eacute;rer dans ce paragraphe...</p>
<dl>
<dt><b><code>can't load library: /lib/libxxx.so, Incompatible
version</code></b></dt>
<dd>
<p>(seulement a.out) Cela signifie que vous n'avez pas la version
correcte de la biblioth&egrave;que (num&eacute;ro dit majeur). Non,
il n'est pas possible d'effectuer un lien symbolique sur la
biblioth&egrave;que que vous poss&eacute;dez : si vous avez de la
chance, vous obtiendrez un <em>segmentation fault</em>.
R&eacute;cup&eacute;rez la nouvelle version. Un message un peu
&eacute;quivalent existe &eacute;galement sur les syst&egrave;mes
ELF :</p>
<blockquote>
<pre>
<code>ftp: can't load library 'libreadline.so.2'
</code>
</pre></blockquote>
</dd>
<dt><b><code>warning using incompatible library version
xxx</code></b></dt>
<dd>
<p>(seulement a.out) Vous avez un num&eacute;ro de version de
biblioth&egrave;que (mineur) inf&eacute;rieur &agrave; la version
avec laquelle a &eacute;t&eacute; compil&eacute; le programme. Le
programme fonctionnera s&ucirc;rement. Une mise &agrave; jour est
toutefois conseill&eacute;e.</p>
</dd>
</dl>
<h2><a name="index.81"></a> <a name="index.80"></a> <a name=
"ss7.3">7.3 Contr&ocirc;ler l'op&eacute;ration de chargement
dynamique</a></h2>
<p>Il existe certaines variables d'environnements que le chargeur
dynamique utilise. Beaucoup sont exploit&eacute;es par le programme
<code>ldd</code> lorsqu'il s'agit de particularit&eacute;s de
l'environnement de l'utilisateur, ce qui peuvent &ecirc;tre
positionn&eacute;es pour lancer ldd avec des options
particuli&egrave;res. Voici une description des diff&eacute;rentes
variables d'environnement que vous pouvez rencontrer :</p>
<ul>
<li><code>LD_BIND_NOW</code> --- normalement, les fonctions ne sont
pas cherch&eacute;es dans les biblioth&egrave;ques avant leur
appel. En positionnant cette option, vous v&eacute;rifiez que
toutes les fonctions employ&eacute;es dans votre programmes se
trouvent bien dans la biblioth&egrave;que lors de son chargement,
ce qui ralentit le lancement du programme. C'est utile lorsque vous
voulez tester que l'&eacute;dition de liens s'est parfaitement
d&eacute;roul&eacute;e et que tous les symboles sont bien
associ&eacute;s.</li>
<li><code>LD_PRELOAD</code> peut &ecirc;tre d&eacute;fini avec un
nom de fichier qui contient des fonctions surchargeant des
fonctions d&eacute;j&agrave; existantes. Par exemple, si vous
testez une strat&eacute;gie d'allocation m&eacute;moire, et que
vous voulez remplacer le malloc de la biblioth&egrave;que C par le
v&ocirc;tre situ&eacute; dans un module ayant pour nom
<code>malloc.o</code>, il vous suffit de faire :
<blockquote>
<pre>
<code>$ export LD_PRELOAD=malloc.o
$ test_mon_malloc
</code>
</pre></blockquote>
<code>LD_ELF_PRELOAD</code> et <code>LD_AOUT_PRELOAD</code> sont
similaires, mais leur utilisation est sp&eacute;cifique au type de
binaire utilis&eacute;. Si
<code>LD_</code><em>TypeBinaire</em><code>_PRELOAD</code> et
<code>LD_PRELOAD</code> sont positionn&eacute;s, celui
correspondant le mieux &agrave; la machine est utilis&eacute;.</li>
<li><code>LD_LIBRARY_PATH</code> contient une liste de
r&eacute;pertoires contenant les biblioth&egrave;ques dynamiques.
Cela n'affecte pas l'&eacute;dition de liens : cela n'a qu'un effet
lors de l'ex&eacute;cution. Il faut noter qu'elle est
d&eacute;sactiv&eacute;e pour des programmes qui s'ex&eacute;cutent
avec un setuid ou un setgid. Enfin,
<code>LD_ELF_LIBRARY_PATH</code> et
<code>LD_AOUT_LIBRARY_PATH</code> peuvent &ecirc;tre
utilis&eacute;s pour orienter le mode de compilation du binaire.
<code>LD_LIBRARY_PATH</code> ne devrait pas &ecirc;tre
n&eacute;cessaire en principe : ajoutez les r&eacute;pertoires dans
le fichier <code>/etc/ld.so.conf/</code> et relancez ldconfig.</li>
<li><code>LD_NOWARN</code> s'applique au format a.out uniquement.
Lorsqu'elle est positionn&eacute;e (c.a.d si elle existe par
exemple avec <code>LD_NOWARN=true; export LD_NOWARN</code>) cela
arr&ecirc;te le chargeur du programme m&ecirc;me sur des
avertissements insignifiants (tels que des messages
d'incompatibilit&eacute;s de num&eacute;ros mineurs de
version).</li>
<li><code>LD_WARN</code> s'applique &agrave; ELF uniquement.
Lorsqu'elle est positionn&eacute;e, on transforme le message
habituellement fatal <em>Can't find library</em> en un
avertissement. Ce n'est pas positionn&eacute; par d&eacute;faut
mais c'est important pour un programme comme ldd.</li>
<li><code>LD_TRACE_LOADED_OBJECTS</code> s'applique &agrave; ELF
uniquement, et permet de simuler l'ex&eacute;cution des programmes
comme s'ils l'&eacute;taient par <code>ldd</code> :
<blockquote>
<pre>
<code>$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
        libncurses.so.1 =&gt; /usr/lib/libncurses.so.1.9.6
        libc.so.5 =&gt; /lib/libc.so.5.2.18
</code>
</pre></blockquote>
</li>
</ul>
<h2><a name="index.83"></a> <a name="index.82"></a> <a name=
"ss7.4">7.4 Ecrire des programmes en utilisant le chargement
dynamique</a></h2>
<p>Cela ressemble &eacute;norm&eacute;ment au syst&egrave;me de
chargement dynamique utilis&eacute; sous Solaris 2.x. Ce
syst&egrave;me est d&eacute;crit d'une mani&egrave;re
pr&eacute;cise dans le document expliquant la programmation avec
ELF &eacute;crit par H J Lu et dans la page de manuel
<code>dlopen(3)</code>, qui se trouve dans le paquetage ld.so.
Voici un exemple simple : pensez &agrave; faire l'&eacute;dition de
liens avec <code>-ldl</code></p>
<blockquote>
<pre>
<code>#include &lt;dlfcn.h&gt;
#include &lt;stdio.h&gt;

main()
{
  void *libc;
  void (*printf_call)();

  if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
  {
    printf_call = dlsym(libc,"printf");
    (*printf_call)("Bonjour ! Ha ben ca marche pil poil sous Linux !\n");
  }

}
</code>
</pre></blockquote>
<h2><a name="s8">8. Contacter les d&eacute;veloppeurs</a></h2>
<h2><a name="index.84"></a> <a name="ss8.1">8.1 Annoncer des
bogues</a></h2>
<p>Commencez par mettre en doute le probl&egrave;me. Est-ce
sp&eacute;cifique &agrave; Linux ou bien cela arrive avec gcc mais
sur d'autres plates-formes ? Est-ce sp&eacute;cifique &agrave; la
version du noyau ? A la version de la biblioth&egrave;que C ?
Est-ce que ce probl&egrave;me dispara&icirc;t lorsque vous
effectuez une &eacute;dition de liens statique ? Pouvez-vous
produire un code tr&egrave;s court mettant en &eacute;vidence le
probl&egrave;me ?</p>
<p>Apr&egrave;s avoir r&eacute;pondu apr&egrave;s ces quelques
questions, vous saurez quel programme est &agrave; l'origine du
probl&egrave;me. Pour un probl&egrave;me direct avec GCC, le mieux
est de consulter le fichier d'information livr&eacute; avec : la
proc&eacute;dure pour rapporter un bogue y est
d&eacute;taill&eacute;. Pour un probl&egrave;me avec ld.so, la
biblioth&egrave;que C ou math&eacute;matique, envoyez un courrier
&eacute;lectronique &agrave;
<code>linux-gcc@vger.rutgers.edu</code>. Si possible, donnez un
court exemple mettant en &eacute;vidence le probl&egrave;me ainsi
qu'une courte description indiquant ce que le programme aurait
normalement d&ucirc; faire, et ce qu'il fait en
r&eacute;alit&eacute;.</p>
<h2><a name="ss8.2">8.2 Participer au d&eacute;veloppement</a></h2>
<p>Si vous d&eacute;sirez participer au d&eacute;veloppement de GCC
ou de la biblioth&egrave;que C, la premi&egrave;re chose &agrave;
faire est de rejoindre la liste de diffusion
<code>linux-gcc@vger.rutgers.edu</code>. Si vous d&eacute;sirez
uniquement savoir de quoi &ccedil;a parle, il existe des archives
&agrave; l'adresse <a href=
"http://homer.ncm.com/linux-gcc/">http://homer.ncm.com/linux-gcc/</a>.
Tout d&eacute;pend de ce que vous d&eacute;sirez faire ou apporter
&agrave; ce projet !</p>
<h2><a name="s9">9. Divers</a></h2>
<h2><a name="ss9.1">9.1 Ce document</a></h2>
<p>Ce HowTo est bas&eacute; sur la FAQ de Mitchum DSouza's. Bon
nombre des informations en proviennent. D'une mani&egrave;re
g&eacute;n&eacute;rale, il est fr&eacute;quent de dire une phrase
du genre &laquo; je n'ai pas tout test&eacute; et donc ne me
bl&acirc;mez pas si vous cassez votre disque, votre syst&egrave;me
ou si vous rompez avec votre &eacute;pouse &raquo;.</p>
<p>Le nom des contributeurs &agrave; ce document sont donn&eacute;s
par ordre alphab&eacute;tique : Andrew Tefft, Axel Boldt, Bill
Metzenthen, Bruce Evans, Bruno Haible, Daniel Barlow, Daniel
Quinlan, David Engel, Dirk Hohndel, Eric Youngdale, Fergus
Henderson, H.J. Lu, Jens Schweikhardt, Kai Petzke, Michael
Meissner, Mitchum DSouza, Olaf Flebbe, Paul Gortmaker, Rik Faith,
Steven S. Dick, Tuomas J Lukka, et bien s&ucirc;r Linus Torvalds,
sans qui ce genre d'exercice aurait &eacute;t&eacute; difficile,
voir impossible :-)</p>
<p>Ne soyez pas offens&eacute; si votre nom n'appara&icirc;t pas
dans la liste et que vous ayez contribu&eacute; &agrave; ce
document (sous la forme d'un HowTo ou d'une FAQ). Envoyez-moi un
courrier &eacute;lectronique et j'effectuerai la correction.</p>
<h2><a name="ss9.2">9.2 Traduction</a></h2>
<p>A l'heure ou j'&eacute;cris ces lignes, je ne connais pas de
traduction de ce document. Si vous en r&eacute;alisez une, s'il
vous pla&icirc;t dites-le moi. Je suis disponible pour toute aide
concernant l'explication du texte, je serai tr&egrave;s content d'y
r&eacute;pondre.</p>
<p>Note du traducteur : <b>Cocorico !</b> La version
fran&ccedil;aise est la premi&egrave;re traduction de ce
document.</p>
<h2><a name="ss9.3">9.3 Contacts</a></h2>
<p>Tout contact est le bienvenu. Envoyez-moi un courrier
&eacute;lectronique &agrave; l'adresse suivante : <a href=
"mailto:dan@detached.demon.co.uk">dan@detached.demon.co.uk</a>. Ma
clef publique PGP (ID 5F263625) est disponible sur mes <a href=
"http://ftp.linux.org.uk/~barlow/">pages WWW</a>, Si vous souhaitez
rendre confidentiel certains messages.</p>
<h2><a name="ss9.4">9.4 Copyright</a></h2>
<p>Toutes les remarques appartiennent &agrave; leurs auteurs
respectifs.</p>
<p>Ce document est copyright&eacute; (C) 1996 Daniel Barlow
<code>&lt;dan@detached.demon.co.uk&gt;</code>. Il peut &ecirc;tre
reproduit et distribu&eacute; en partie ou enti&egrave;rement, sur
tout support physique ou &eacute;lectronique, du moment o&ugrave;
ce copyright se trouve sur toute les copies. La redistribution
commerciale est autoris&eacute;e et encourag&eacute;e. Toutefois
l'auteur de ce document doit &ecirc;tre mis au courant de ce genre
de distributions.</p>
<p>Toute traduction, adaptation, ou bien tout travail incorporant
tout document HowTo Linux doit poss&eacute;der ce copyright. De
cette mani&egrave;re, vous ne pouvez pas imposer de restriction
&agrave; la distribution de ce document. Des exceptions peuvent
&ecirc;tre &eacute;ventuellement accord&eacute;es sous certaines
conditions : contactez le coordinateur des HowTo's Linux &agrave;
l'adresse donn&eacute;e ci-dessous.</p>
<p>En r&eacute;sum&eacute;, nous souhaitons voir diffuser
l'information de la mani&egrave;re la plus large qui soit.
Toutefois, nous souhaitons garder la ma&icirc;trise de ces
documents et nous aimerions &ecirc;tre consult&eacute;s avant toute
diffusion des HowTo's.</p>
<p>Si vous avez des questions, vous pouvez contacter Greg Hankins,
le coordinateur des HowTo Linux HOWTO &agrave; l'adresse
&eacute;lectronique suivante :
<code>gregh@sunsite.unc.edu</code></p>
<h2><a name="s10">10. Index</a></h2>
<p>Les entr&eacute;es de cet index sont tri&eacute;es dans l'ordre
alphab&eacute;tique.</p>
<ul>
<li><code>-fwritable-strings</code> <a href="#index.39">39</a>,
<a href="#index.56">56</a></li>
<li>/lib/cpp <a href="#index.16">16</a></li>
<li>a.out <a href="#index.1">1</a></li>
<li><code>ar</code> <a href="#index.10">10</a></li>
<li><code>as</code> <a href="#index.8">8</a></li>
<li>&lt;asm/*.h&gt; <a href="#index.19">19</a></li>
<li><code>atoi()</code> <a href="#index.40">40</a></li>
<li><code>atol()</code> <a href="#index.41">41</a></li>
<li>ex&eacute;cutables trop gros <a href="#index.63">63</a>,
<a href="#index.65">65</a>, <a href="#index.77">77</a></li>
<li>chewing gum <a href="#index.3">3</a></li>
<li><code>cos()</code> <a href="#index.68">68</a></li>
<li>deboguer <a href="#index.59">59</a></li>
<li>divers <a href="#index.72">72</a></li>
<li><code>dlopen()</code> <a href="#index.82">82</a></li>
<li><code>dlsym()</code> <a href="#index.83">83</a></li>
<li>documentation <a href="#index.4">4</a></li>
<li>EINTR <a href="#index.52">52</a></li>
<li>elf <a href="#index.0">0</a>, <a href="#index.71">71</a></li>
<li><code>execl()</code> <a href="#index.57">57</a></li>
<li><code>fcntl</code> <a href="#index.47">47</a></li>
<li><code>FD_CLR</code> <a href="#index.44">44</a></li>
<li><code>FD_ISSET</code> <a href="#index.45">45</a></li>
<li><code>FD_SET</code> <a href="#index.43">43</a></li>
<li><code>FD_ZERO</code> <a href="#index.46">46</a></li>
<li><code>fichier</code> <a href="#index.2">2</a></li>
<li>&lt;float.h&gt; <a href="#index.20">20</a></li>
<li>gcc <a href="#index.6">6</a></li>
<li><code>gcc -fomit-frame-pointer</code> <a href=
"#index.61">61</a></li>
<li><code>gcc -g</code> <a href="#index.60">60</a></li>
<li>gcc -v <a href="#index.14">14</a></li>
<li>gcc, bogues <a href="#index.15">15</a>, <a href=
"#index.28">28</a>, <a href="#index.29">29</a>, <a href=
"#index.84">84</a></li>
<li>gcc, options de compilation <a href="#index.13">13</a>,
<a href="#index.25">25</a>, <a href="#index.26">26</a></li>
<li>gdb <a href="#index.64">64</a></li>
<li>fichiers d'en-t&ecirc;te <a href="#index.17">17</a></li>
<li>appels syst&egrave;mes interrompus <a href=
"#index.51">51</a></li>
<li><code>ld</code> <a href="#index.9">9</a></li>
<li><code>LD_*</code> : variables d'environnement <a href=
"#index.80">80</a></li>
<li>ldd <a href="#index.81">81</a></li>
<li>libc <a href="#index.7">7</a></li>
<li><code>libg.a</code> <a href="#index.62">62</a></li>
<li>libgcc <a href="#index.79">79</a></li>
<li>&lt;limits.h&gt; <a href="#index.21">21</a></li>
<li>lint <a href="#index.58">58</a></li>
<li>&lt;linux/*.h&gt; <a href="#index.18">18</a></li>
<li><code>&lt;math.h&gt;</code> <a href="#index.70">70</a></li>
<li>maths <a href="#index.69">69</a></li>
<li><code>mktemp()</code> <a href="#index.55">55</a></li>
<li>num&eacute;ro de version <a href="#index.12">12</a>, <a href=
"#index.74">74</a></li>
<li>optimisation <a href="#index.27">27</a></li>
<li>pages de manuel <a href="#index.5">5</a></li>
<li>QMAGIC <a href="#index.76">76</a></li>
<li>segmentation fault <a href="#index.30">30</a>, <a href=
"#index.54">54</a></li>
<li>segmentation fault, in GCC <a href="#index.33">33</a></li>
<li>select() <a href="#index.50">50</a></li>
<li><code>SIGBUS</code> <a href="#index.34">34</a></li>
<li><code>SIGEMT</code> <a href="#index.35">35</a></li>
<li><code>SIGIOT</code> <a href="#index.36">36</a></li>
<li>SIGSEGV <a href="#index.31">31</a>, <a href=
"#index.53">53</a></li>
<li>SIGSEGV, in gcc <a href="#index.32">32</a></li>
<li><code>SIGSYS</code> <a href="#index.38">38</a></li>
<li><code>SIGTRAP</code> <a href="#index.37">37</a></li>
<li><code>sin()</code> <a href="#index.67">67</a></li>
<li>soname <a href="#index.73">73</a></li>
<li><code>sprintf()</code> <a href="#index.42">42</a></li>
<li>binaires link&eacute;s statiquement <a href="#index.66">66</a>,
<a href="#index.78">78</a></li>
<li>&lt;stdarg.h&gt; <a href="#index.23">23</a></li>
<li>&lt;stddef.h&gt; <a href="#index.24">24</a></li>
<li><code>strings</code> <a href="#index.11">11</a></li>
<li><code>&lt;sys/time.h&gt;</code> <a href="#index.48">48</a></li>
<li><code>&lt;unistd.h&gt;</code> <a href="#index.49">49</a></li>
<li>&lt;varargs.h&gt; <a href="#index.22">22</a></li>
<li>ZMAGIC <a href="#index.75">75</a></li>
</ul>
</body>
</html>