Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • OS
  • Cum să omorâți un proces în Linux. Managementul proceselor în Linux Cum să aflați codul cod al unui proces Linux

Cum să omorâți un proces în Linux. Managementul proceselor în Linux Cum să aflați codul cod al unui proces Linux

Practic, ne uităm la PID pentru a ucide programul care nu răspunde și este similar cu Managerul de activități Windows.

GUI Linux oferă, de asemenea, aceeași caracteristică, dar CLI este o modalitate eficientă de a efectua operația de ucidere.

Ce este ID-ul procesului PID?

PID reprezintă numărul de identificare a procesului, care este utilizat în mod obișnuit de majoritatea nucleelor ​​de sisteme de operare, cum ar fi Linux, Unix, macOS și Windows.

Acesta este un număr unic de identificare care este atribuit automat fiecărui proces atunci când este creat în sistemul de operare.

Un proces este o instanță executabilă a unui program.

De fiecare dată, ID-ul procesului va primi modificări la toate procesele, cu excepția init, deoarece init este întotdeauna primul proces din sistem și este strămoșul tuturor celorlalte procese. Acest PID este 1.

Valoarea PID maximă implicită este 32.768.

# cat/proc/sys/kernel/pid_max

Pe sistemele pe 32 de biți, 32768 este valoarea maximă, dar putem seta orice valoare până la 2^22 (aproximativ 4 milioane) pe sistemele pe 64 de biți.

Vă puteți întreba de ce avem nevoie de atâtea PID-uri? pentru că nu putem reutiliza PID-ul imediat. De asemenea, pentru a evita eventualele erori.

PID-ul pentru rularea proceselor în sistem poate fi găsit folosind următoarele nouă metode, cum ar fi comanda pidof, comanda pgrep, comanda ps, comanda pstree, comanda ss, comanda netstat, comanda lsof, comanda fuser și comanda systemctl.

  • pidof: pidof - găsiți ID-ul de proces al unui program care rulează.
  • pgrep: pgre - Căutați sau procesați semnale pe baza numelui și a altor atribute.
  • ps: ps - raportează un instantaneu al proceselor curente.
  • pstree: pstree - afișează un arbore de proces.
  • ss: ss este folosit pentru a afișa statisticile socketului.
  • netstat: netstat afișează o listă de socket-uri deschise.
  • lsof: lsof - listă de fișiere deschise.
  • fuzor: ID-uri de proces într-o listă de termeni a tuturor proceselor care deschid unul sau mai multe fișiere
  • systemctl: systemctl - Gestionează sistemul systemd și managerul de servicii

În acest tutorial ne vom uita la ID-ul procesului Apache pentru verificare.

Metoda-1: Folosind comanda pidof

pidof este folosit pentru a găsi ID-ul de proces al unui program care rulează.

Tipărește acești identificatori la ieșirea standard.

Pentru a demonstra acest lucru, vom afla ID-ul procesului Apache2 dintr-un sistem Debian 9.

# pidof apache2 3754 2594 2365 2364 2363 2362 2361

Din cele de mai sus, este posibil să vă fie dificil să identificați ID-ul procesului, deoarece arată toate PID (inclusiv părinte și copil) cu numele procesului.

Prin urmare, trebuie să aflăm PID-ul părinte (PPID) pe care îl căutăm.

Acesta ar putea fi numărul unu. În cazul meu, este 3754 și este afișat în ordine descrescătoare.

Metoda-2: Utilizarea comenzii pgrep

pgrep analizează procesele curente și listează ID-urile proceselor care se potrivesc cu criteriile de selecție pentru stdout.

# pgrep apache2 2361 2362 2363 2364 2365 2594 3754

Aceasta este, de asemenea, similară cu rezultatul de mai sus, dar aceasta reduce rezultatele în ordine crescătoare, ceea ce indică în mod clar că PID-ul părinte este ultimul.

În cazul meu este 3754.

Notă. Dacă aveți mai multe ID-uri de proces, este posibil să aveți probleme la identificarea ID-ului procesului părinte atunci când utilizați comanda pidof & pgrep.

Metoda-3: Utilizarea comenzii pstree

