Beëindig een proces in Linux - ps, kill en killall-opdrachten. De PID van een proces in Linux wijzigen met behulp van een kernelmodule

In dit artikel zullen we proberen een kernelmodule te maken die de PID van een reeds actief proces in Linux kan veranderen, en ook experimenteren met processen die een gewijzigde PID hebben ontvangen.


Waarschuwing: Het wijzigen van de PID is een niet-standaardproces en kan onder bepaalde omstandigheden tot kernelpaniek leiden.

Onze testmodule zal het /dev/test character device implementeren, dat de PID van het proces zal veranderen wanneer er van gelezen wordt. Dank aan dit artikel voor een voorbeeld van het implementeren van een karakterapparaat. De volledige modulecode vindt u aan het einde van het artikel. De meest correcte oplossing was natuurlijk het toevoegen van een systeemaanroep aan de kernel zelf, maar hiervoor zou de kernel opnieuw moeten worden gecompileerd.

Omgeving

Alle moduletestactiviteiten werden uitgevoerd in een virtuele VirtualBox-machine met een 64-bit Linux-distributie en kernelversie 4.14.4-1. De communicatie met de machine vond plaats via SSH.

Poging #1 eenvoudige oplossing

Een paar woorden over de huidige: de huidige variabele verwijst naar een task_struct-structuur met een beschrijving van het proces in de kernel (PID, UID, GID, cmdline, naamruimten, enz.)

Het eerste idee was om eenvoudigweg de current->pid parameter van de kernelmodule naar de gewenste parameter te veranderen.

Statisch ssize_t device_read(struct bestand *filp, char *buffer, size_t lengte, loff_t * offset) ( printk("PID: %d.\n",current->pid); current->pid = 1; printk("new PID: %d.\n",huidige->pid); , )
Om de functionaliteit van de module te controleren, heb ik een programma geschreven in C++:

#erbij betrekken #erbij betrekken #erbij betrekken int main() (std::cout<< "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >>str; std::uit<< "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Laten we de module laden met de opdracht insmod, /dev/test maken en het proberen.

# ./a.out Mijn ouder-PID 293 Mijn PID 782 Mijn nieuwe PID 782
PID is niet veranderd. Dit is mogelijk niet de enige plaats waar de PID wordt gespecificeerd.

Probeer #2 extra PID-velden

Als current->pid niet de procesidentificatie is, wat is het dan wel? Een snelle blik op de getpid()-code wees op een task_struct-structuur die het Linux-proces en het pid.c-bestand in de kernelbroncode beschrijft. De vereiste functie is __task_pid_nr_ns. In de functiecode staat een oproep task->pids.pid, we zullen deze parameter wijzigen

Compileren en proberen

Sinds ik via SSH heb getest, kon ik de programma-uitvoer krijgen voordat de kernel crashte:

Mijn ouder PID 293 Mijn PID 1689 Mijn nieuwe PID 1689
Het eerste resultaat is al iets. Maar de PID is nog steeds niet veranderd.

Probeer #3 niet-exporteerbare kernelsymbolen

Een nadere blik op pid.c leverde een functie op die doet wat we nodig hebben
static void __change_pid(struct taak_struct *taak, enum pid_type type,
struct pid *nieuw)
De functie accepteert een taak waarvoor het nodig is om de PID, het PID-type en, in feite, de nieuwe PID te wijzigen. De functie creëert een nieuwe PID
struct pid *alloc_pid(struct pid_naamruimte *ns)

Deze functie accepteert alleen de naamruimte waarin de nieuwe PID zich zal bevinden. Deze ruimte kan worden verkregen met task_active_pid_ns .
Maar er is één probleem: deze kernelsymbolen worden niet door de kernel geëxporteerd en kunnen niet in modules worden gebruikt. Een geweldige heeft me geholpen bij het oplossen van dit probleem. De find_sym-functiecode wordt daar vandaan gehaald.

