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 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178
|
The Linux GCC HOWTO
Daniel Barlow (dan@detached.demon.co.uk)
v1.17, 28 Febbraio 1996
Questo documento tratta la configurazione del compilatore C GNU e
delle librerie di sviluppo sotto Linux, e fornisce una panoramica
sulla compilazione, il link, l'esecuzione e la correzione (debug) dei
programmi. La maggior parte del materiale contenuto nel documento
stato preso dal GCC-FAQ di Mitch D'Souza, che sostituisce, o dall'ELF-
HOWTO (per la traduzione in italiano vedi [1]). Quella che state
leggendo la prima versione rilasciata pubblicamente (nonostante il
numero). Ogni feedback benvenuto. Revisione e manutenzione della
traduzione italiana: Andrea Girotto (andrea.girotto@usa.net)
1. Preliminari
1.1. Confronto tra ELF e a.out
Lo sviluppo di Linux si trova attualmente in uno stato di continua
evoluzione. Brevemente, esistono due formati di file binari che Linux
in grado di eseguire, ed a seconda di come stato costruito, un
sistema potrebbe usare uno o l'altro dei due. Leggendo questo HOWTO si
scoprir quale.
Per riconoscere il tipo di un binario possibile utilizzare l'utility
file (ad esempio: file /bin/bash). Per un programma ELF, dar una
risposta contenente ELF; per un programma a.out la risposta sar
qualcosa del tipo Linux/i386.
Le differenze tra ELF e a.out sono descritte ampiamente in questo
documento. ELF il formato pi recente, generalmente ritenuto il
migliore.
1.2. Questioni amministrative
Informazioni riguardo al copyright si trovano alla fine di questo
documento, insieme a dovute avvertenze relative a certe stupide
domande poste su Usenet, che, segnalando problemi inesistenti,
rivelano un'ignoranza del linguaggio C.
1.3. Tipografia
La versione in formato Postscipt, dvi, o html, di questo documento ha
una maggiore variet tipografica rispetto a quella in solo testo. In
particolare, i nomi di file, i comandi, l'output dei comandi e gli
stralci di codice sorgente sono impostati con un carattere tipo
macchina da scrivere, come pure sono state messe in evidenza le
"variabili" ed altre parti che dovevano essere enfatizzate.
Inoltre, presente un utile indice. In dvi o postscript, la
numerazione dell'indice corrisponde a quella dei paragrafi. In HTML si
tratta di numeri assegnati sequenzialmente che rimandano ad altre
parti del testo. Nella versione a solo testo, si tratta solo di
numeri. Si consiglia una versione avanzata piuttosto che quella in
modalit testo.
Negli esempi viene utilizzata la sintassi dell'interprete dei comandi
(shell) Bourne (al posto di quella C). Gli utenti di C-shell potranno
utilizzare il comando:
% setenv FOO bar
al posto di:
$ FOO=bar; export FOO
Se il prompt mostrato # invece di $, il comando indicato
probabilmente funzioner solo se digitato come root. Naturalmente, non
si assumere alcuna responsabilit per qualsiasi cosa accada al sistema
nell'utilizzo di questi esempi.
2. Dove ottenere quello che serve.
2.1. Questo documento.
Questo documento fa parte della serie dei Linux HOWTO, pertanto si pu
ottenere da tutti gli archivi di Linux HOWTO, come
http://sunsite.unc.edu/pub/linux/docs/HOWTO/ (le traduzioni italiane
sono disponibili presso [2]). La versione HTML in inglese pu anche
essere trovata (probabilmente leggermente pi aggiornata) su
http://ftp.linux.org.uk/~barlow/howto/gcc-howto.html (traduzione
italiana [3]).
2.2. Ulteriore documentazione.
La documentazione ufficiale di gcc si trova nella distribuzione
sorgente (si veda sotto) sotto forma di file texinfo, e come file
.info. Se si dispone di una connessione di rete veloce, un cd-rom o
una buona dose di pazienza, possibile eseguirne l'untar e copiare le
parti rilevanti in /usr/info. In caso contrario, possono essere
trovati presso ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/, ma non
necessariamente si tratter della versione pi recente.
Esistono due sorgenti di documentazione per libc. La GNU libc contiene
dei file info che descrivono piuttosto accuratamente la libc Linux,
fatta eccezione per stdio. Inoltre, le pagine di manuale dell'archivio
ftp://sunsite.unc.edu/pub/Linux/docs/ sono state scritte per Linux e
descrivono numerose chiamate di sistema (sezione 2) e funzioni libc
(sezione 3).
2.3. GCC
La distribuzione ufficiale del GCC Linux pu sempre essere trovata in
formato binario (gi compilato) all'indirizzo
ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/. Nel momento in cui
viene scritto questo documento, la versione pi recente la 2.7.2
(gcc-2.7.2.bin.tar.gz).
possibile ottenere la distribuzione sorgente pi recente di GCC
fornita dalla Free Software Foundation dagli archivi
ftp://prep.ai.mit.edu/pub/gnu/. I gestori del GCC Linux hanno reso
molto semplice la compilazione dell'ultima versione - il programma di
configurazione (configure) dovrebbe impostare tutto da solo. Si
verifichi anche l'eventuale presenza di patch da applicare presso:
ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/.
Per compilare qualcosa di non banale (ma anche alcune cose banali)
sar necessario possedere anche quanto descritto nel paragrafo che
segue.
2.4. Libreria C e header file
Quello che si desidera a questo punto dipende da due fattori:
1. se il proprio sistema ELF oppure a.out
2. quale dei due si desidera avere.
Se si sta passando da libc 4 a libc 5, si raccomanda di leggere l'ELF-
HOWTO, rintracciabile pi o meno nello stesso luogo in cui stato
trovato questo documento (traduzione italiana [1]).
Da ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/ sono disponibili:
libc-5.2.18.bin.tar.gz
Immagini di librerie condivise ELF, librerie statiche e file
include per le librerie C e matematiche.
libc-5.2.18.tar.gz
Sorgenti per quanto descritto sopra. Sar necessario anche il
pacchetto .bin. per gli header file. Se si indecisi tra
compilarsi in proprio la libreria C o utilizzare il formato
binario, la scelta migliore consiste nell'usare il codice gi
compilato. Nel caso in cui si desideri il supporto NIS o per le
shadow password di dovr comunque gestirli in prima persona.
libc-4.7.5.bin.tar.gz
Immagini di libreria condivisa a.out e librerie statiche per la
versione 4.7.5 della libreria C e simili. Questo stato
studiato per coesistere con il pacchetto libc 5 sopra
menzionato, ma necessario solo se si desidera continuare a
utilizzare o sviluppare programmi in formato a.out.
2.5.
Strumenti associati (as, ld, ar, strings, ecc.)
Si possono trovare su ftp://tsx-11.mit.edu:/pub/linux/packages/GCC/,
come ogni altra cosa sinora descritta. La versione corrente
binutils-2.6.0.2.bin.tar.gz.
Le binutils sono disponibili unicamente in ELF, la versione corrente
di libc si trova in ELF ed inoltre meglio utilizzare la versione
a.out di libc in congiunzione con una ELF. Lo sviluppo della libreria
C si sta muovendo verso ELF: se non c' un particolare motivo per
l'utilizzo di a.out, si consiglia di fare altrettanto.
3. Installazione e impostazione di GCC
3.1.
Versioni GCC
possibile scoprire quale versione GCC si sta eseguendo digitando gcc
-v alla richiesta dell'interprete comandi. Si tratta di un metodo
piuttosto affidabile anche per scoprire se la propria impostazione
ELF o a.out. Il risultato potrebbe essere:
$ gcc -v
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
gcc version 2.7.2
Le cose da notare sono:
i486
Indica che il gcc stato compilato per un processore 486 -
altre possibilit sono 386 o 586. Tutti i processori possono
eseguire il codice compilato per ciascuna delle altre versioni;
la differenza consiste nell'ottimizzazione che non ha effetti
sulle prestazioni in un 386, ma rende il codice eseguibile
leggermente pi grande.
box
Non affatto importante, potrebbe esserci qualcosa di diverso
(come slackware o debian) o anche nulla (in tal caso, il nome di
directory completa sar i486-linux). Se si esegue personalmente
la compilazione di gcc, possibile impostare questa
caratteristica al momento della compilazione, a fini puramente
estetici.
linux
In alternativa, potrebbe essere linuxelf o linuxaout, il
significato varia a seconda della versione utilizzata, fatto che
potrebbe confondere le idee.
linux
significa ELF se la versione la 2.7.0 o seguente,
altrimenti significa a.out.
linuxaout
significa a.out. stato introdotto quando la definizione di
linux stata modificata da a.out in ELF, in modo che non sia
possibile vedere un gcc linuxaout pi vecchio della versione
2.7.0.
linuxelf
obsoleto. Si tratta generalmente di una versione di gcc
2.6.3 impostata per produrre eseguibili ELF. Si noti che il
gcc 2.6.3 contiene degli errori nella produzione di codice
per ELF - si consiglia un aggiornamento.
2.7.2
numero della versione.
In conclusione, si tratta di gcc 2.7.2 che produce del codice ELF.
3.2. Dov' finito?
Se gcc stato installato senza prestare attenzione, oppure se stato
ottenuto come parte di una distribuzione, potrebbe essere necessario
scoprire dove si trova all'interno del filesystem. Le parti chiave
sono:
/usr/lib/gcc-lib/destinazione/versione/ (e sottodirectory) posto in
cui si trova la maggior parte del compilatore, i programmi
eseguibili che effettuano la compilazione, alcune librerie e file
include specifici per la versione che si sta utilizzando.
/usr/bin/gcc driver del compilatore - la parte che si esegue dalla
riga di comando. Pu essere utilizzato con diverse versioni di gcc,
a patto che siano state installate pi directory di compilatore
(come descritto sopra). Per scoprire la versione predefinita,
digitare gcc -v. Per forzare un'altra versione, digitare gcc -V
versione. Ad esempio:
# gcc -v
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
gcc version 2.7.2
# gcc -V 2.6.3 -v
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.6.3/specs
gcc driver version 2.7.2 executing gcc version 2.6.3
/usr/destinazione/(bin|lib|include)/. Se sono stati installati pi
destinazioni (target) (ad esempio, a.out ed elf, o un cross
compilatore di qualche tipo), le librerie, le binutils (come as, ld
o altri) e gli header file per destinazioni non native possono
essere trovati in questa posizione. Se stato installato un solo
tipo di gcc, diverse parti di esso sono poste o in questa directory
o, alternativamente, in /usr/(bin|lib|include).
/lib/, /usr/lib e altre sono directory di libreria per il sistema
nativo. Sar anche necessaria la directory /lib/cpp per molte
applicazioni (ad esempio X ne fa un grande utilizzo) - possibile
copiarla da /usr/lib/gcc-lib/destinazione/versione/ o creare un
collegamento (link) simbolico.
3.3. Dove si trovano gli header file?
Indipendentemente dalla posizione in cui sono stati installati i
propri, sotto /usr/local/include, esistono tre sorgenti principali
degli header file in Linux:
la maggior parte di /usr/include/ e relative subdirectory sono
sostituiti con il pacchetto binario di libc da H. J. Lu. In tali
posizioni si potrebbero anche trovare file da altri sorgenti
(librerie curses e dbm, ad esempio) specialmente se si sta
utilizzando la distribuzione libc pi recente (che non contiene
curses o dbm, come invece accadeva nelle pi vecchie).
/usr/include/linux e /usr/include/asm (per i file <linux/*.h> e
<asm/*.h>) dovrebbero essere link simbolici alle directory
linux/include/linux e linux/include/asm nella distribuzione
sorgente del kernel. necessario installarli se si pensa di
eseguire lo sviluppo di un qualsiasi programma non banale; non
servono solo per la compilazione del kernel.
Potrebbe essere anche necessario eseguire il make config nelle
directory del kernel dopo aver scaricato i sorgenti. Molti file
dipendono da <linux/autoconf.h> che potrebbe non esistere, e in
alcune versioni di kernel, asm un link simbolico che viene creato
al momento del make config. Pertanto, se si scaricano i sorgenti
del kernel sotto /usr/src/linux:
$ cd /usr/src/linux
$ su
# make config
[rispondere alle domande. A meno che non si abbia intenzione di
proseguire con la compilazione del kernel, la risposta non ha
molta importanza]
# cd /usr/include
# ln -s ../src/linux/include/linux .
# ln -s ../src/linux/include/asm .
File come <float.h>, <limits.h>, <varargs.h>, <stdarg.h> e
<stddef.h> variano a seconda della versione del compilatore,
pertanto si trovano in /usr/lib/gcc-lib/i486-box-
linux/2.7.2/include/ e posizioni simili.
3.4. Compilazione di cross compilatori
3.4.1. Linux come piattaforma di destinazione
Supponendo di aver ottenuto il codice sorgente per gcc, solitamente
sufficiente seguire le istruzioni contenute nel file INSTALL di GCC.
Un comando configure -target=i486-linux -host=XXX sulla piattaforma
XXX seguito da un make dovrebbe funzionare. Si noti che saranno
necessari gli include di Linux, gli include del kernel e sar
necessario eseguire anche la compilazione del cross assembler e del
cross linker dai sorgenti in
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/.
3.4.1.1. Linux come piattaforma sorgente, MSDOS come destinazione
Apparentemente dovrebbe essere possibile utilizzando il pacchetto
"emx" o l'extender "go". Si invita a dare un'occhiata a
ftp://sunsite.unc.edu/pub/Linux/devel/msdos.
L'autore, non ha ancora verificato le funzionalit e pertanto non pu
dare alcuna garanzia in merito.
4. Il porting e la compilazione
4.1. Simboli definiti automaticamente
possibile elencare i simboli definiti automaticamente dalla propria
versione di gcc eseguendolo con l'opzione -v. Ad esempio:
$ echo 'main(){printf("hello world\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__ -
Se si sta scrivendo del codice che utilizza delle caratteristiche
specifiche per Linux, una buona idea includere le parti non
portabili in
#ifdef __linux__
/* ... altro codice ... */
#endif /* linux */
Si utilizzi __linux__ per questo scopo, non semplicemente linux.
Sebbene anche il secondo sia definito, non conforme a POSIX.
4.2. Chiamata del compilatore
La documentazione per le opzioni del compilatore rappresentata dalla
info page di gcc (in Emacs, si utilizzi C-h i quindi si selezioni la
voce 'gcc'). Il proprio distributore potrebbe non aver incluso questa
parte nel sistema, o la versione che si possiede potrebbe essere
vecchia; la cosa migliore da fare in questo caso consiste nello
scaricare l'archivio sorgente gcc da ftp://prep.ai.mit.edu/pub/gnu o
da uno dei suoi siti mirror.
La pagina di manuale gcc (gcc.1) di solito obsoleta. Tentando di
leggerla si trover questo avvertimento.
4.2.1.
Opzioni del compilatore
L'output di gcc pu essere ottimizzato aggiungendo -On alla sua riga
di comando, dove n rappresenta un intero opzionale. I valori
significativi di n, ed il loro esatto effetto, variano a seconda della
versione; tipicamente vanno da 0 (nessuna ottimizzazione) a 2 (molte
ottimizzazioni) a 3 (moltissime ottimizzazioni).
Internamente, gcc le traduce in una serie di opzioni -f e -m.
possibile vedere esattamente quale livello -O si lega a ogni opzione
eseguendo gcc -v -Q (Q un'opzione non documentata). Ad esempio, -O2
sul sistema dell'autore produce questo risultato:
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
L'utilizzo di un livello di ottimizzazione maggiore di quanto previsto
per il proprio compilatore (ad esempio, -O6) avr lo stesso risultato
che utilizzare il livello pi alto che in grado di supportare.
Tuttavia, la distribuzione di codice impostato per la compilazione in
questo modo non una buona idea - se in versioni future saranno
incorporate ulteriori ottimizzazioni, potrebbe accadere che
interrompano il proprio codice.
Gli utenti di gcc dalla versione 2.7.0 fino alla 2.7.2 dovrebbero
notare che esiste un errore in -O2. In particolare, '-fstrenght-
reduction' non funziona. disponibile una patch per risolvere questo
problema, che necessita della ricompilazione del gcc, altrimenti
sufficiente assicurarsi di usare sempre l'opzione -fno-strength-
reduce.
4.2.1.1. Opzioni specifiche per il processore
Esistono altre opzioni -m che non sono attivate da nessun -O, e si
dimostrano utili in molti casi. Le principali sono -m386 e -m486, che
indicano a gcc di favorire rispettivamente 386 o 486. Il codice
compilato con una di queste due opzioni funzioner anche su macchine
dell'altro tipo; il codice 486 pi voluminoso, ma non pi lento se
eseguito su 386.
Attualmente non esiste un'opzione -mpentium o -m586. Linus suggerisce
di utilizzare -m486 -malign-loops=2 -malign-jumps=2 -malign-
functions=2, per ottenere l'ottimizzazione del codice 486 ma senza i
salti necessari per l'allineamento (di cui il pentium non ha bisogno).
Michael Meissner (di Cygnus) dice:
La mia impressione che -mno-strength-reduce produca anche
un codice pi veloce sull'x86 (si noti che non mi sto rifer
endo all'errore relativo all'opzione '-fstrength-reduction':
altra questione). Ci dovuto alla carenza di registri
dell'x86 (ed il metodo di GCC di raggruppare i registri in
registri sparsi piuttosto che in altri registri non aiuta
molto). 'strenght-reduce' ha come effetto l'utilizzo di reg
istri addizionali per sostituire moltiplicazioni con
addizioni. Sospetto anche che -fcaller-saves possa causare
una perdita di prestazioni.
Un'altra considerazione consiste nel fatto che -fomit-frame-
pointer possa o meno rappresentare un vantaggio. Da un lato,
rende disponibile un altro registro per l'uso; tuttavia, il
modo in cui x86 codifica il suo set di istruzioni comporta
che gli indirizzi relativi di stack occupino pi spazio
rispetto agli indirizzi relativi di frame; di conseguenza,
sar disponibile ai programmi una quantit (leggermente)
inferiore di Icache. Inoltre, -fomit-frame-pointer implica
il continuo aggiustamento del puntatore allo stack da parte
del compilatore, dopo ogni chiamata, quando, con un frame,
pu lasciare che lo stack esegua un accumulo per alcune
chiamate.
L'ultima parola su questo argomento viene ancora da Linus:
Se si desidera ottenere prestazioni ottimali, non credete
alle mie parole, effettuate delle prove. Esistono molte
opzioni nel compilatore gcc, e pu darsi che un insieme par
ticolare dia l'ottimizzazione migliore per la propria
impostazione.
4.2.2. Internal compiler error: cc1 got fatal signal 11
(Ovvero: "Errore interno del compilatore: cc1 ha ricevuto il segnale
fatale 11").
Il segnale 11 SIGSEGV, o 'segmentation violation'. Solitamente
significa che il programma ha confuso i puntatori e ha tentato di
scrivere su una porzione di memoria che non possedeva. Potrebbe
trattarsi di un errore di gcc.
Tuttavia, gcc ben verificato ed affidabile, nella maggior parte dei
casi. Utilizza anche un gran numero di strutture dati complesse, e una
grande quantit di puntatori. In breve, il miglior tester di RAM tra
quelli disponibili comunemente. Se non possibile replicare l'errore
- il sistema non si ferma nello stesso punto quando si riavvia la
compilazione - molto probabilmente si tratta di un problema legato
all'hardware (CPU, memoria, scheda madre o cache). Non lo si deve
considerare un errore del compilatore solo perch il proprio computer
supera i controlli di avvio del sistema o in grado di eseguire
Windows o qualunque altro programma; questi 'test' sono comunemente
ritenuti, a ragione, di nessun valore. Comunque sbagliato ritenere
che si tratti di un errore, perch una compilazione del kernel si
blocca sempre durante `make zImage' - logico che ci accada: `make
zImage' probabilmente compila pi di 200 file. In genere si ricerca un
bug in un insieme pi piccolo di cos.
Se possibile duplicare l'errore, e (ancora meglio) produrre un breve
programma che lo dimostra, possibile inviarlo come report di errori
all'FSF, o alla mailing list di linux-gcc. Si faccia riferimento alla
documentazione di gcc per i dettagli relativi alle informazioni
effettivamente necessarie.
4.3. Portabilit
stato detto che, in questi giorni, se non pu essere portato a
Linux, allora qualcosa che non vale la pena di possedere. :-)
In generale, sono necessarie solo piccole modifiche per ottenere la
conformit POSIX al 100% di Linux. Sarebbe anche molto utile
restituire agli autori ogni modifica al codice in modo che, in futuro,
si possa ottenere un eseguibile funzionante tramite il solo comando
'make'.
4.3.1. BSD (inclusi bsd_ioctl, demone e <sgtty.h>)
possibile compilare il proprio programma con -I/usr/include/bsd ed
eseguire il link con -lbsd (ossia, aggiungere -I/usr/include/bsd a
CFLAGS e -lbsd alla riga LDFLAGS nel proprio Makefile). Non pi
necessario aggiungere -D__USE_BSD_SIGNAL se si desidera un
comportamento dei segnali di tipo BSD, dal momento che questa
caratteristica viene ottenuta automaticamente quando si ha
-I/usr/include/bsd e l'include <signal.h>.
4.3.2. SIGIOT , SIGTRAP , SIGSYS ecc) Segnali 'mancanti' ( SIGBUS ,
SIGEMT ,
Linux conforme a POSIX. Quelli elencati nel seguito sono segnali non
definiti in POSIX - ISO/IEC 9945-1:1990 (IEEE Std 1003.1-1990),
paragrafo B.3.3.1.1:
"I segnali SIGBUS, SIGEMT, SIGIOT, SIGTRAP, e SIGSYS sono
stati omessi da POSIX.1 perch il loro comportamento dipende
dall'implementazione e non stato possibile classificarlo
adeguatamente. Implementazioni conformi potranno contenere
questi segnali, ma devono documentare le circostanze in cui
sono rilasciati ed elencare ogni restrizione riguardante il
loro rilascio."
Il modo pi economico e scadente di gestire la cosa consiste nel
ridefinire questi segnali in SIGUNUSED. Il modo corretto consiste
nell'inserire il codice che li gestisce in appropriati #ifdef
#ifdef SIGSYS
/* ... codice SIGSYS non-posix .... */
#endif
4.3.3. Codice K & R
GCC un compilatore ANSI; una grande quantit di codice esistente non
ANSI. Non c' molto da fare per risolvere questo problema, oltre
all'aggiungere -traditional alle opzioni del compilatore. Si invita a
consultare l'info page di gcc.
Si noti che -traditional ha altri effetti oltre a cambiare il
linguaggio accettato da gcc. Ad esempio, attiva -fwritable-strings,
che sposta le stringhe costanti nello spazio dati (dallo spazio di
codice, dove non possono essere scritte). Questo aumenta
l'occupazione di memoria del programma.
4.3.4. Conflitto dei simboli di preprocessore con prototipi nel
codice
Uno dei problemi pi frequenti consiste nel fatto che alcune funzioni
comuni sono definite come macro negli header file di Linux e il
preprocessore si rifiuter di eseguire il parsing di definizioni
prototipo simili. I pi comuni sono atoi() e atol().
4.3.5. sprintf()
Soprattutto quando si esegue il porting da SunOS, necessario essere
consapevoli del fatto che sprintf(string, fmt, ...) restituisce un
puntatore a stringhe, mentre Linux (seguendo ANSI) restituisce il
numero di caratteri che sono stati messi nella stringa.
4.3.6. fcntl e affini. Quali sono le definizioni di FD_* ?
Le definizioni si trovano in <sys/time.h>. Se si sta utilizzando
fcntl, probabilmente si vorr includere anche <unistd.h>.
In genere, la pagina di manuale di una funzione elenca gli #include
necessarie nella sua sezione SYNOPSIS.
4.3.7. Il timeout di select() . Programmi in busy-waiting
Una volta, il parametro timeout di select() era utilizzato a sola
lettura. Gi allora, le pagine di manuale avvertivano:
select() dovrebbe probabilmente restituire il tempo rima
nente dal timeout originale, se esistente, modificando il
valore del tempo. Questo potr essere implementato in ver
sioni future del sistema. Pertanto, sarebbe sbagliato
ritenere che il puntatore al timeout non sar modificato
dalla chiamata select().
Ora il futuro arrivato. Di ritorno da una select(), l'argomento di
timeout sar impostato al tempo rimanente che si sarebbe atteso se i
dati non fossero arrivati. Se non arrivato alcun dato, il valore
sar zero, e le chiamate future utilizzando la stessa struttura
timeout eseguiranno immediatamente il return.
Per rimediare, in caso di errore, si metta il valore di timeout nella
struttura ogni volta che si chiama select(). Si modifichi il codice
come:
______________________________________________________________________
struct timeval timeout;
timeout.tv_sec = 1; timeout.tv_usec = 0;
while (some_condition)
select(n,readfds,writefds,exceptfds,&timeout);
______________________________________________________________________
in
______________________________________________________________________
struct timeval timeout;
while (some_condition) {
timeout.tv_sec = 1; timeout.tv_usec = 0;
select(n,readfds,writefds,exceptfds,&timeout);
}
______________________________________________________________________
Alcune versioni di Mosaic evidenziavano questo problema. La velocit
dell'animazione del globo rotante era inversamente correlata alla
velocit con cui i dati giungevano dalla rete!
4.3.8. Chiamate di sistema interrotte
4.3.8.1. Sintomo
Quando un programma viene interrotto utilizzando Ctrl-Z e poi viene
riavviato - o in altre situazioni che generano dei segnali:
interruzione con Ctrl-C, terminazione di un processo figlio ecc. - si
ottengono messaggi del tipo "interrupted system call" o "write:
unknown error".
4.3.8.2. Problema
I sistemi POSIX controllano la presenza di segnali pi frequentemente
rispetto a sistemi UNIX pi vecchi. Linux pu eseguire dei gestori di
segnali:
in modo asincrono (tramite un timer)
al ritorno da ogni chiamata di sistema
durante l'esecuzione delle seguenti chiamate di sistema: select(),
pause(), connect(), accept(), read() su terminali, su socket, su
pipe o su file in /proc, write() su terminali, su socket, su pipe o
sulla line printer; open() su FIFO, su PTY o su linee seriali,
ioctl() su terminali; fcntl() con il comando F_SETLKW; wait4(),
syslog(), ogni operazione TCP o NFS.
Per altri sistemi operativi potrebbe essere necessario includere in
questa lista le chiamate di sistema creat(), close(), getmsg(),
putmsg(), msgrcv(), msgsnd(), recv(), send(), wait(), waitpid(),
wait3(), tcdrain(), sigpause(), semop().
Se un segnale (per il quale il programma ha installato un gestore)
avviene durante una chiamata di sistema, viene chiamato il gestore.
Quando il gestore restituisce il controllo (alla chiamata di sistema),
essa rileva che stata interrotta e restituisce immediatamente -1 e
errno = EINTR. Il programma non si aspetta che questo accada, pertanto
si blocca.
possibile scegliere tra due alternative, per rimediare.
Per ogni gestore di segnali che viene installato, aggiungere
SA_RESTART ai flag sigaction. Per esempio, modificare
___________________________________________________________________
signal (sig_nr, my_signal_handler);
___________________________________________________________________
in
______________________________________________________________________
signal (sig_nr, my_signal_handler);
{ struct sigaction sa;
sigaction (sig_nr, (struct sigaction *)0, &sa);
#ifdef SA_RESTART
sa.sa_flags |= SA_RESTART;
#endif
#ifdef SA_INTERRUPT
sa.sa_flags &= ~ SA_INTERRUPT;
#endif
sigaction (sig_nr, &sa, (struct sigaction *)0);
}
______________________________________________________________________
Si noti che mentre questo viene applicato alla maggior parte delle
chiamate di sistema, necessario controllare EINTR personalmente
riguardo a read(), write(), ioctl(), select(), pause() e connect() .
Si veda sotto.
Controllare EINTR esplicitamente.
Seguono due esempi per read() e ioctl().
Una parte di codice originale utilizzante read()
______________________________________________________________________
int result;
while (len > 0) {
result = read(fd,buffer,len);
if (result < 0) break;
buffer += result; len -= result;
}
______________________________________________________________________
diventa
______________________________________________________________________
int result;
while (len > 0) {
result = read(fd,buffer,len);
if (result < 0) { if (errno != EINTR) break; }
else { buffer += result; len -= result; }
}
______________________________________________________________________
e una parte di codice utilizzante ioctl()
______________________________________________________________________
int result;
result = ioctl(fd,cmd,addr);
______________________________________________________________________
diventa
______________________________________________________________________
int result;
do { result = ioctl(fd,cmd,addr); }
while ((result == -1) && (errno == EINTR));
______________________________________________________________________
Si noti che in alcune versioni di Unix BSD il comportamento
predefinito consiste nel riavviare le chiamate di sistema. Per
ottenere l'interruzione delle chiamate di sistema necessario
utilizzare i flag SV_INTERRUPT o SA_INTERRUPT.
4.3.9. Stringhe scrivibili (il programma genera 'segmentation fault'
in modo casuale)
GCC ha una visione ottimistica dei suoi utenti, considerando le
costanti stringa esattamente quello che sono - delle costanti.
Pertanto, le memorizza nell'area del codice, dove possono essere
inserite ed estratte dall'immagine di disco del programma (invece di
occupare uno swapspace). Ne consegue che ogni tentativo di riscriverle
causer 'segmentation fault'.
Questo pu causare dei problemi a vecchi programmi che, per esempio
eseguono una chiamata mktemp() con una stringa costante come
argomento. mktemp() tenta di riscrivere il suo argomento.
Per correggere,
compilare con l'opzione -fwritable-strings, per fare in modo che
gcc posizioni le costanti nello spazio dati, oppure
riscrivere le parti che causano dei problemi per allocare una
stringa non costante ed eseguire la strcpy dei dati in essa prima
della chiamata.
4.3.10. Perch la chiamata execl() fallisce?
Probabilmente accade perch viene eseguita in modo errato. Il primo
argomento per execl il nome del programma da eseguire. Il secondo e
i successivi diventano l'array argv del programma che si sta
chiamando. Ricordare che: argv[0] viene impostato anche per un
programma eseguito senza argomenti. Pertanto si dovrebbe scrivere
______________________________________________________________________
execl("/bin/ls","ls",NULL);
______________________________________________________________________
e non solo
______________________________________________________________________
execl("/bin/ls", NULL);
______________________________________________________________________
L'esecuzione del programma senza nessun argomento interpretata come
un invito a stampare le sue dipendenze a librerie dinamiche, almeno
utilizzando a.out. ELF si comporta diversamente.
(Se si desidera questa informazione di libreria, esistono interfacce
pi semplici; si veda il paragrafo relativo al caricamento dinamico, o
la pagina di manuale per ldd).
5. Debugging e Profiling
5.1. Manutenzione preventiva (lint)
Non esiste un lint ampiamente utilizzato per Linux, dal momento che la
maggior parte della gente si accontenta degli avvertimenti che gcc pu
generare. Probabilmente, quello pi utile il -Wall opzione che
significa 'Warnings, all' ma probabilmente ha un maggior valore
mnemonico, se pensato come qualcosa contro cui si sbatte la testa
(NdT. "wall" in inglese significa "muro").
Esiste un lint di dominio pubblico disponibile su
ftp://larch.lcs.mit.edu/pub/Larch/lclint. Putroppo non sono in grado
di giudicare la sua validit.
5.2. Debugging
5.2.1. Come si ottengono le informazioni di debug in un programma?
necessario compilare ed eseguire il link di tutte le sue parti con
l'opzione -g, e senza -fomit-frame-pointer. Non necessario
ricompilarlo interamente, solo le parti di cui si esegue il debug.
Nelle configurazioni a.out le librerie condivise sono compilate con
-fomit-frame-pointer, con la quale gdb non funzioner. Questo perch
l'opzione -g implica un link statico.
Se il linker va in errore fornendo un messaggio che indica
l'impossibilit di trovare libg.a, significa che non si possiede
/usr/lib/libg.a, che consiste nella speciale libreria C abilitata al
debugging. Tale libreria pu essere fornita nel pacchetto binario
libc, oppure (in versioni di libreria C pi recenti) pu essere
necessario ottenere il codice sorgente libc ed eseguire personalmente
la compilazione. Tuttavia, possibile ottenere sufficienti
informazioni per la maggior parte degli scopi semplicemente
sostituendola con un collegamento simbolico con /usr/lib/libc.a.
5.2.1.1. Come eliminarle?
Molto software GNU impostato affinch la compilazione e il link
siano eseguite con l'opzione -g, che determina la generazione di
eseguibili molto voluminosi (e spesso statici). Questa non una buona
idea.
Se il programma possiede uno script di configurazione `autoconf',
possibile disabilitare le informazioni di debugging controllando il
Makefile. Naturalmente, se si sta utilizzando ELF, il link del
programma viene eseguito in modo dinamico indipendentemente
dall'impostazione -g, pertanto si pu semplicemente usare strip.
5.2.2. Software disponibile
Molte persone utilizzano gdb, che pu essere ottenuto in forma
sorgente dai siti di archivio GNU ftp://prep.ai.mit.edu/pub/gnu,
oppure in formato binario da tsx-11
(ftp://tsx-11.mit.edu/pub/linux/packages/GCC) o da sunsite. xxgdb un
debugger X basato su gdb (ossia, necessario che sia installato gdb).
possibile trovare i sorgenti presso
ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz.
Rick Sladkey ha eseguito il porting del debugger UPS. Pu essere
eseguito anche sotto X, ma a differenza di xxgdb, non un semplice
front end X per un debugger basato su testo. Possiede diverse
caratteristiche molto interessanti, e se si ha la necessit di
eseguire diversi debug, il caso di provarlo. La versione
precompilata per Linux e i patch per i sorgenti UPS possono essere
trovati in ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/, mentre i
sorgenti originali in ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z.
Un altro strumento utile per il debug 'strace', che visualizza le
chiamate di sistema fatte da un processo. Questo strumento possiede
anche molti altri utilizzi, inclusa la possibilit di sapere i nomi di
file compilati, di cui non si possiede il sorgente; di esasperare i
race condition in programmi che si sospettano contenerle, e in
generale di imparare come funzionano le cose. La versione pi recente
di strace (attualmente la 3.0.8) pu essere trovata in
ftp://ftp.std.com/pub/jrs/.
5.2.3. Programmi background (demone)
I programmi demone tipicamente eseguono presto la fork(), e terminano
il programma chiamante. Questo rende la sessione di debug molto breve.
Il modo pi semplice per aggirare questo ostacolo consiste
nell'impostare un breakpoint per fork, e quando il programma si
blocca, forzare la restituzione di 0.
(gdb) list
1 #include <stdio.h>
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
Step singolo fino all'uscita dalla funzione fork,
che non contiene informazioni sul numero di riga.
child
7 }
5.2.4. Core file
Quando Linux viene avviato, solitamente configurato per non produrre
core file. Se si desidera, possibile utilizzare il comando interno
dell'interprete comandi per riabilitarli: per shell compatibili C
(come tcsh) corrisponde al comando
% limit core unlimited
mentre per interpreti comandi di tipo Bourne (sh, bash, zsh, pdksh)
utilizzare
$ ulimit -c unlimited
Se si desidera una maggiore flessibilit nell'assegnazione dei nomi ai
core file (nel caso, per esempio, di analisi post-mortem con un
debugger che contiene errori) possibile eseguire una piccola
modifica al proprio kernel. Cercare in fs/binfmt_aout.c e
fs/binfmt_elf.c il codice tipo:
______________________________________________________________________
memcpy(corefile,"core.",5);
#if 0
memcpy(corefile+5,current->comm,sizeof(current->comm));
#else
corefile[4] = '\0';
#endif
______________________________________________________________________
e modificare gli 0 in 1.
5.3. Profiling
Il profiling rappresenta un modo per esaminare le parti di un
programma richiamate pi frequentemente o eseguite pi a lungo.
buona norma ottimizzare il codice e vedere dove viene perso del tempo.
necessario compilare tutti i file oggetto sui quali si desiderano
informazioni sul tempo di esecuzione con l'opzione -p, e per
interpretare il file di output sar necessario anche gprof (dal
pacchetto binutils). Si veda la pagina di manuale gprof per ulteriori
dettagli.
6. Linking
Questo paragrafo piuttosto complicato a causa dei due formati binari
incompatibili, la distinzione tra libreria statica e condivisa, e del
sovraccarico del verbo 'link' che significa sia 'cosa accade dopo la
compilazione', sia 'cosa accade quando viene richiamato un programma
compilato' (e, di fatto, il sovraccarico del verbo 'load' in un senso
simile ma opposto).
Per ridurre in qualche modo la confusione, si user il termine
`caricamento dinamico' (dynamic loading) per quello che accade durante
l'esecuzione, argomento descritto nel prossimo paragrafo. Potrebbe
anche accadere di trovare il termine 'collegamento dinamico' (dynamic
linking) con lo stesso significato, ma non in questo documento. Questo
paragrafo, quindi, tratta esclusivamente il tipo di link che avviene
alla fine di una compilazione.
6.1. Librerie condivise e statiche
L'ultima fase della compilazione di un programma consiste nel
'collegamento' (link), ossia nell'unire tutte le parti e vedere se
manca qualcosa. Ovviamente esistono alcune cose che molti programmi
hanno in comune - ad esempio, aprire file, ed il codice in grado di
fare queste cose sono fornite sotto forma di librerie. Nella maggior
parte dei sistemi Linux si trovano in /lib e /usr/lib/.
Quando si utilizza una libreria statica, il linker trova le parti
necessarie ai moduli di programma e le copia fisicamente nel file di
output eseguibile che viene generato. Al contrario, questo non avviene
per le librerie condivise - in questo caso nell'output viene inserita
una nota del tipo 'quando viene eseguito questo programma,
necessario caricare questa libreria'. Ovviamente, le librerie
condivise tendono a creare eseguibili di dimensioni minori; inoltre
utilizzano una quantit inferiore di memoria e viene utilizzato meno
spazio su disco. Il comportamento predefinito di Linux consiste
nell'eseguire il collegamento di librerie condivise se esistono,
altrimenti vengono utilizzate quelle statiche. Se si ottengono dei
binari statici quando, al contrario, si vogliono quelli condivisi,
controllare che i file di libreria condivisa (*.sa per a.out, *.so per
ELF) si trovino dove dovrebbero essere e siano leggibili.
Su Linux, le librerie statiche hanno nomi come libname.a, mentre le
librerie condivise sono denominate libname.so.x.y.z dove x.y.z
rappresenta il numero di versione. Le librerie condivise, inoltre,
contengono spesso dei collegamenti che puntano ad esse, che risultano
essere molto importanti, e (in configurazioni a.out) contengono dei
file .sa associati. Le librerie standard sono disponibili sia in
formato condiviso, sia in formato statico.
possibile sapere quali librerie condivise sono richieste da un
programma utilizzando ldd (List Dynamic Dependencies)
$ ldd /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
Questo esempio mostra che il browser WWW 'lynx' dipende dalla presenza
di libc.so.5 (la libreria C) e libncurses.so.1 (utilizzata per il
controllo del terminale). Se un programma non ha dipendenze, ldd
risponder 'statically linked' o 'statically linked (ELF)'.
6.2. Interrogazione delle librerie ('In quale libreria si trova
sin()?')
nm nome_libreria dovrebbe listare tutti i simboli per i quali esistono
dei riferimenti in nome_libreria. Il comando funziona sia per librerie
statiche che dinamiche. Si supponga di voler saper dov' definita
tcgetattr(): si potrebbe utilizzare
$ nm libncurses.so.1 |grep tcget
U tcgetattr
`U' significa 'undefined' - mostra che la libreria ncurses la utilizza
ma non la definisce. In alternativa, si potrebbe usare
$ nm libc.so.5 | grep tcget
00010fe8 T __tcgetattr
00010fe8 W tcgetattr
00068718 T tcgetpgrp
`W' significa 'weak', ossia che il simbolo definito, ma in modo tale
da poter essere sostituito da un'altra definizione in una libreria
diversa. Una definizione 'normale' (come quella per tcgetpgrp)
indicata con una 'T'.
Comunque la risposta breve alla domanda del titolo, consiste in
libm.(so|a). Tutte le funzioni definite in <math.h> sono tenute nella
libreria math; ne consegue che sar necessario eseguire il
collegamento con l'opzione -lm quando si utilizza una di esse.
6.3. Ricerca dei file
ld: Output file requires shared library `libfoo.so.1`
(Ovvero: "ld: Il file di output richiede la libreria condivisa
'libfoo.so.1'")
La strategia di ricerca di un file per ld e simili varia a seconda
della versione, ma l'unico punto che si pu ritenere predefinito
/usr/lib. Se si vuole che le librerie vengano cercate in altre
locazioni, necessario specificare le loro directory tramite
l'opzione -L in gcc o ld.
Se non dovesse funzionare, controllare che i file necessari si trovino
effettivamente in quelle directory. Per a.out, il collegamento con
-lfoo fa in modo che ld cerchi libfoo.sa (condivisa) e, in caso di
insuccesso, libfoo.a (statica). Per ELF, verr eseguita la ricerca di
libfoo.so, quindi di libfoo.a. libfoo.so generalmente un
collegamento simbolico a libfoo.so.x.
6.4. Compilazione delle proprie librerie
6.4.1. Controllo della versione
Come qualunque altro programma, le librerie possono contenere errori
che vengono riscontrati e risolti nel tempo. Inoltre, le librerie
possono introdurre nuove caratteristiche, modificare l'effetto di
altre esistenti, o rimuovere quelle vecchie. Questo potrebbe
costituire un problema per i programmi che le utilizzano.
Pertanto si introdutto il concetto di versione della libreria. Tutte
le modifiche che possono essere fatte a una libreria sono catalogate
in 'minori' o 'maggiori', dove una modifica 'minore' non interrompe il
funzionamento dei vecchi programmi che la utilizzano. La versione di
una libreria pu essere dedotta dal suo nome di file (di fatto, questo
non vero per quanto riguarda ELF; nel seguito viene spiegato il
motivo): libfoo.so.1.2 ha '1' come versione maggiore, e '2' come
minore. Il numero di versione minore pu essere svariato - libc
inserisce in esso il 'livello di patch', assegnando alle librerie nomi
del tipo libc.so.5.2.18, e spesso sono utilizzate lettere, underscore,
o quasi ogni altro carattere ASCII.
Una delle differenze principali tra il formato ELF e a.out consiste
nel modo in cui viene eseguita la compilazione delle librerie
condivise. Per prima cosa viene descritto ELF, dal momento che pi
semplice.
6.4.2. ELF. Di cosa si tratta?
ELF (Executable and Linking Format) un formato binario
originariamente sviluppato da USL (UNIX System Laboratories) e
attualmente utilizzato in Solaris e System V Release 4. A seguito
della sua aumentata flessibilit rispetto al pi vecchio formato a.out
utilizzato da Linux, gli sviluppatori di librerie GCC e C hanno deciso
lo scorso anno di utilizzare ELF come formato binario standard per
Linux.
6.4.2.1. Uteriori dettagli
Questo paragrafo tratto dal documento '/news-
archives/comp.sys.sun.misc'.
ELF (Executable Linking Format) il nuovo e migliorato for
mato di file oggetto introdotto in SVR4. ELF molto pi
potente di COFF, nel fatto di essere estendibile
dall'utente. ELF vede un file oggetto come una lista di
sezioni arbitrariamente lunga (piuttosto che come un array
di entit a lunghezza fissa), tali sezioni, a differenza di
quanto accade in COFF, non si devono trovare in un luogo
specifico e non devono essere in un ordine specifico ecc.
Gli utenti possono aggiungere nuove sezioni ai file oggetto,
se desiderano avere a disposizione nuovi dati. ELF, inoltre,
possiede un formato di debugging molto pi potente denomi
nato DWARF (Debugging With Attribute Record Format) -
attualmente non supportato completamente su Linux (ma ci si
sta lavorando). Una lista linkata di DIE (o Debugging Infor
mation Entries) di DWARF costituisce la sezione .debug di
ELF. Invece di essere un insieme di piccoli record a dimen
sione fissa, ogni DIE di DWARF contiene una lista di
lunghezza arbitraria di attributi complessi ed scritto
come un albero di dati di programma. I DIE sono in grado di
includere una quantit di informazioni di molto maggiore
rispetto alla sezione .debug di COFF (come grafi di eredit
del C++ ecc).
L'accesso ai file ELF avviene tramite la libreria di accesso
ELF SVR4 (Solaris 2.0 ?), che fornisce un'interfaccia sem
plice e rapida alle parti pi complicate di ELF. Uno dei
vantaggi principali derivanti dall'utilizzo della libreria
di accesso ELF consiste nel fatto che non sar mai neces
sario vedere un file ELF come file Unix, possibile
eseguire l'accesso come file Elf *, dopo una chiamata
elf_open() si eseguono chiamate elf_foobar() sulle sue com
ponenti invece di occuparsi della sua immagine effettiva su
disco (cosa che con COFF si faceva impunemente).
I vantaggi e gli svantaggi di ELF, e le evoluzioni necessarie per
eseguire l'upgrade di un sistema a.out per supportarlo, sono descritti
nell'ELF-HOWTO e non ho intenzione di ripeterli qui. L'HOWTO dovrebbe
essere disponibile nello stesso luogo in cui stato trovato questo
documento.
6.4.2.2. Librerie condivise di ELF
Per eseguire la compilazione di libfoo.so come libreria condivisa, i
passi di base hanno la seguente forma:
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
$ ln -s libfoo.so.1.0 libfoo.so.1
$ ln -s libfoo.so.1 libfoo.so
$ LD_LIBRARY_PATH='pwd':$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH
Questi comandi genererano una libreria condivisa denominata
libfoo.so.1.0, i collegamenti appropriati per ld (libfoo.so) e il
caricamento dinamico (libfoo.so.1) per trovarla. Per eseguire un
collaudo, si aggiunge la directory corrente a LD_LIBRARY_PATH.
Quando si sicuri che la libreria funziona, deve essere spostata, ad
esempio, in /usr/local/lib, e devono essere creati appropriati
collegamenti. Il collegamento da libfoo.so.1 a libfoo.so.1.0
mantenuto aggiornato da ldconfig, che nella maggior parte dei sistemi
viene eseguito come parte del processo di avviamento. Il collegamento
libfoo.so deve essere aggiornato manualmente. Se si scrupolosi
nell'eseguire l'aggiornamento di tutte le parti di una libreria (ossia
degli header file) contemporaneamente, la cosa pi semplice da fare
consiste nel rendere libfoo.so -> libfoo.so.1, in modo che ldconfig
mantenga correnti entrambi i collegamenti. In caso contrario, potrebbe
in seguito verificarsi ogni genere di stranezza.
$ su
# cp libfoo.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )
6.4.2.3. Numerazione delle versioni, soname e symlink
Ogni libreria ha un soname. Quando il linker trova uno di questi in
una libreria in cui sta eseguendo una ricerca, nel binario viene
incluso il soname in luogo del nome di file effettivo ricercato.
Durante l'esecuzione, il loader dinamico cercher un file tramite il
nome di soname, non con il nome di file/libreria. Pertanto, una
libreria denominata libfoo.so potrebbe avere il soname libbar.so, di
conseguenza tutti i programmi collegati ad essa, all'avvio,
cercherebbero libbar.so.
Sembra essere una caratteristica di poca importanza, invece la
chiave per capire come su un sistema possono coesistere diverse
versioni della stessa libreria. Di fatto, la denominazione standard
delle librerie in Linux consiste nel chiamare la libreria, ad esempio,
libfoo.so.1.2, e assegnare ad essa il soname libfoo.so.1. Se aggiunta
in una directory di libreria 'standard' (ossia, /usr/lib), ldconfig
creer un collegamento simbolico libfoo.so.1 -> libfoo.so.1.2 in modo
che sia possibile trovare l'immagine appropriata durante l'esecuzione.
necessario anche un collegamento libfoo.so -> libfoo.so.1 affinch
ld possa trovare il soname corretto da utilizzare durante il link.
Pertanto, quando si risolve un errore nella libreria, o si aggiungono
nuove funzioni (ogni modifica che non influenzi in modo negativo i
programmi esistenti), si eseguir nuovamente la compilazione
mantenendo lo stesso soname, e modificando il nome di file. Quando si
inseriscono nella libreria delle modifiche che causerebbero
l'interruzione dei programmi esistenti, incrementare semplicemente il
numero nel soname - in questo caso, rinominare la nuova versione
libfoo.so.2.0, e assegnarle il soname libfoo.so.2. Quindi, convertire
il collegamento a libfoo.so in modo che punti alla nuova versione e
tutto a posto.
Si noti che non necessario dare un nome alle librerie, ma si tratta
di una buona convenzione. ELF fornisce una flessibilit nel nominare
le librerie in modi che potrebbero confondere, ma questo non significa
che debba farlo per forza.
Riassumendo: se si suppone di osservare la tradizione secondo cui gli
aggiornamenti maggiori potrebbero distruggere la compatibilit e che
quelli minori non lo fanno, eseguire il collegamento con
gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor
e tutto funzioner alla perfezione.
6.4.3. a.out. Il formato tradizionale
La facilit con cui si esegue la compilazione di librerie condivise
uno dei motivi principali per passare a ELF. Detto questo, ancora
possibile utilizzare a.out. Si prenda
ftp://tsx-11.mit.edu/pub/linux/packages/GCC/src/tools-2.17.tar.gz e si
legga il documento di 20 pagine.
6.4.3.1. ZMAGIC e QMAGIC
QMAGIC un formato eseguibile proprio come i vecchi binari a.out
(conosciuti anche come ZMAGIC), ma che lascia la prima pagina non
mappata. Questo consente che accada pi facilmente un riferimento
NULL dal momento che non esiste alcun mapping nel range 0-4096. Come
effetto collaterale, i binari saranno di dimensioni inferiori (di
circa 1 K).
I linker obsoleti supportano solamente ZMAGIC, quelli semi-obsoleti
supportano entrambi i formati, mentre le versioni attuali supportano
solo QMAGIC. In realt questo non ha importanza, dal momento che il
kernel riesce ad eseguire entrambi i formati.
Il proprio comando 'file' dovrebbe essere in grado di identificare se
un programma QMAGIC.
6.4.3.2. Posizione dei file
Una libreria condivisa a.out (DLL) formata da due file reali e da un
collegamento simbolico. Per la libreria 'foo' utilizzata come esempio,
questi file sarebbero libfoo.sa e libfoo.so.1.2; il collegamento
simbolico sarebbe libfoo.so.1 e punterebbe all'ultimo di questi file.
Ma a cosa servono?
Durante la compilazione, ld ricerca libfoo.sa. Si tratta del file
'matrice' della libreria, e contiene tutti i dati esportati e i
puntatori alle funzioni richieste per il collegamento run time.
Durante l'esecuzione, il loader dinamico cerca libfoo.so.1. Si tratta
di un collegamento simbolico anzich di un file reale in modo che le
librerie possano essere aggiornate con versioni pi recenti e corrette
senza procurare danni a nessuna delle applicazioni utilizzanti la
libreria in quel momento. Dopo che la nuova versione, ad esempio
libfoo.so.1.3 - stata introdotta, l'esecuzione di ldconfig commuter
il collegamento affinch punti ad essa tramite un'operazione atomica,
lasciando illeso ogni programma che stava utilizzando la vecchia
versione.
Le librerie DLL appaiono spesso pi grandi delle loro controparti
statiche. Riservano spazio per future espansioni nella forma di
'buchi' che possono essere creati senza occupare spazio su disco. Una
semplice chiamata cp o l'utilizzo del programma makehole raggiunger
questo scopo. Dopo la compilazione, anche possibile rimuoverli, dal
momento che gli indirizzi si trovano in locazioni fisse. Non tentare
di rimuoverli dalle librerie ELF.
6.4.3.3. "libc-lite"?
Un libc-lite una versione ridotta della libreria libc per la quale
stata eseguita la compilazione in modo tale da stare su un floppy disk
ed essere sufficiente per tutti i task Unix essenziali. Non include
codice curse, dbm, termcap ecc. Se il proprio /lib/libc.so.4 ha un
collegamento con un lite lib, il sistema avvisa di sostituirlo con una
versione completa.
6.4.4. Linking: problemi comuni
Inviatemi i problemi derivanti dal linking! Anche se non potr fare
niente per risolverli, ne scriver un resoconto dettagliato.
Programmi eseguono il link statico anzich dinamico
Controllare di avere i collegamenti corretti affinch ld possa
trovare tutte le librerie condivise. Per ELF questo significa un
collegamento simbolico libfoo.so per l'immagine, in a.out un
file libfoo.sa. Molte persone hanno riscontrato questo problema
dopo il passaggio dai binutils ELF 2.5 ai 2.6 - la versione
precedente ricercava le librerie condivise in un modo 'pi
intelligente' pertanto non avevano bisogno di creare tutti i
collegamenti. Il comportamento intelligente stato eliminato
per compatibilit con altre architetture, e perch molto spesso
le sue supposizioni erano sbagliate e causando pi guai di
quanti fossero i problemi risolti.
Lo strumento DLL 'mkimage' non riesce a trovare libgcc
Da libc.so.4.5.x e oltre, libgcc non pi condivisa. Pertanto,
necessario sostituire le occorrenze di '-lgcc' con 'gcc
-print-libgcc-file-name'.
Inoltre, bisogna cancellare tutti i file /usr/lib/libgcc*.
Questo molto importante.
Messaggi __NEEDS_SHRLIB_libc_4 multiply defined
Altra conseguenza del problema descritto al punto precedente.
Messaggio ``Assertion failure'' quando si ricompila una DLL?
Questo messaggio criptico molto probabilmente significa che uno
degli slot della propria jump table andato in overflow poich
stato riservato troppo poco spazio nel file jump.vars
originale. possibile localizzare i colpevoli eseguendo il
comando 'getsize' fornito nel pacchetto tools-2.17.tar.gz.
Tuttavia, probabilmente l'unica soluzione consiste nel
sostituire il numero di versione maggiore della libreria,
forzandolo affinch sia impossibile tornare indietro.
ld: output file needs shared library libc.so.4
Questo accade solitamente quando si sta eseguendo il
collegamento con librerie diverse da libc (come le librerie X),
e si utilizza l'opzione -g sulla riga di link utilizzando anche
-static.
Gli stub .sa per le librerie condivise contengono solitamente un
simbolo indefinito _NEEDS_SHRLIB_libc_4 che viene risolto da
libc.sa. Tuttavia, con -g si finisce di eseguire il collegamento
con libg.a o libc.a, il simbolo non viene mai risolto, portando
all'errore sopra descritto.
In conclusione, aggiungere -static quando si compila con
l'opzione -g, oppure non eseguire il collegamento con -g. Molto
spesso possibile ottenere informazioni di debugging
sufficienti compilando i file individuali con -g, ed eseguendo
il collegamento senza questa opzione.
6.5. Loading dinamico
Questo paragrafo per il momento piuttosto breve, verr esteso in
futuro.
6.5.1. Concetti
Linux possiede delle librerie condivise, come si visto diverse molte
volte nell'ultimo paragrafo. Gran parte del lavoro di associazione
dei nomi a locazioni, che tradizionalmente era svolto al momento del
link, deve essere ritardato al momento del load (caricamento).
6.5.2. Messaggi di errore
I lettori sono pregati di inviare i proprii errori di link all'autore,
che anche se non potr risolverli, comunque scriver un resoconto
dettagliato.
can't load library: /lib/libxxx.so, Incompatible version
(solo in a.out) Questo significa che non si possiede la versione
maggiore aggiornata della libreria xxx. Non possibile
semplicemente creare un collegamento simbolico ad un'altra
versione che si possiede; nella migliore delle ipotesi questo
causer un segfault nel proprio programma. Si consiglia di
ottenere una nuova versione. Una situazione simile in ELF
produrr un messaggio del tipo
ftp: can't load library 'libreadline.so.2'
warning using incompatible library version xxx
(solo in a.out) Si possiede una versione minore della libreria
pi vecchia di quella posseduta dalla persona che ha compilato
il programma in questione. Il programma funzioner comunque.
Tuttavia, un aggiornamento non sarebbe una cattiva idea.
6.5.3. Controllo delle operazioni del loader dinamico
Esistono diverse variabili di ambiente a che influenzano il
comportamento del loader dinamico. La maggior parte di esse sono pi
utili a ldd di quanto non lo siano per l'utente medio, e possono
essere impostate eseguendo ldd con diverse opzioni. Includono
LD_BIND_NOW --- normalmente, le funzioni non sono ricercate nelle
librerie finch non vengono chiamate. L'impostazione di questa
opzione attiva la ricerca all'atto del caricamento della libreria,
determinando un tempo di avviamento maggiore. Pu essere utile
quando si vuole collaudare un programma per accertarsi che sia
eseguito il link di tutte le parti.
LD_PRELOAD --- pu essere impostato con un file contenente delle
definizioni di funzioni da sovrapporre. Ad esempio, se si sta
eseguendo un test delle strategie di allocazione della memoria, e
si vuole sostituire 'malloc', possibile scrivere la propria
routine sostitutiva, compilarla come malloc.o e utilizzare i
comandi
$ LD_PRELOAD=malloc.o; export LD_PRELOAD
$ programma_di_test
LD_ELF_PRELOAD e LD_AOUT_PRELOAD sono simili, ma possono essere appli
cati solo al tipo binario appropriato. Se LD_qualcosa_PRELOAD e
LD_PRELOAD sono entrambi impostati, verr utilizzato quello pi speci
fico.
LD_LIBRARY_PATH --- elenco, separato da virgole, di directory in
cui ricercare le librerie condivise. Non ha effetti su ld, ma solo
durante l'esecuzione. Inoltre, disabilitato per programmi che
eseguono setuid o setgid. LD_ELF_LIBRARY_PATH e
LD_AOUT_LIBRARY_PATH possono anche essere utilizzati per impostare
la ricerca in modo differente per diversi tipi di binari.
LD_LIBRARY_PATH non dovrebbe essere necessario nelle operazioni
normali; piuttosto aggiungere le directory a /etc/ld.so.conf/ ed
eseguire ldconfig.
LD_NOWARN --- si applica solo ad a.out. Quando impostato (ossia con
LD_NOWARN=true; export LD_NOWARN) evita che il loader fornisca i
warning non fatali (come i messaggi per incompatibilit di versione
minore).
LD_WARN --- si applica solamente a ELF. Quando impostato, rende i
messaggi, solitamente fatali, "Can't find library" dei semplici
warning. Non molto utilizzato nelle operazioni normali, ma
importante per ldd.
LD_TRACE_LOADED_OBJECTS --- si applica solamente a ELF, e fa in
modo che i programmi credano di essere in esecuzione sotto ldd:
$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
6.5.4. Scrivere programmi con il loading dinamico
Questo molto simile al funzionamento del supporto di loading
dinamico di Solaris 2.x. L'argomento trattato ampiamente nel
documento di programmazione ELF di H J Lu e nella pagina di manuale
dlopen(3) manual page, che pu essere trovata nel pacchetto ld.so.
Segue un semplice esempio: necessario effettuare il link con -ldl
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*printf_call)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
printf_call=dlsym(libc,"printf");
(*printf_call)("hello, world\n");
}
}
7. Come contattare gli sviluppatori
7.1. Comunicazione degli errori
Per prima cosa necessario cominciare a circoscrivere il problema.
specifico di Linux, oppure accade con gcc su altri sistemi?
specifico della versione di kernel? Della versione di libreria?
Sparisce se si esegue il link statico? possibile ritagliare una
piccola parte del programma che dimostra l'errore?
Fatto questo, si a conoscenza del/i programma/i in cui si trova
l'errore. Per GCC, la procedura di comunicazione degli errori
spiegata nel file info. Per ld.so o per le librerie C o maths, inviare
una mail a linux-gcc@vger.rutgers.edu. Se possibile, includere un
breve e autonomo programma che possa dimostrare l'errore, e una
descrizione sia di cosa si intendeva che facesse, sia di cosa fa
effettivamente.
7.2. Aiuto nello sviluppo
Se si desidera aiutare lo sviluppo di GCC o della libreria C, la prima
cosa da fare consiste nell'unirsi alla mailing list linux-
gcc@vger.rutgers.edu. Se si vuole semplicemente dare un'occhiata alle
discussioni, possibile consultare http://homer.ncm.com/linux-gcc/.
La seconda cosa e le successive dipendono solo dalle vostre
intenzioni!
8. Ultime cose
8.1. Ringraziamenti
Only presidents, editors, and people with tapeworms have the
right to use the editorial "we". (Mark Twain)
Ovvero
Soli i presidenti, gli editori e la gente con il verme soli
tario hanno il diritto di usare il "noi" editoriale. (Mark
Twain)
Questo HOWTO si basa molto strettamente al GCC-FAQ di Mitchum DSouza;
la maggior parte delle informazioni (per non dire una grande quantit
di testo) derivato direttamente da quel documento. Esperienze
riferite all'autore all'interno di questo HOWTO potrebbero riferirsi
anche a Mitchum DSouza; generalmente le frasi del tipo 'Non si mai
collaudato questa parte; non maledite l'autore se il vostro
disco/sistema si abbrustolito' possono essere applicate a entrambi.
Inoltre hanno contribuito a questo documento (in ordine ASCII per
nome): 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, e naturalmente Linus Torvalds,
senza il quale l'intero lavoro non avrebbe avuto senso. Vi prego di
non sentirvi offesi se nella lista non compare il vostro nome e avete
contribuito a questo documento (come HOWTO o come FAQ). Inviate mail
ed sar eseguita la correzione.
8.2. Traduzioni
Attualmente, non esistono traduzioni di questo documento Se desiderate
farne una, siete liberi di farlo ma vi prego di farmelo sapere! Ci
sono pochissime probabilit che io sia in grado di parlare la lingua
in cui desiderate tradurre il documento, ma a parte questo sarei lieto
di aiutarvi in qualsiasi modo.
8.3. Comunicazioni, opinioni, correzioni
Sono benvenute inviate email all'indirizzo dan@detached.demon.co.uk.
La chiave pubblica PGP (ID 5F263625) disponibile dalle pagine web
dell'autore http://ftp.linux.org.uk/~barlow/, se ci sono necessit di
riservatezza.
8.4. Informazioni legali
All trademarks used in this document are acknowledged as being owned
by their respective owners.
This document is copyright (C) 1996 Daniel Barlow
dan@detached.demon.co.uk. It may be reproduced and distributed in
whole or in part, in any medium physical or electronic, as long as
this copyright notice is retained on all copies. Commercial
redistribution is allowed and encouraged; however, the author would
like to be notified of any such distributions.
All translations, derivative works, or aggregate works incorporating
any Linux HOWTO documents must be covered under this copyright notice.
That is, you may not produce a derivative work from a HOWTO and impose
additional restrictions on its distribution. Exceptions to these rules
may be granted under certain conditions; please contact the Linux
HOWTO coordinator at the address given below.
In short, we wish to promote dissemination of this information through
as many channels as possible. However, we do wish to retain copyright
on the HOWTO documents, and would like to be notified of any plans to
redistribute the HOWTOs.
If you have questions, please contact Tim Bynum, the Linux HOWTO
coordinator, at linux-howto@sunsite.unc.edu.
L'unica licenza valida quella originale in lingua inglese.
Di seguito ne trovate una traduzione abbastanza fedele che
per non ha alcun valore.
Tutti i marchi utilizzati in questo documento sono riconosciuti come
appartenenti ai rispettivi proprietari.
Questo documento ha copyright (C) 1996 di Daniel Barlow
dan@detached.demon.co.uk. Pu essere riprodotto e distribuito
completamente o in parte, su ogni mezzo fisico o elettronico, purch
questo messaggio di copyright sia mantenuto in tutte le copie.
consentita e incoraggiata la ridistribuzione commerciale; tuttavia,
l'autore gradirebbe essere informato su ciascuna di tali
distribuzioni.
Tutte le traduzioni, lavori derivati, o lavori aggregati che includono
un qualunque documento Linux deve essere coperto da questo messaggio
di copyright. Ossia, non possibile produrre un lavoro derivato da un
HOWTO e imporre delle restrizioni addizionali sulla sua distribuzione.
Eccezioni a queste regole possono essere ammesse sotto particolari
condizioni; si prega di contattare il coordinatore degli HOWTO di
Linux all'indirizzo sotto riportato.
In breve, desideriamo promuovere la diffusione di queste informazioni
attraverso pi canali possibile. Tuttavia, desideriamo anche mantenere
il copyright sui documenti HOWTO, e vorremmo essere informati se
qualcuno ha intenzione di ridistribuire gli HOWTO.
Se avete delle domande, contattate Tim Bynum, il coordinatore degli
HOWTO di Linux, all'indirizzo linux-howto@sunsite.unc.edu tramite
email.
9. Riferimenti in italiano
Questa sezione riporta riferimenti a documenti italiani. Nel caso in
cui un documento non sia ancora tradotto si rimanda al WEB server del
Pluto.
[1] http://www.pluto.linux.it/ildp/HOWTO/ELF-HOWTO.html
[2] http://www.pluto.linux.it/ildp/ WEB server del PLUTO, sono
disponibili anche le traduzioni di altri HOWTO.
[3] http://www.pluto.linux.it/ildp/HOWTO/GCC-HOWTO.html
10. Indice Analitico
-fwritable-strings
``39'' ``56''
/lib/cpp
``16''
a.out
``1''
ar
``10''
as
``8''
<asm/*.h>
``19''
atoi()
``40''
atol()
``41''
binaries too big
``63'' ``65'' ``77''
cos()
``68''
debugging
``59''
dlopen()
``82''
dlsym()
``83''
documentazione
``4''
EINTR
``52''
elf
``0'' ``71''
execl()
``57''
fcntl
``47''
FD_CLR
``44''
FD_ISSET
``45''
FD_SET
``43''
FD_ZERO
``46''
file
``2''
<float.h>
``20''
gcc
``6''
gcc -fomit-frame-pointer
``61''
gcc -g
``60''
gcc -v
``14''
gcc, errori (bug)
``15'' ``28'' ``29'' ``84''
gcc, opzioni (flag)
``13'' ``25'' ``26''
gdb
``64''
header file
``17''
chiamate a sistema interrotte
``51''
ld
``9''
LD_* variabili d'ambiente
``80''
ldd
``81''
libc
``7''
libg.a
``62''
libgcc
``79''
<limits.h>
``21''
lint
``58''
<linux/*.h>
``18''
pagine del manuale
``5''
<math.h>
``70''
maths
``69''
mktemp()
``55''
ottimizzazione
``27''
QMAGIC
``76''
segmentation fault
``30'' ``54''
segmentation fault, in GCC
``33''
select()
``50''
SIGBUS
``34''
SIGEMT
``35''
SIGIOT
``36''
SIGSEGV
``31'' ``53''
SIGSEGV, in gcc
``32''
SIGSYS
``38''
SIGTRAP
``37''
sin()
``67''
soname
``73''
sprintf()
``42''
librerie collegate staticamente, in modo inatteso
``66'' ``78''
<stdarg.h>
``23''
<stddef.h>
``24''
strings
``11''
<sys/time.h>
``48''
<unistd.h>
``49''
<varargs.h>
``22''
numeri di versione
``12'' ``74''
cose misteriose
``72''
ZMAGIC
``75''
|