pstree arată procesele care rulează ca un arbore.

Arborele este înrădăcinat fie la pid, fie la init dacă pid este omis.

Dacă este specificat un nume de utilizator în comanda pstree, atunci este afișat întregul proces deținut de utilizatorul corespunzător.

pstree combină vizual ramuri identice punându-le între paranteze drepte și prefixându-le cu numărul de repetări.

#pstree -p | grep "apache2" |- apache2(3754)-+-apache2(2361) | |-apache2(2362) | |-apache2(2363) | |-apache2(2364) | |-apache2(2365) | `-apache2(2594)

Pentru a obține un singur proces părinte, utilizați următorul format.

#pstree -p | grep "apache2" | cap -1 |- apache2(3754)-+-apache2(2361)

Comanda pstree este foarte simplă, deoarece separă procesele părinte și secundare separat

Metoda-4: Folosind comanda ps

ps afișează informații despre selecția proceselor active.

Afișează ID-ul procesului (pid = PID), terminalul asociat procesului (tname = TTY), timpul cumulat al CPU în format hh:mm:ss (time = TIME) și numele executabilului (ucmd = cmd).

În mod implicit, fișierul de ieșire nu este sortat.

# ps aux | grep "apache2" www-data 2361 0,0 0,4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start www-data 2362 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start www-data 2363 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start www-data 2364 0.0 0.4 302652 9732 ? S 06:25 0:00 /usr/sbin/apache2 -k start www-data 2365 0.0 0.4 302652 8400 ? S 06:25 0:00 /usr/sbin/apache2 -k start www-data 2594 0.0 0.4 302652 8400 ? S 06:55 0:00 /usr/sbin/apache2 -k start rădăcină 3754 0,0 1,4 302580 29324 ? Ss Dec11 0:23 /usr/sbin/apache2 -k start root 5648 0,0 0,0 12784 940 puncte/0 S+ 21:32 0:00 grep apache2

Din rezultatul de mai sus, putem identifica cu ușurință ID-ul procesului părinte (PPID) pe baza datei de începere a procesului.

În cazul meu, procesul apache2 a fost pornit de @Dec11, care este părintele, iar ceilalți sunt copiii. Apache2 PID este 3754.

Metoda-5: Folosind comanda ss

ss este folosit pentru a afișa statisticile socketului.

Vă permite să afișați informații similare cu netstat.

Poate afișa mai multe informații TCP și stare decât alte instrumente.

Poate afișa statistici pentru toate tipurile de socketuri, cum ar fi PACKET, TCP, UDP, DCCP, RAW, domeniul Unix etc.

# ss -tnlp | grep apache2 LISTEN 0 128:::80:::* utilizatori:(("apache2",pid=3319,fd=4),("apache2",pid=3318,fd=4),("apache2",("apache2", pid=3317,fd=4))

Metoda-6: Folosind comanda netstat

netstat - Afișează conexiuni de rețea, tabele de rutare, statistici de interfață, conexiuni masquerading și multicast.

În mod implicit, netstat afișează o listă de socket-uri deschise.

Dacă nu specificați nicio familie de adrese, socketurile active ale tuturor familiilor de adrese configurate vor fi listate.

Acest program este depășit. Înlocuitorul pentru netstat este ss.

# netstat -tnlp | grep apache2 tcp6 0 0:::80:::* ASCULTATI 3317/apache2

Metoda-7: Utilizarea comenzii lsof

lsof - lista de fișiere deschise.

Comanda lsof Linux afișează informații despre fișierele deschise proceselor care rulează pe sistem.

# lsof -i -P | grep apache2 apache2 3317 root 4u IPv6 40518 0t0 TCP *:80 (ASCULTARE) apache2 3318 www-data 4u IPv6 40518 0t0 TCP *:80 (ASCULTARE) apache2 3319 www-data 4u IPv6 40518 0t0 TCP *:80

Metoda-8: Folosind comanda cuptorului

Utilitarul cuptorului trebuie să scrie la ieșirea standard ID-urile de proces ale proceselor care rulează pe sistemul local care deschid unul sau mai multe fișiere numite.