Statische asmlinkage void (*change_pidR)(struct task_struct *task, enum pid_type type, struct pid *pid); statische asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) ( printk(KERN_ALERT "TEST driver geladen!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... ) static ssize_t device_read(struct bestand * filp, char *buffer, size_t lengte, loff_t * offset) ( printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(current)); change_pidR(current) ,PIDTYPE_PID,newpid);printk("nieuwe PID: %d.\n",huidige->pid ... )
Compileren, lanceren

Mijn ouder PID 299 Mijn PID 750 Mijn nieuwe PID 751
PID gewijzigd! De kernel heeft automatisch een vrije PID aan ons programma toegewezen. Maar is het mogelijk om een ​​PID te gebruiken die bezet is door een ander proces, zoals PID 1? Laten we de code na de toewijzing toevoegen

Newpid->getallen.nr = 1;
Compileren, lanceren

Mijn ouder-PID 314 Mijn PID 1172 Mijn nieuwe PID 1
We krijgen echte PID 1!

Bash genereert een bug die verhindert dat het wisselen van taak met behulp van de opdracht %n werkt, maar alle andere functies werken prima.

Interessante kenmerken van processen met veranderde PID

PID 0: binnengaan kan niet afsluiten

Laten we teruggaan naar de code en de PID wijzigen in 0.

Newpid->getallen.nr = 0;
Compileren, lanceren

Mijn ouder PID284 Mijn PID 1517 Mijn nieuwe PID 0
Dus PID 0 is niet zo bijzonder? We verheugen ons, schrijven exit en...

De kanonskogel valt! De kernel definieerde onze taak als IDLE TASK en crashte simpelweg toen hij de voltooiing zag. Blijkbaar moet ons programma terugkeren naar zijn “normale” PID voordat het wordt afgesloten.

Onzichtbaar proces

Laten we teruggaan naar de code en een PID instellen die gegarandeerd niet bezet is
newpid->nummers.nr = 12345;

Compileren, lanceren

Mijn ouder PID296 Mijn PID 735 Mijn nieuwe PID 12345
Laten we eens kijken wat er in /proc zit

1 148 19 224 288 37 79 86 93 consoles fb kcore locks partities swaps versie 10 149 2 226 29 4 8 87 acpi cpuinfo bestandssystemen sleutelgebruikers meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs sleutels overige schemastat sysrq- trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 dma ioports kpagecount m trr plaatinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
Zoals we kunnen zien identificeert /proc ons proces niet, zelfs niet als we een vrije PID hebben bezet. De vorige PID staat ook niet in /proc, en dit is heel vreemd. Misschien bevinden we ons in een andere naamruimte en daarom niet zichtbaar voor main /proc. Laten we een nieuwe /proc mounten en kijken wat daar staat

1 14 18 210 25 291 738 81 9 busapparaten fs key-users sloten pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts sleutels meminfo partities stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg diversen sched_debug swaps uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys versie 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 20 8 23 29 6 8 86 klinkt cpuinfo fb ​​kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto bestandssystemen kcore loadavg net slabinfo thread-self zoneinfo
Ons proces bestaat nog steeds niet, wat betekent dat we ons in de normale naamruimte bevinden. Laten we het controleren

Ps-e | grep bash
296 pts/0 00:00:00 bash

Slechts één bash, van waaruit we het programma hebben gelanceerd. Noch de vorige PID, noch de huidige staat in de lijst.

Denk je dat het Linux-besturingssysteem automatisch voor zichzelf kan zorgen? Als alles goed werkt of als je geen niet-standaard functies nodig hebt, ja. Maar soms kan uw tussenkomst in haar werk noodzakelijk zijn.

In Linux wordt voor elk afzonderlijk programma een proces gemaakt wanneer het start. Het maakt niet uit of u het programma zelf handmatig uitvoert of dat het systeem of de kernel dit doet. Zo heeft het initialisatieprogramma, dat direct draait nadat de kernel is geladen, ook een eigen proces met ID 0. Processen in Linux kunnen worden omschreven als containers waarin alle informatie over de status en uitvoering van het programma wordt opgeslagen. Als het programma goed werkt, is alles in orde, maar als het vastloopt of als je het werk moet aanpassen, heb je mogelijk procesbeheer in Linux nodig.

Dit artikel behandelt een breed onderwerp en we bekijken de volgende mogelijkheden:

  • Bekijk lopende processen
  • Procesinformatie bekijken
  • Processen zoeken in Linux
  • Veranderende procesprioriteit
  • Beëindigen van processen
  • Het beperken van het beschikbare geheugen voor een proces

Ik kon het niet laten om de eerste punten in het artikel op te nemen, maar ze zijn heel eenvoudig en we zullen er niet in detail op ingaan. Maar al het andere lijkt misschien ingewikkeld en onvoldoende beschreven.

Laten we beginnen met het begrijpen van de voorwaarden. In wezen is elk programma een proces. Zoals ik al zei, wordt voor elk gelanceerd programma een apart proces gemaakt. Als onderdeel van een proces krijgt een programma CPU-tijd, RAM en andere systeembronnen toegewezen. Elk proces heeft zijn eigen identificatie, proces-ID of eenvoudigweg PID, en Linux-processen worden er meestal door geïdentificeerd. De PID wordt niet willekeurig bepaald; zoals ik al zei, het initialisatieprogramma ontvangt PID 1, en elk volgend gelanceerd programma ontvangt er nog één. Zo bereikt de PID van gebruikersprogramma's enkele duizenden.

In feite zijn Linux-processen niet zo abstract als ze je nu lijken. Je kunt proberen ze te voelen. Open uw bestandsbeheerder, ga naar de hoofdmap en open vervolgens de map /proc. Zie je hier een aantal cijfers? Dit is dus alles: de PID van alle lopende processen. Elk van deze mappen bevat alle informatie over het proces.

Laten we bijvoorbeeld eens kijken naar de map van proces 1. De map bevat andere submappen en veel bestanden. Het cmdline-bestand bevat informatie over de opdracht voor het starten van het proces:

cat /proc/1/cmdline

/usr/lib/systemd/systemd

Omdat ik het Systemd-initialisatiesysteem gebruik, wordt het eerste proces ervoor gestart. Je kunt alles doen met de map /proc. Maar dit is erg lastig, vooral gezien het aantal actieve processen in het systeem. Daarom zijn er speciale hulpprogramma's om de noodzakelijke taken uit te voeren. Laten we verder gaan met het overwegen van hulpprogramma's waarmee u procesbeheer in Linux kunt implementeren.

Procesbeheer onder Linux

Linux heeft een zeer groot aantal hulpprogramma's voor het oplossen van verschillende procesbeheertaken. Deze omvatten multifunctionele oplossingen als htop, top, maar ook eenvoudige hulpprogramma's, bijvoorbeeld ps, kill, killall, who, etc. Grafische hulpprogramma's zal ik in dit artikel niet bespreken, en ik zal ook top niet overwegen. De eerste is omdat het te simpel is, de tweede is omdat htop beter is. We zullen ons concentreren op het werken met het htop-programma en zijn analogen in de vorm van hulpprogramma's in GNU-stijl, één hulpprogramma - één functie.

Laten we htop installeren als je het nog niet hebt geïnstalleerd. In Ubuntu gebeurt dit als volgt:

sudo apt installeer htop

Op andere distributies hoeft u alleen maar uw pakketbeheerder te gebruiken. De pakketnaam is hetzelfde.

Bekijk lopende processen

Dit is een heel eenvoudige taak en ook gemakkelijk op te lossen. Daar zijn veel hulpprogramma's voor, variërend van de gebruikelijke ps tot meer geavanceerde interactieve top, htop enzovoort.

Nadat we htop hebben geopend, zien we onmiddellijk een lijst met actieve processen. Natuurlijk worden hier niet alle Linux-processen weergegeven, er zijn er veel in het systeem, je weet het al, ze passen niet allemaal op één scherm. Standaard worden processen weergegeven die als uw gebruiker worden uitgevoerd:

U kunt de volgende informatie over het proces bekijken:

  • PID- procesidentificatie
  • GEBRUIKER- de gebruiker van wie het proces is gestart
  • PRI- Linux-procesprioriteit op kernelniveau (meestal NI+20)
  • NI- procesuitvoeringsprioriteit van -20 tot 19
  • S- processtatus
  • CPU- CPU-bronnen gebruikt
  • MEM- gebruikt geheugen
  • TIJD- proceslooptijd

U kunt extra parameters aan het display toevoegen, maar dit zijn de belangrijkste. U kunt parameters toevoegen via het Setup-menu. Daar is alles heel eenvoudig, lees de tips en volg de aanwijzingen. De PPID-parameter wordt bijvoorbeeld toegevoegd:

Een heel belangrijk kenmerk van het programma is dat je processen in Linux kunt sorteren op basis van de gewenste parameter. Klik gewoon op de naam van de parameter, deze wordt groen gemarkeerd en het sorteren wordt uitgevoerd. Als u bijvoorbeeld wilt zien in welke volgorde de processen zijn gestart, sorteert u op PID:

Er is ook een interessante optie om processen in een boom te ordenen. U kunt zien welk proces een bepaald proces heeft gestart. Druk op de F5-knop om de boom weer te geven:

Je kunt bijna dezelfde acties uitvoeren met het ps-programma. Alleen hier is er niet zo'n handige interactieve modus. Alles gebeurt met behulp van opties.

Laten we eens kijken naar de belangrijkste opties die we zullen gebruiken:

  • -e- informatie over alle processen weergeven
  • -A- informatie weergeven over alle meest gevraagde processen
  • -T- toon alleen processen van deze terminal
  • -P- toon alleen informatie over het opgegeven proces
  • -u- toon processen van alleen een specifieke gebruiker

Kortom, om alle momenteel actieve processen in Linux te bekijken, gebruikt u een combinatie van aux-opties:

Het programma toont allemaal dezelfde parameters, alleen is er geen interactieve interface. Je denkt dat het onmogelijk is om processen hier te sorteren, maar je hebt het mis: het is mogelijk. Hiervoor bestaat een sorteeroptie. U kunt ze op elk veld sorteren, bijvoorbeeld:

ps aux --sort=%mem

De lijst wordt in omgekeerde volgorde gesorteerd, met meer waarden onderaan en minder bovenaan. Als je het omgekeerd moet doen, voeg dan een min toe:

ps aux --sort=-%cpu

Linux-procesprioriteiten of andere parameters kunnen als sorteerveld worden gebruikt. U kunt de uitvoer ook inkorten als u niet alle informatie hoeft weer te geven:

Het lijkt erop dat ps niet de mogelijkheid heeft om bomen te verwerken. Maar niet echt, hier is een apart commando voor:

Processen zoeken in Linux

Een lijst met processen is goed. Maar soms, wanneer een proces bevroren is en we het Linux-proces moeten beëindigen of er acties mee moeten uitvoeren, moeten we dit proces uit de lijst selecteren, de PID en informatie erover achterhalen.

Om het Linux-proces in htop te vinden, kunt u de F3-knop gebruiken. Druk op F3 en typ het gewenste woord. Om vervolgens naar het volgende item te gaan, drukt u op F2 of Esc om de zoekopdracht te voltooien:

U kunt ook het htop-filter gebruiken om naar processen in htop te zoeken. Druk op F4, voer een woord in en alleen Linux-processen waarvan de naam dat woord bevat, worden weergegeven.

Er is geen filtering in het ps-hulpprogramma, maar we kunnen het grep-hulpprogramma gebruiken, waarbij de uitvoer van ps ernaar wordt omgeleid om het Linux-proces te vinden:

ps aux | grep chroom

Dit is een veelgebruikt commando.

Veranderende procesprioriteit

Linux-procesprioriteit betekent hoeveel meer CPU-tijd aan dat proces zal worden besteed in vergelijking met andere. Op deze manier kunnen we heel fijn afstemmen welk programma sneller en welk langzamer zal draaien. De prioriteitswaarde kan variëren van 19 (minimale prioriteit) tot -20 - maximale prioriteit van het Linux-proces. Bovendien kun je met de rechten van een gewone gebruiker de prioriteit verlagen, maar om deze te verhogen heb je superuser-rechten nodig.

htop gebruikt de Nice-parameter om de prioriteit te regelen. Laat me u eraan herinneren dat Priv slechts een amendement is, in de meeste gevallen is het 20 meer dan Nice. Om de prioriteit van een proces te wijzigen, plaatst u eenvoudigweg de cursor erop en drukt u op F7 om het aantal te verlagen (de prioriteit te verhogen) of op F8 om het aantal te verlagen. verhoog het aantal.

Maar om deze taak van het beheren van Linux-processen op te lossen, is het niet nodig om htop te gebruiken. Je kunt alles doen met andere commando's. Bijvoorbeeld het mooie commando. Hiermee kunt u de prioriteit opgeven voor het te starten proces:

nice -n 10 apt-get-upgrade

Of verander de prioriteit voor een bestaande met zijn pid:

renice -n 10 -p 1343

Processen beëindigen in Linux

Als een proces vastloopt en niet meer reageert, moet het worden beëindigd. Om in htop een Linux-proces te beëindigen, plaatst u eenvoudigweg de cursor op het proces en drukt u op F9:

Het systeem gebruikt bepaalde signalen om processen te besturen. Er zijn signalen die aangeven dat het proces moet worden beëindigd. Hier zijn enkele basissignalen:

  • SIGKILL- vraag het proces om de gegevens op te slaan en te beëindigen
  • SIGTERM- Beëindig het proces onmiddellijk, zonder op te slaan

Over het algemeen zijn er enkele tientallen signalen, maar we zullen ze niet in overweging nemen. Laten we het SIGKILL-signaal verzenden:

Je kunt ook het kill-hulpprogramma gebruiken:

Je kunt een proces ook op naam beëindigen:

dood alle chroom

Procesbeperking

Met procesbeheer in Linux heb je vrijwel alles onder controle. Je hebt al gezien wat er gedaan kan worden, maar er kan nog meer gedaan worden. Met behulp van de opdracht ulimit en het configuratiebestand /etc/security/limits.conf kunt u de toegang van processen tot systeembronnen zoals geheugen, bestanden en de processor beperken. U kunt bijvoorbeeld het Linux-procesgeheugen, het aantal bestanden, enz. beperken.

De vermelding in het bestand ziet er als volgt uit:

<домен> <тип> <элемент> <значение>

  • domein- gebruikersnaam, groepsnaam of UID
  • type- soort beperkingen - zacht of hard
  • element- een hulpbron die beperkt zal zijn
  • betekenis- vereiste limiet

Harde limieten worden bepaald door de superuser en kunnen niet worden gewijzigd door gewone gebruikers. Zachte limieten kunnen door gebruikers worden gewijzigd met behulp van de opdracht ulimit.

Laten we eens kijken naar de belangrijkste beperkingen die op processen kunnen worden toegepast:

  • geen bestand
  • als- maximale hoeveelheid RAM
  • stapel- maximale stapelgrootte
  • CPU- maximale processortijd
  • nproc- maximaal aantal processorkernen
  • sloten- aantal vergrendelde bestanden
  • Leuk- maximale procesprioriteit

Laten we bijvoorbeeld de processortijd voor de processen van gebruiker Sergiy beperken:

sergiy harde nproc 20

U kunt de beperkingen voor een specifiek proces bekijken in de map proc:

cat /proc/PID/limieten

Maximale CPU-tijd onbeperkt onbeperkt seconden
Maximale bestandsgrootte onbeperkt onbeperkt bytes
Maximale gegevensgrootte onbeperkt onbeperkt bytes
Maximale stapelgrootte 204800, onbeperkt aantal bytes
Maximale kernbestandsgrootte 0 onbeperkt bytes
Max. inwoner ingesteld onbeperkt onbeperkt bytes
Max. aantal processen 23562 23562 processen
Max. geopende bestanden 1024 4096 bestanden
Max. vergrendeld geheugen 18446744073708503040 18446744073708503040 bytes
Max. adresruimte onbeperkt onbeperkt bytes
Max. bestandsvergrendelingen onbeperkt onbeperkte vergrendelingen
Max. wachtende signalen 23562 23562 signalen
Maximale berichtwachtrijgrootte 819200 819200 bytes
Max. mooie prioriteit 0 0
Maximale realtime prioriteit 0 0
Max realtime time-out onbeperkt onbeperkt ons

Beperkingen die op deze manier worden gewijzigd, worden van kracht na een herstart. Maar we kunnen ook limieten instellen voor de huidige shell en de processen die deze creëert met behulp van de opdracht ulimit.

Dit zijn de opdrachtopties:

  • -S- zachte grens
  • -H- harde grens
  • -A- toon alle informatie
  • -F- maximale grootte van gemaakte bestanden
  • -N- maximaal aantal geopende bestanden
  • -S- maximale stapelgrootte
  • -T- maximale hoeveelheid processortijd
  • -u- maximaal aantal actieve processen
  • -v- maximale hoeveelheid virtueel geheugen

We kunnen bijvoorbeeld een nieuwe limiet instellen voor het aantal bestanden dat kan worden geopend:

Laten we nu eens kijken:

Laten we de RAM-limiet instellen:

ulimit -Sv 500000

Ik wil u eraan herinneren dat deze beperking van toepassing is op alle programma's die in deze terminal worden uitgevoerd.

conclusies

Dat is alles. Nu zal het beheren van processen in Linux geen problemen opleveren. Wij hebben dit onderwerp uitvoerig onderzocht. Als je vragen of suggesties hebt om aan het artikel toe te voegen, schrijf dan in de reacties!

UNIX-besturingssysteem Robachevsky Andrey M.

Proces-ID (PID)

Elk proces heeft een unieke PID, waardoor de systeemkernel onderscheid kan maken tussen processen. Wanneer een nieuw proces wordt aangemaakt, wijst de kernel het de volgende vrije (dat wil zeggen, niet aan enig proces gekoppelde) identificatie toe. Identificatiegegevens worden in oplopende volgorde toegekend, d.w.z. De ID van het nieuwe proces is groter dan de ID van het proces dat ervoor is gemaakt. Als de ID de maximale waarde bereikt, ontvangt het volgende proces de minimale vrije PID en herhaalt de cyclus zich. Wanneer een proces wordt afgesloten, geeft de kernel de identificatie vrij die het bezette.

Uit het boek Architectuur van het UNIX-besturingssysteem auteur Bach Maurice J

4.4 DE COMPONENTNAAM VAN EEN BESTAND (ZOEKPAD) OMZETTEN IN EEN INDEX-ID De initiële verwijzing naar een bestand is via de gekwalificeerde naam (zoekpad), zoals bij de opdrachten open, chdir (map wijzigen) of link. Omdat binnen het systeem de kernel met indexen werkt, niet met

Uit het boek Een zeldzaam beroep auteur Zuev Evgeniy

Wat is een identiteitsbewijs? Naast onduidelijkheden in de syntaxis kwamen er al snel andere problemen aan het licht. Het is moeilijker om ze met voorbeelden te laten zien, dus je zult ze in woorden moeten uitleggen. De syntaxis van de C++-taal is ook in een ander opzicht lastig. Kortom, direct

Uit het boek Programmeren auteur Kozlova Irina Sergejevna

11. Identificatie. Trefwoorden Een identificatie is een reeks cijfers, letters en speciale tekens. In dit geval is het eerste teken een letter of een speciaal teken. Om identificatiegegevens te verkrijgen, kunt u kleine letters of hoofdletters van het Latijnse alfabet gebruiken.

Uit het boek 200 beste programma's voor internet. Populaire tutorial auteur Krainsky I

Proces Guardian XP Fabrikant: T.A.S. Onafhankelijk programmeren (http://www.tas-independent-programming.com).Status: gratis.Downloadlink: http://www.tas-independent-programming.com/cgi-bin/countdown.pl?Guardian Grootte: 2,4 MB. Het belangrijkste doel van dit hulpprogramma is het beheren van processen die op de computer worden uitgevoerd.

Uit het boek Microsoft Visual C++ en MFC. Programmeren voor Windows 95 en Windows NT auteur Frolov Alexander Vjatsjeslavovitsj

Identificatie van open bestand De klasse CFile bevat een gegevenselement m_hFile van het type UINT. Het slaat de identificatie van het geopende bestand op. Als u een object van de klasse CFile hebt gemaakt, maar nog geen bestand hebt geopend, wordt de constante hFileNull in m_hFile geschreven. Meestal is dit niet nodig

Uit het boek UNIX: Procescommunicatie auteur Stevens Willem Richard

Transactie-ID Een ander onderdeel van de time-out- en hertransmissiestrategie is het gebruik van transactie-ID's (XID's) om onderscheid te maken tussen clientverzoeken en serverreacties. Wanneer een client een RPC-functie aanroept, wijst de bibliotheek deze toe

Uit het boek TCP/IP Architecture, Protocols, Implementation (inclusief IP versie 6 en IP Security) door Faith Sydney M

16.7 Tijdstempel en bericht-ID Bij het ontvangen van e-mail is het interessant om te weten op welk tijdstip deze is verzonden en ontvangen. SMTP voegt deze informatie toe aan het doorgestuurde bericht. Bovendien houdt dit protocol alle hosts bij die het mailbericht hebben verzonden en de tijd

Uit het boek Adobe Audition 3 tutorial auteur auteur onbekend

Dynamic EQ (proces) Het Dynamic EQ-effect varieert de hoeveelheid filtering in de loop van de tijd. In de eerste helft van de golf kun je bijvoorbeeld de hoge frequenties versterken, en in de tweede helft kun je de breedte van de betreffende frequentieband veranderen. Het Dynamic EQ-venster heeft drie tabbladen: Versterking, Frequentie en Q (bandbreedte). 1. Frequentiegrafiek

Uit het boek PHP Reference van de auteur

Pan/Expander (proces) Met het Pan/Expand-effect kunt u het middenkanaal (monocomponent) van een stereosignaal verplaatsen en de stereoscheiding tussen de linker- en rechterkanalen verbreden of verkleinen met behulp van de midden- en omliggende kanalen van de stereo-opname,

Uit het boek Applicatieontwikkeling in de Linux-omgeving. Tweede druk auteur Johnson Michaël K.

Stretch (proces) Met het Stretch-effect kunt u de toonhoogte (toonhoogte) van een audiosignaal, het tempo of beide wijzigen. U kunt dit effect bijvoorbeeld gebruiken om de toonhoogte van een soundtrack te verhogen zonder de duur ervan te veranderen, of, omgekeerd, de duur te veranderen zonder de duur te veranderen

Uit het boek Firebird DATABASE DEVELOPER'S GUIDE van Borri Helen

Sessie-ID De sessie-ID is dus de naam van de tijdelijke opslag die zal worden gebruikt om sessiegegevens op te slaan tussen scriptuitvoeringen. Eén SID - één opslag. Geen SID, geen opslag en omgekeerd. Hoe verhouden de ID en de naam zich tot elkaar?

Uit het boek UNIX-besturingssysteem auteur Robachevski Andrej M.

10.2.1. Proces-ID en oorsprong Twee van de meest fundamentele kenmerken zijn het proces-ID, of pid, en de ID van het bovenliggende proces. De pid is een positief geheel getal dat op unieke wijze identificeert

Uit het boek van de auteur

10.2.3. Bestandssysteem uid In zeer speciale gevallen kan het nodig zijn dat een programma zijn root-rechten behoudt voor alles behalve toegang tot het bestandssysteem, waarvoor het de uid van de gebruiker gebruikt. Oorspronkelijk gebruikt in Linux NFS-ruimteserver

Uit het boek van de auteur

Domein-ID Wanneer u een domein in een database aanmaakt, moet u een domein-ID opgeven die globaal uniek is in de database. Ontwikkelaars gebruiken vaak een voor- of achtervoegsel op domein-ID's om de documentatie te verbeteren. Bijvoorbeeld: MAKEN

Uit het boek van de auteur

Uit het boek van de auteur

Parent Process ID (PPID) De identificatie van het proces dat dit heeft voortgebracht

Hoe het ook zij, sommige toepassingen in Linux soms bevriezen ze. Tegelijkertijd zijn er situaties waarin de applicatie helemaal niet reageert of zo langzaam werkt dat het niet mogelijk is om het werk correct te beëindigen. Om snel uit de resulterende situatie te komen, kunt u dit proces 'doden'. Gebruik hiervoor de commando's doden En dood. Nu zullen we uitzoeken hoe we deze commando's kunnen gebruiken, de PID van het proces vinden en het SIGKILL-signaal verzenden.

Laten we, om verwarring te voorkomen, afspreken dat we met proces een programma bedoelen dat in het systeem wordt gelanceerd. Als u bijvoorbeeld meerdere Mozilla Firefox-browservensters actief heeft, betekent dit dat er drie processen actief zijn.

Bepaal de PID van een proces - pidof-commando

PID— unieke procesidentificatie in het systeem Linux. Om een ​​proces correct te stoppen, moet u eerst de PID ervan bepalen. Gebruik hiervoor de opdrachten ps en grep. Op zijn beurt ps-opdracht is ontworpen om een ​​lijst met actieve processen in het systeem en informatie daarover weer te geven. grep-opdracht draait gelijktijdig met ps (in een kanaal) en zal de resultaten van het ps-commando doorzoeken. U kunt alle processen weergeven door op de opdrachtregel uit te voeren:

Uiteraard kan PID ook worden bepaald met behulp van bovenkant. Maar in de meeste gevallen is het aantal processen te groot (en verandert het dynamisch bovenaan), dus het is niet zo eenvoudig om de PID snel en correct te bepalen. Dit is precies waarvoor het grep-commando wordt gebruikt. Om bijvoorbeeld het Google Chrome-browserproces te beëindigen, moet u de volgende opdracht uitvoeren:

p.s. | grep chroom

[ ////// ~]$ ps axu | grep chroom
itechf2 20474 2,7 1,5 938416 120136 tty2 Sl+ 11:07 0:00 /opt/google/chrome/chrome

In ons geval is 20474 de gewenste PID. Een eenvoudigere manier is om de opdracht te gebruiken pidof, moet u de procesnaam opgeven. Bijvoorbeeld:

[ ///// ~]$ pidof chroom
20728 20706 20668 20647 20586 20574 20553 20508 20474

Beëindig een proces in Linux - commando's kill en killall

Beëindig een proces in het besturingssysteem Linux, als u de PID kent, kunt u de opdracht gebruiken doden. Het is de moeite waard om te weten en te begrijpen: het kill-commando is ontworpen om een ​​signaal naar een proces te sturen. Als we niet specificeren welk signaal we moeten verzenden, wordt standaard het SIGTERM-signaal (van de woordbeëindiging) verzonden. SIGTERM vertelt het proces om te beëindigen. Elk signaal heeft zijn eigen nummer. SIGTERM heeft nummer 15. Een lijst met alle signalen (en hun nummers) die het kill-commando kan verzenden, kan worden verkregen door het uitvoeren van doden -l . Om het SIGKILL-signaal (genummerd 9) naar proces 2811 te sturen, voert u het volgende uit op de opdrachtregel:

Tegelijkertijd stopt het SIGTERM-signaal het proces mogelijk niet (bijvoorbeeld wanneer het signaal wordt onderschept of geblokkeerd), maar SIGKILL beëindigt het proces altijd, omdat het niet kan worden onderschept of genegeerd.

killall-commando in Linux is ontworpen om alle processen met dezelfde naam te "doden". Dit is handig omdat we de PID van het proces niet hoeven te weten. We willen bijvoorbeeld alle processen met de naam chrome sluiten. Uitvoeren in terminal:

Het killall-commando verzendt, net als kill, standaard het SIGTERM-signaal. Om nog een signaal te verzenden, moet u de optie gebruiken -S . Bijvoorbeeld:



In dit artikel zullen we proberen een kernelmodule te maken die de PID van een reeds actief proces in Linux kan veranderen, en ook experimenteren met processen die een gewijzigde PID hebben ontvangen.


Waarschuwing: Het wijzigen van de PID is een niet-standaardproces en kan onder bepaalde omstandigheden tot kernelpaniek leiden.

Onze testmodule zal het /dev/test character device implementeren, dat de PID van het proces zal veranderen wanneer er van gelezen wordt. Dank aan dit artikel voor een voorbeeld van het implementeren van een karakterapparaat. De volledige modulecode vindt u aan het einde van het artikel. De meest correcte oplossing was natuurlijk het toevoegen van een systeemaanroep aan de kernel zelf, maar hiervoor zou de kernel opnieuw moeten worden gecompileerd.

Omgeving

Alle moduletestactiviteiten werden uitgevoerd in een virtuele VirtualBox-machine met een 64-bit Linux-distributie en kernelversie 4.14.4-1. De communicatie met de machine vond plaats via SSH.

Poging #1 eenvoudige oplossing

Een paar woorden over de huidige: de huidige variabele verwijst naar een task_struct-structuur met een beschrijving van het proces in de kernel (PID, UID, GID, cmdline, naamruimten, enz.)

Het eerste idee was om eenvoudigweg de current->pid parameter van de kernelmodule naar de gewenste parameter te veranderen.

Statisch ssize_t device_read(struct bestand *filp, char *buffer, size_t lengte, loff_t * offset) ( printk("PID: %d.\n",current->pid); current->pid = 1; printk("new PID: %d.\n",huidige->pid); , )
Om de functionaliteit van de module te controleren, heb ik een programma geschreven in C++:

#erbij betrekken #erbij betrekken #erbij betrekken int main() (std::cout<< "My parent PID " << getppid() << std::endl; std::cout << "My PID " << getpid() << std::endl; std::fstream f("/dev/test",std::ios_base::in); if(!f) { std::cout << "f error"; return -1; } std::string str; f >>str; std::uit<< "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Laten we de module laden met de opdracht insmod, /dev/test maken en het proberen.

# ./a.out Mijn ouder-PID 293 Mijn PID 782 Mijn nieuwe PID 782
PID is niet veranderd. Dit is mogelijk niet de enige plaats waar de PID wordt gespecificeerd.

Probeer #2 extra PID-velden

Als current->pid niet de procesidentificatie is, wat is het dan wel? Een snelle blik op de getpid()-code wees op een task_struct-structuur die het Linux-proces en het pid.c-bestand in de kernelbroncode beschrijft. De vereiste functie is __task_pid_nr_ns. In de functiecode staat een oproep task->pids.pid, we zullen deze parameter wijzigen

Compileren en proberen

Sinds ik via SSH heb getest, kon ik de programma-uitvoer krijgen voordat de kernel crashte:

Mijn ouder PID 293 Mijn PID 1689 Mijn nieuwe PID 1689
Het eerste resultaat is al iets. Maar de PID is nog steeds niet veranderd.

Probeer #3 niet-exporteerbare kernelsymbolen

Een nadere blik op pid.c leverde een functie op die doet wat we nodig hebben
static void __change_pid(struct taak_struct *taak, enum pid_type type,
struct pid *nieuw)
De functie accepteert een taak waarvoor het nodig is om de PID, het PID-type en, in feite, de nieuwe PID te wijzigen. De functie creëert een nieuwe PID
struct pid *alloc_pid(struct pid_naamruimte *ns)

Deze functie accepteert alleen de naamruimte waarin de nieuwe PID zich zal bevinden. Deze ruimte kan worden verkregen met task_active_pid_ns .
Maar er is één probleem: deze kernelsymbolen worden niet door de kernel geëxporteerd en kunnen niet in modules worden gebruikt. Een geweldige heeft me geholpen bij het oplossen van dit probleem. De find_sym-functiecode wordt daar vandaan gehaald.

Statische asmlinkage void (*change_pidR)(struct task_struct *task, enum pid_type type, struct pid *pid); statische asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) ( printk(KERN_ALERT "TEST driver geladen!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... ) static ssize_t device_read(struct bestand * filp, char *buffer, size_t lengte, loff_t * offset) ( printk("PID: %d.\n",current->pid); struct pid* newpid; newpid = alloc_pidR(task_active_pid_ns(current)); change_pidR(current) ,PIDTYPE_PID,newpid);printk("nieuwe PID: %d.\n",huidige->pid ... )
Compileren, lanceren

Mijn ouder PID 299 Mijn PID 750 Mijn nieuwe PID 751
PID gewijzigd! De kernel heeft automatisch een vrije PID aan ons programma toegewezen. Maar is het mogelijk om een ​​PID te gebruiken die bezet is door een ander proces, zoals PID 1? Laten we de code na de toewijzing toevoegen

Newpid->getallen.nr = 1;
Compileren, lanceren

Mijn ouder-PID 314 Mijn PID 1172 Mijn nieuwe PID 1
We krijgen echte PID 1!

Bash genereert een bug die verhindert dat het wisselen van taak met behulp van de opdracht %n werkt, maar alle andere functies werken prima.

Interessante kenmerken van processen met veranderde PID

PID 0: binnengaan kan niet afsluiten

Laten we teruggaan naar de code en de PID wijzigen in 0.

Newpid->getallen.nr = 0;
Compileren, lanceren

Mijn ouder PID284 Mijn PID 1517 Mijn nieuwe PID 0
Dus PID 0 is niet zo bijzonder? We verheugen ons, schrijven exit en...

De kanonskogel valt! De kernel definieerde onze taak als IDLE TASK en crashte simpelweg toen hij de voltooiing zag. Blijkbaar moet ons programma terugkeren naar zijn “normale” PID voordat het wordt afgesloten.

Onzichtbaar proces

Laten we teruggaan naar de code en een PID instellen die gegarandeerd niet bezet is
newpid->nummers.nr = 12345;

Compileren, lanceren

Mijn ouder PID296 Mijn PID 735 Mijn nieuwe PID 12345
Laten we eens kijken wat er in /proc zit

1 148 19 224 288 37 79 86 93 consoles fb kcore locks partities swaps versie 10 149 2 226 29 4 8 87 acpi cpuinfo bestandssystemen sleutelgebruikers meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs sleutels overige schemastat sysrq- trigger vmstat 11 16 208 24 291 6 81 89 buddyinfo devices interrupts kmsg modules scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 bus diskstats iomem kpagecgroup mounts self thread-self 13 176 210 26 3 737 83 90 dma ioports kpagecount m trr plaatinfo timer_list 139 18 22 27 30 76 84 91 cmdline driver irq kpageflags net softirqs tty 14 182 222 28 31 78 85 92 config.gz execdomains kallsyms loadavg pagetypeinfo stat uptime
Zoals we kunnen zien identificeert /proc ons proces niet, zelfs niet als we een vrije PID hebben bezet. De vorige PID staat ook niet in /proc, en dit is heel vreemd. Misschien bevinden we ons in een andere naamruimte en daarom niet zichtbaar voor main /proc. Laten we een nieuwe /proc mounten en kijken wat daar staat

1 14 18 210 25 291 738 81 9 busapparaten fs key-users sloten pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrupts sleutels meminfo partities stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg diversen sched_debug swaps uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys versie 12 16 20 226 288 4 79 85 acpi consoles execdomains irq kpagecount mounts scsi sysrq-trigger vmallocinfo 13 17 20 8 23 29 6 8 86 klinkt cpuinfo fb ​​kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto bestandssystemen kcore loadavg net slabinfo thread-self zoneinfo
Ons proces bestaat nog steeds niet, wat betekent dat we ons in de normale naamruimte bevinden. Laten we het controleren

Ps-e | grep bash
296 pts/0 00:00:00 bash

Slechts één bash, van waaruit we het programma hebben gelanceerd. Noch de vorige PID, noch de huidige staat in de lijst.