Nejde až tak o to, jestli je to z pohledu programu konstanta nebo ne – mne spíš překvapilo, že si systém nedrží ve své paměti kopii těchto hodnot a místo toho se dívá do paměti procesu. Neříkám, že mít možnost přepisu parametrů je špatné, má to i smysluplné využití, ale spíš bych čekal, že to bude nějaké API a bude to nějak řízené (tzn. s možností např. zalogovat, že došlo k přepisu), než že to bude založené na tom, že obě strany koukají na jedno místo v paměti.
Pokud nekdo touzi po jmene programu, ktere meni syscallem, ma k dispozici comm (/proc/PID/comm, ps -o comm, pctl(PR_SET_NAME)). Jakej duvod by melo nekam zaznamenavat, ze doslo k prepisu? Pokud si nekdo bude chtit takto "ukryt" process, muze ho execnout rovnou s "falesnym" argv a vysledek bude stejny.
Mimochodem, uplne stejne se chova i prostredi, protoze pro kernel je oboji jen pole ukazatelu na retezce, jehoz obsah ho nijak nezajima.
Ne, je to pole ukazatelu, coz je zrejme z protypu main a nebo si to muze zvedavec precist ve fs/exec.c (alespon myslim, neoveroval jsem). Vypada takhle:
ptr_to_str1
ptr_to_str2
ptr_to_str3
NULL /* Posledni prvek pole */
str1
str2
str3
Samozrejme je to v pameti za sebou, protoze nedava smysl, aby mezi ne kernel daval prazdne misto.
Reagoval jsem na to „pro kernel je oboji jen pole ukazatelu na retezce“.
Pole ukazatelů je to IMHO jen z pohledu programu, ale jádro toto pole ignoruje, neřeší a přistupuje přímo k té souvislé paměti a drží si svoje vlastní značky ( arg_start, arg_end, env_start, env_end), kde začínají a končí parametry a proměnné prostředí. Budu si muset prostudovat zdrojáky procfs, ale zatím jsem to ověřil experimentálně:
printf("%p\n", argv[0]);
printf("%p\n", argv[1]);
argv[1]++;
printf("%p\n", argv[0]);
printf("%p\n", argv[1]);
for (int i = 0; i < argc; i++) {
printf("%d = %s\n", i, argv[i]);
}
argv[1][0] = '_';
for (int i = 0; i < argc; i++) {
printf("%d = %s\n", i, argv[i]);
}
Dejme tomu, že program byl spuštěn s jedním parametrem xxx. První cyklus vypíše xx a druhý _x. Zatímco jádro ( ps aux) vypisuje nejdřív xxx a pak x_x – což znamená, že jádro se dívá pořád na stejné místo v paměti, bez ohledu na to, že jsem do toho pole dal jiný ukazatel.
Trochu zvláštní je, že jádro tu svoji koncovou značku klidně překročí, pokud přemažu příslušný nulový bajt – a pak do seznamu parametrů začnou prosakovat proměnné prostředí, které následují v paměti hned za tím.