# fuzor -v 80/tcp COMANDA DE ACCES PID UTILIZATOR 80/tcp: root 3317 F.... apache2 www-data 3318 F.... apache2 www-data 3319 F.... apache2

Metoda-9: Folosind comanda systemctl

systemctl - Gestionează sistemul systemd și managerul de servicii.

Acesta este un înlocuitor pentru vechiul sistem de management SysV și Cele mai multe sisteme de operare Linux moderne au adoptat systemd.

# systemctl status apache2 ● apache2.service - Serverul Apache HTTP încărcat: încărcat (/lib/systemd/system/apache2.service; dezactivat; prestabilit furnizor: activat) Drop-In: /lib/systemd/system/apache2.service. d └─apache2-systemd.conf Activ: activ (în rulare) din Mar 2018-09-25 10:03:28 IST; Acum 3 secunde Proces: 3294 ExecStart=/usr/sbin/apachectl start (cod=ieșit, stare=0/SUCCESS) PID principal: 3317 (apache2) Sarcini: 55 (limită: 4915) Memorie: 7.9M CPU: 71ms CGroup: /system.slice/apache2.service ├─3317 /usr/sbin/apache2 -k start ├─3318 /usr/sbin/apache2 -k start└2 ─3319 /usr/sbin/apache2 -k start 25 septembrie 10:03:28 ubuntu systemd: Se pornește serverul Apache HTTP... 25 septembrie 10:03:28 ubuntu systemd: Se pornește serverul Apache HTTP.

Sistemul de operare UNIX Robachevsky Andrey M.

ID proces (PID)

Fiecare proces are un PID unic, care permite nucleului sistemului să facă distincția între procese. Când este creat un nou proces, nucleul îi atribuie următorul identificator liber (adică, nu este asociat cu niciun proces). Identificatorii sunt alocați în ordine crescătoare, de ex. ID-ul noului proces este mai mare decât ID-ul procesului creat înainte de acesta. Dacă ID-ul atinge valoarea maximă, următorul proces va primi PID-ul minim gratuit și ciclul se repetă. Când un proces iese, nucleul eliberează identificatorul pe care îl ocupa.

Acest text este un fragment introductiv. Din cartea Arhitectura sistemului de operare UNIX autorul Bach Maurice J

4.4 TRANSFORMAREA NUMELE DE COMPONENTĂ AL UNUI FIȘIER (CALEA DE CĂUTARE) ÎNTR-UN ID INDEX Referința inițială la un fișier este după numele său calificat (calea de căutare), ca și în cazul comenzilor open, chdir (modificare director) sau link. Pentru că în interiorul sistemului nucleul lucrează cu indici, nu cu

Din cartea O profesie rară autor Zuev Evgeniy

Ce este un ID? Pe lângă ambiguitățile în sintaxă, au apărut rapid și alte probleme. Este mai dificil să le arăți cu exemple, așa că va trebui să le explici în cuvinte.Sintaxa limbajului C++ este, de asemenea, incomodă și în altă privință. Pe scurt, direct

Din cartea Programare autor Kozlova Irina Sergheevna

11. Identificator. Cuvinte cheie Un identificator este o succesiune de numere, litere și caractere speciale. În acest caz, primul caracter este o literă sau un caracter special. Pentru a obține identificatori, puteți utiliza litere mici sau mari ale alfabetului latin.

Din cartea 200 de cele mai bune programe pentru Internet. Tutorial popular autorul Krainsky I

Process Guardian XP Producător: T.A.S. Programare independentă (http://www.tas-independent-programming.com).Stare: gratuit.Link de descărcare: http://www.tas-independent-programming.com/cgi-bin/countdown.pl?Guardian.exe .Dimensiune: 2,4 MB.Scopul principal al acestui utilitar este gestionarea proceselor care rulează pe computer.După

Din cartea Microsoft Visual C++ și MFC. Programare pentru Windows 95 și Windows NT autor Frolov Alexandru Viaceslavovici

Deschideți identificatorul fișierului Clasa CFile include un element de date m_hFile de tip UINT. Stochează identificatorul fișierului deschis. Dacă ați creat un obiect din clasa CFile, dar nu ați deschis încă niciun fișier, atunci constanta hFileNull este scrisă în m_hFile. De obicei nu este nevoie

Din cartea UNIX: Process Communication autor Stevens William Richard

ID-ul tranzacției O altă parte a strategiei de timeout și retransmisie este utilizarea ID-urilor de tranzacție (XID) pentru a distinge între cererile client și răspunsurile serverului. Când un client apelează o funcție RPC, biblioteca atribuie aceasta

Din cartea Arhitectură TCP/IP, protocoale, implementare (inclusiv versiunea IP 6 și securitate IP) de Faith Sydney M

16.7 Marcaj temporal și ID mesaj Când primiți e-mail, este interesant să știți ora la care a fost trimis și primit. SMTP adaugă aceste informații la mesajul redirecționat. În plus, acest protocol ține evidența tuturor gazdelor care au transmis mesajul de e-mail și ora

Din cartea tutorial Adobe Audition 3 autor autor necunoscut

Dynamic EQ (proces) Efectul Dynamic EQ variază cantitatea de filtrare în timp. De exemplu, în prima jumătate a valului puteți spori frecvențele înalte, iar în a doua jumătate puteți modifica lățimea benzii de frecvență afectate. Fereastra Dynamic EQ are trei file: Câștig, Frecvență și Q (lățime de bandă). 1. Graficul de frecvență

Din cartea PHP Reference a autorului

Pan/Expander (proces) Efectul Pan/Expand vă permite să mutați canalul central (componenta mono) al unui semnal stereo și să lărgiți sau să restrângeți separarea stereo dintre canalele stânga și dreapta. Canalul central este deplasat folosind centrul și canalele înconjurătoare ale înregistrării stereo,

Din cartea Dezvoltarea aplicațiilor în mediul Linux. A doua editie autor Johnson Michael K.

Stretch (proces) Efectul Stretch vă permite să modificați înălțimea (înălțimea) unui semnal audio, tempo-ul sau ambele. De exemplu, puteți utiliza acest efect pentru a crește înălțimea unei coloane sonore fără a-i modifica durata sau, dimpotrivă, pentru a schimba durata fără a modifica

Din cartea Firebird DATABASE DEVELOPER'S GHIDE de Borri Helen

ID de sesiune Deci, ID-ul de sesiune este numele stocării temporare care va fi folosită pentru a stoca datele de sesiune între rulările de script. Un SID - o stocare. Fără SID, fără stocare și invers. Deci, cum se leagă identificatorul și numele?

Din cartea Sistem de operare UNIX autor Robachevsky Andrey M.

10.2.1. ID-ul procesului și originea Două dintre cele mai fundamentale atribute sunt ID-ul procesului, sau pid, și ID-ul procesului părinte. PID este un număr întreg pozitiv care identifică în mod unic

Din cartea autorului

10.2.3. Uid-ul sistemului de fișiere În cazuri foarte speciale, un program poate avea nevoie să-și păstreze privilegiile root pentru orice, cu excepția accesului la sistemul de fișiere, pentru care folosește uid-ul utilizatorului. Folosit inițial în serverul spațial Linux NFS

Din cartea autorului

ID de domeniu Când creați un domeniu într-o bază de date, trebuie să specificați un ID de domeniu care este unic la nivel global în baza de date. Dezvoltatorii folosesc adesea un prefix sau un sufix pe identificatorii de domeniu pentru a îmbunătăți documentația. De exemplu: CREATE

Din cartea autorului

Din cartea autorului

Parent Process ID (PPID) Identificatorul procesului care a generat acest lucru

Există momente în care aplicația începe să eșueze și, odată cu ea, întregul mediu de lucru, desigur, puteți reporni computerul, iar funcționalitatea în sine va dispărea, dar aceasta nu este o opțiune pentru a reporni computerul de fiecare dată. Și există o echipă pentru asta Ucide, care vă va ajuta să opriți un proces înghețat.

Echipă Ucide poate fi folosit pentru a ucide sau a termina un proces folosind „Semnal” sau „PID”. Comanda Kill trimite semnalul specificat pentru a termina o aplicație care se comportă greșit. Dacă nu este specificat niciun semnal, este trimis semnalul TERM. Acest semnal TERM va ucide procesele care nu îl prind; pentru alte procese poate fi necesar să se utilizeze semnalul Kill (numărul 9), deoarece acest semnal nu poate fi interceptat.

SIGTERM este un semnal care solicită oprirea unui proces. Acest proces are un timp pentru a-și finaliza activitatea.

Ei bine, cu ajutorul semnalului SIGKILL, putem forța procesul să se termine imediat. Și Programul nu are dreptul de a ignora acest semnal și închide aplicația.

Următorul este formatul comenzii Kill:

ucide [ -semnal | -s signal ] pid...

Cel mai simplu mod de a ucide un proces este să găsiți PID-ul resursei și apoi să rulați PID-ul ca argument cu comanda Kill.

Ce este PID?

Fiecărui proces sau program Linux sau Unix care rulează i se atribuie automat un număr unic de identificare a procesului (PID). PID atribuie automat un număr fiecărui proces din sistem.

Puteți găsi PID-ul unei resurse utilizând comanda „pidof” sau comanda „ps”. Pentru a afla PID-ul unui proces (să zicem firefox) utilizați următoarea comandă

Pidof firefox

De asemenea, puteți utiliza comanda sub altă formă:

Ps-A | grep -i firefox

În exemplul de mai sus, este afișat numărul „23814”, care este PID-ul procesului Firefox. Odată ce cunoașteți PID-ul procesului (firefox), puteți utiliza comanda Kill pentru a opri procesul (Firefox), așa cum se arată mai jos.

Ucide 23814

Când o comandă execută o ucidere, adică trimite un semnal procesului al cărui PID este transmis împreună cu comanda ca argument.

Pentru a fi mai specific, comanda Kill are următoarele forme:

  • ucide PID
  • ucide -15 PID
  • ucide -9 PID
  • kill -SIGTERM PID
  • kill -SIGTERM PID

Comanda Kill are următoarele coduri de returnare:

  • 0 – la succes
  • 1 – eșec
  • 64 – succes parțial (dacă sunt specificate mai multe procese)

O altă comandă pe care o poți folosi este Omoara-i pe toti. Killall folosește, de asemenea, numele procesului în loc de PID și termină toate instanțele procesului cu acel nume. De exemplu, dacă aveți mai multe instanțe de Firefox care rulează, le puteți închide pe toate cu comanda

Ucide-l pe firefox

Pentru serverul X, există o altă comandă numită Xkill, care poate ucide procese. Comanda Xkill este pentru modul grafic, fără a trece numele procesului sau PID-ul acestuia, adică dacă rulați într-un terminal

Astăzi vom vorbi despre cum să faceți față proceselor în Ubuntu Linux care sunt înghețate și nu le puteți termina. Ei devorează resursele sistemului prin încărcarea sistemului, consumând o parte decentă din RAM, ceea ce creează probleme precum încetinirea computerului sau înghețarea parțială a sistemului pentru perioade scurte de timp. Există situații diferite, uneori desktopul se blochează, alteori aplicația se blochează, alteori mediul desktop îngheață, tocmai în aceste situații vom căuta o cale de a face fără a reporni sistemul și a nu opri computerul cu un butonul de pe unitatea de sistem a computerului, deoarece aceasta nu este o soluție bună.

Uneori este nevoie să omorâți un proces în Ubuntu Linux, cum să o faceți corect și să nu provocați rău, vom discuta atât soluțiile de consolă, cât și prin interfața grafică.

Astăzi vom vorbi despre cum să faceți față proceselor în Ubuntu Linux care sunt înghețate și nu le puteți termina. Ei devorează resursele sistemului prin încărcarea sistemului, consumând o parte decentă din RAM, ceea ce creează probleme precum încetinirea computerului sau înghețarea parțială a sistemului pentru perioade scurte de timp. Există diferite situații, uneori desktopul se blochează, alteori aplicația se blochează, alteori mediul desktop îngheață, tocmai în aceste situații vom căuta o cale de ieșire, cum să facem fără a reporni sistemul și a nu opri computerul cu un butonul de pe unitatea de sistem a computerului deoarece aceasta nu este o soluție bună.

Când lucrați cu Ubuntu Linux, probabil că aveți deja întrebări:

Cum să determinați PID-ul pentru a ucide ulterior procesul/aplicația

Dacă nu doriți să rulați comanda top sau un alt analog mai puternic htop, apoi deranjează-te să cauți ID-ul acestui sau aceluia ID de proces, există o cale de ieșire/soluție mai ușoară de găsit PID proces, puteți folosi comanda " pidof" sau " PS".

Să presupunem că trebuie să aflăm ID-ul de proces al aplicației Google Chrome, ce facem în această situație, deschidem terminalul Ctrl + Alt + T și rulăm comanda în terminal:

Pidof crom

obținem rezultatul:

9497 9183 9123 8815 8788 6042 6033 5938 5916 5911 5908 5900 5892 5836 5831 5819

aproape gata, am determinat PID-ul, citiți mai jos despre cum să omorâți procesul.

Cum să omorâți un proces în Linux prin PID

Am stabilit ce PID este în aplicația pe care vrem să o omorâm, din cea descrisă mai sus, vezi că acum am multe file care rulează în browser, plus procese individuale ale browserului, în total sunt 16 ID-uri, pentru a le ucide pe toate , rulăm comanda:

Sudo kill 9497 9183 9123 8815 8788 6042 6033 5938 5916 5911 5908 5900 5892 5836 5831 5819

De asemenea, puteți vizualiza toate procesele active din sistem rulând comanda:

Sudo ps axu

da, asa de simplu e. În loc de Chrome, poate exista orice altă aplicație, Skype sau alta.

De asemenea, puteți utiliza o comandă suplimentară pentru a detecta ID-ul de proces al aplicației pe care doriți să o omorâți:

Ps-A | grep -i nume-aplicație

În loc de name-app, scriem numele aplicației, nu introduceți manual numele complet, folosiți detectarea automată folosind „ tastele” TAB„. Ca urmare, această comandă va afișa timpul de funcționare al procesului necesar și, în consecință, acesta PID, pe care îl puteți folosi pentru a ucide, să verificăm funcționarea comenzii, rulați în terminal:

Ps-A | grep -i skype

obtinem urmatorul rezultat:

9257? 00:00:57 Skype

tot ce avem nevoie este în palma noastră, există un act de identitate și putem vedea și de cât timp durează acest proces.

Cum să utilizați comanda Kill în Linux

Am descris deja cum să obținem identificatorul PID mai sus, apoi tot ce trebuie să facem este să folosim acest PID împreună cu kill, care va distruge procesul care nu ne place, vedeți detaliile puțin mai jos.

Am primit ID-ul și acum putem anula aplicația:

Sudo kill 9257

Asta e tot, aplicația este ucisă.

Cum să omorâți un proces în Linux după nume

Pentru a ucide un proces după nume, puteți folosi comanda killall, mai întâi trebuie să înțelegeți că această comandă omoara toate procesele care au același nume. Acest lucru este foarte convenabil, deoarece în această situație nu trebuie să căutăm PID-ul procesului de care avem nevoie, de exemplu, dorim să închidem aplicația Skype, vom executa comanda în terminal:

Sudo killall skype

de asemenea o optiune:

Sudo Killall -s 9 Skype

în același moment, aplicația încetează să funcționeze, așa puteți ucide cu ușurință procesele care nu vă plac.

Comanda morții, ce nu ar trebui să faci în terminal

Am scris anterior material despre sfaturi proaste, ce comenzi nu trebuie executate în terminal pentru a nu distruge sistemul, dar lista nu este perfectă și poate fi completată cu multe alte comenzi, dintre care una o veți găsi mai jos.

Iată un exemplu de comandă a morții:

Sudo kill -9 -1

Această comandă va ucide toate procesele care rulează în prezent. Nu aș recomanda să faceți acest lucru deoarece consecințele pot fi imprevizibile și cel mai probabil va trebui să reporniți sistemul fără o interfață grafică. În cazul în care interfața grafică eșuează brusc, deschideți terminalul folosind comenzile CTRL+ALT+F1, fiecare fereastră nouă se deschide prin aceeași analogie, pur și simplu schimbând F1 în F2 și așa mai departe.

De asemenea, puteți obține ajutor cu privire la comenzile utilizate mai sus prin terminal, rulând comenzile:

Man ps man grep man pidof man kill man killall

Aceasta încheie materialul nostru scurt, dacă nu înțelegeți ceva, întrebați în comentarii la materialul de mai jos.


În acest articol, vom încerca să creăm un modul kernel care poate schimba PID-ul unui proces care rulează deja în Linux și, de asemenea, să experimentăm procese care au primit un PID modificat.


Avertizare: Modificarea PID-ului este un proces non-standard și, în anumite circumstanțe, poate duce la o panică a nucleului.

Modulul nostru de testare va implementa dispozitivul de caractere /dev/test, care va schimba PID-ul procesului la citirea din acesta. Mulțumim acestui articol pentru un exemplu de implementare a unui dispozitiv de caractere. Codul complet al modulului este dat la sfârșitul articolului. Desigur, cea mai corectă soluție a fost adăugarea unui apel de sistem la nucleul în sine, dar aceasta ar necesita recompilarea nucleului.

Mediu inconjurator

Toate activitățile de testare a modulelor au fost efectuate într-o mașină virtuală VirtualBox cu o distribuție LInux pe 64 de biți și versiunea de kernel 4.14.4-1. Comunicarea cu mașina a fost realizată folosind SSH.

Încercați soluția simplă numărul 1

Câteva cuvinte despre curent: variabila curentă indică o structură task_struct cu o descriere a procesului din nucleu (PID, UID, GID, cmdline, spații de nume etc.)

Prima idee a fost să schimbăm pur și simplu parametrul curent->pid din modulul kernel în cel dorit.

Static ssiize_t device_read(struct file *filp, char *buffer, size_t length, loff_t * offset) ( printk("PID: %d.\n",current->pid); current->pid = 1; printk("new PID: %d.\n",current->pid); , )
Pentru a verifica funcționalitatea modulului, am scris un program în C++:

#include #include #include 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::cout<< "My new PID " << getpid() << std::endl; execl("/bin/bash","/bin/bash",NULL); }
Să încărcăm modulul cu comanda insmod, să creăm /dev/test și să încercăm.

# ./a.out PID-ul meu părinte 293 PID-ul meu 782 Noul meu PID 782
PID nu s-a schimbat. Acesta poate să nu fie singurul loc în care este specificat PID-ul.

Încercați #2 câmpuri PID suplimentare

Dacă curent->pid nu este identificatorul de proces, atunci ce este? O privire rapidă asupra codului getpid() a indicat o structură task_struct care descrie procesul Linux și fișierul pid.c din codul sursă kernel. Funcția necesară este __task_pid_nr_ns. În codul funcției există un apel task->pids.pid, vom schimba acest parametru

Compilați și încercați

De când am testat prin SSH, am putut obține rezultatul programului înainte ca nucleul să se prăbușească:

PID-ul meu părinte 293 PID-ul meu 1689 Noul meu PID 1689
Primul rezultat este deja ceva. Dar PID-ul încă nu s-a schimbat.

Încercați #3 simboluri kernel neexportabile

O privire mai atentă la pid.c a dat o funcție care face ceea ce avem nevoie
static void __change_pid(struct task_struct *task, enum pid_type type,
struct pid *nou)
Funcția acceptă o sarcină pentru care este necesar să se schimbe PID-ul, tipul PID și, de fapt, noul PID. Funcția creează un nou PID
struct pid *alloc_pid(struct pid_namespace *ns)

Această funcție acceptă doar spațiul de nume în care va locui noul PID, acest spațiu poate fi obținut folosind task_active_pid_ns .
Dar există o problemă: aceste simboluri ale nucleului nu sunt exportate de nucleu și nu pot fi folosite în module. Unul minunat m-a ajutat să rezolv această problemă. Codul funcției find_sym este preluat de acolo.

Static asmlinkage void (*change_pidR)(struct task_struct *task, enum pid_type type, struct pid *pid); static asmlinkage struct pid* (*alloc_pidR)(struct pid_namespace *ns); static int __init test_init(void) ( printk(KERN_ALERT "Driverul TEST încărcat!\n"); change_pidR = find_sym("change_pid"); alloc_pidR = find_sym("alloc_pid"); ... ) static ssize_t device_read(struct file * filp, char *buffer, size_t length, 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("nou PID: %d.\n",current->pid); ... )
Compilați, lansați

PID-ul meu părinte 299 PID-ul meu 750 Noul meu PID 751
PID schimbat! Nucleul a alocat automat un PID gratuit programului nostru. Dar este posibil să utilizați un PID care a fost ocupat de un alt proces, cum ar fi PID 1? Să adăugăm codul după alocare

Newpid->numbers.nr = 1;
Compilați, lansați

PID-ul meu părinte 314 PID-ul meu 1172 Noul meu PID 1
Primim PID 1 real!

Bash a lansat o eroare care împiedică schimbarea sarcinilor folosind comanda %n, dar toate celelalte funcții funcționează bine.

Caracteristici interesante ale proceselor cu PID modificat

PID 0: enter nu poate ieși

Să revenim la cod și să schimbăm PID-ul la 0.

Newpid->numbers.nr = 0;
Compilați, lansați

PID-ul meu părinte 284 PID-ul meu 1517 Noul meu PID 0
Deci PID 0 nu este atât de special? Ne bucurăm, scriem exit și...

Mingea de tun cade! Nucleul ne-a definit sarcina ca IDLE TASK și, văzând finalizarea, pur și simplu s-a prăbușit. Aparent, programul nostru trebuie să revină la PID-ul său „normal” înainte de a ieși.

Proces invizibil

Să revenim la cod și să setăm un PID care este garantat că nu va fi ocupat
newpid->numbers.nr = 12345;

Compilați, lansați

PID-ul meu părinte 296 PID-ul meu 735 Noul meu PID 12345
Să vedem ce este în /proc

1 148 19 224 288 37 79 86 93 console fb kcore blocuri partiții schimburi versiunea 10 149 2 226 29 4 8 87 acpi cpuinfo sisteme de fișiere cheie utilizatori meminfo sched_debug sys vmallocinfo 15 2802 15 2802 taste misc schedstat sysrq- declanșare vmstat 11 16 208 24 291 6 81 89 dispozitive buddyinfo întrerupe module kmsg scsi sysvipc zoneinfo 12 17 21 25 296 7 82 9 magistrală diskstats iomem kpagecgroup se montează self thread-self 13 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 oferă kpagecount mtrr slabinfo 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 pagetype info stat up
După cum putem vedea, /proc nu identifică procesul nostru, chiar dacă am ocupat un PID gratuit. PID-ul anterior nu este nici în /proc, iar acest lucru este foarte ciudat. Poate ne aflăm într-un spațiu de nume diferit și, prin urmare, nu suntem vizibili pentru main /proc. Să instalăm un nou /proc și să vedem ce este acolo

1 14 18 210 25 291 738 81 9 dispozitive de magistrală fs key-users locks pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats întreruperi chei stat 1 t 4910 2 2 2 2 26 26 296 741 82 90 6 83 92 cmdline dma iomem kmsg misc sched_debug swaps uptime 11 15 2 224 28 37 78 84 93 config.gz driver ioports kpagecgroup modules schedstat sys version 12 16 20 226 288 4 79 85 acpi consoles sctriq kpagecgroups consoles sctriqkpagecgroup counts-syps 16 20 226 288 4 79 85 7 208 23 29 6 8 86 asound cpuinfo fb ​​​​kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo sisteme de fișiere cripto kcore loadavg net slabinfo thread-self zoneinfo
Procesul nostru încă nu există, ceea ce înseamnă că suntem în spațiul de nume normal. Sa verificam

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

Un singur bash, din care am lansat programul. Nici PID-ul anterior, nici cel actual nu sunt în listă.

Cele mai bune articole pe această temă