Come configurare smartphone e PC. Portale informativo
  • casa
  • OS
  • Come uccidere un processo in Linux. Gestione dei processi Linux Come scoprire il pid di un processo Linux

Come uccidere un processo in Linux. Gestione dei processi Linux Come scoprire il pid di un processo Linux

Fondamentalmente, guardiamo al PID per uccidere il programma che non risponde ed è simile al Task Manager di Windows.

Anche la GUI di Linux offre la stessa funzionalità, ma la CLI è un modo efficiente per eseguire un'operazione di kill.

Che cos'è il PID di processo?

PID è l'acronimo di Process Identification Number, comunemente utilizzato dalla maggior parte dei kernel del sistema operativo come Linux, Unix, macOS e Windows.

Si tratta di un numero di identificazione univoco che viene assegnato automaticamente a ciascun processo quando viene creato nel sistema operativo.

Un processo è un'istanza eseguibile di un programma.

Ogni volta, l'ID processo riceverà modifiche a tutti i processi tranne init, poiché init è sempre il primo processo sul sistema ed è l'antenato di tutti gli altri processi. Questo è PID-1.

Il valore PID massimo predefinito è 32.768.

# cat / proc / sys / kernel / pid_max

Sui sistemi a 32 bit, 32768 è il massimo, ma possiamo impostare qualsiasi valore fino a 2^22 (circa 4 milioni) sui sistemi a 64 bit.

Perché abbiamo bisogno di così tanti PID, potresti chiedere? perché non possiamo riutilizzare subito il PID. Anche per evitare possibili errori.

I PID per l'esecuzione dei processi sul sistema possono essere trovati utilizzando i seguenti nove metodi, come comando pidof, comando pgrep, comando ps, comando pstree, comando ss, comando netstat, comando lsof, comando fuser e comando systemctl.

  • pidof: pidof - trova l'id del processo del programma in esecuzione.
  • pgrep: pgre - Ricerca o elaborazione del segnale in base al nome e ad altri attributi.
  • ps: ps - Riporta un'istantanea dei processi correnti.
  • pstree: pstree - mostra un albero di processi.
  • ss: ss viene utilizzato per visualizzare le statistiche del socket.
  • netstat: netstat visualizza un elenco di socket aperti.
  • lsof: lsof - elenco dei file aperti.
  • fuser: identificatori di processo nell'elenco dei termini di tutti i processi che aprono uno o più file
  • systemctl: systemctl - Gestire il sistema systemd e il gestore dei servizi

In questo tutorial, daremo un'occhiata all'ID del processo Apache per la convalida.

Metodo 1: utilizzo del comando pidof

pidof è usato per trovare l'id del processo di un programma in esecuzione.

Stampa questi identificatori sullo standard output.

Per dimostrarlo, otterremo l'ID del processo Apache2 dal sistema Debian 9.

#pidof apache2 3754 2594 2365 2364 2363 2362 2361

Da quanto sopra, potresti avere difficoltà a identificare l'ID del processo poiché mostra tutti i PID (inclusi padre e figlio) con il nome del processo.

Quindi, abbiamo bisogno di capire il PID genitore (PPID) che stiamo cercando.

Questo potrebbe essere il primo numero. Nel mio caso è 3754 ed è mostrato in ordine decrescente.

Metodo 2: utilizzo del comando pgrep

pgrep esamina i processi correnti ed elenca gli ID dei processi che corrispondono ai criteri di selezione per stdout.

# pgrep apache2 2361 2362 2363 2364 2365 2594 3754

Anche questo è simile all'output sopra, ma questo tende a troncare i risultati in ordine crescente, il che indica chiaramente che il PID padre è l'ultimo.

Nel mio caso è 3754.

Nota. Se hai più ID di processo, potresti incontrare il problema di identificare gli ID di processo padre quando usi il comando pidof & pgrep.

Metodo 3: utilizzo del comando pstree

pstree mostra i processi in esecuzione come un albero.

L'albero è radicato in pid o init se pid viene omesso.

Se viene specificato un nome utente nel comando pstree, viene visualizzato l'intero processo di proprietà dell'utente corrispondente.

pstree concatena visivamente rami identici racchiudendoli tra parentesi quadre e anteponendoli al numero di ripetizioni.

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

Per ottenere un solo processo padre, usa il seguente formato.

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

Il comando pstree è molto semplice perché separa i processi padre e figlio separatamente.

Metodo-4: utilizzo del comando ps

ps visualizza informazioni sulla selezione dei processi attivi.

Visualizza l'id del processo (pid = PID), il terminale associato al processo (tname = TTY), il tempo cumulativo del processore in formato hh: mm: ss (time = TIME) e il nome dell'eseguibile (ucmd = CMD).

Per impostazione predefinita, il file di output non è ordinato.

# 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 radice 3754 0,0 1,4 302580 29324? Ss Dec11 0:23 / usr / sbin / apache2 -k start radice 5648 0.0 0.0 12784 940 punti / 0 S + 21:32 0:00 grep apache2

Dall'output sopra, possiamo facilmente identificare l'ID del processo padre (PPID) in base alla data di inizio del processo.

Nel mio caso il processo apache2 è stato avviato da @ Dec11 che è il genitore e gli altri sono figli. Il PID di Apache2 è 3754.

Metodo 5: utilizzo del comando ss

ss viene utilizzato per visualizzare le statistiche del socket.

Ti consente di visualizzare informazioni simili a netstat.

Può visualizzare più TCP e informazioni di stato rispetto ad altri strumenti.

Può visualizzare statistiche per tutti i tipi di socket come PACKET, TCP, UDP, DCCP, RAW, dominio Unix, ecc.

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

Metodo-6: utilizzo del comando netstat

netstat - Visualizza le connessioni di rete, le tabelle di routing, le statistiche dell'interfaccia, le connessioni mascherate e multicast.

Per impostazione predefinita, netstat visualizza un elenco di socket aperti.

Se non si specificano famiglie di indirizzi, vengono elencati i socket attivi di tutte le famiglie di indirizzi configurate.

Questo programma è obsoleto. Il sostituto di netstat è ss.

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

Metodo-7: usare il comando lsof

lsof - elenco di file aperti.

Il comando lsof Linux visualizza le informazioni sui file aperti per i processi in esecuzione sul sistema.

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

Metodo-8: utilizzo del comando fuser

L'utilità di fusione dovrebbe scrivere sull'output standard gli ID dei processi in esecuzione sul sistema locale che aprono uno o più file denominati.

# fuser -v 80 / tcp COMANDO DI ACCESSO PID UTENTE 80 / tcp: root 3317 F .... apache2 www-data 3318 F .... apache2 www-data 3319 F .... apache2

Metodo-9: utilizzo del comando systemctl

systemctl - Gestire il sistema systemd e il gestore dei servizi.

È un sostituto del vecchio sistema di controllo SysV e i più moderni sistemi operativi Linux sono stati adattati da systemd.

# systemctl status apache2 ● apache2.service - Il server HTTP Apache Caricato: caricato (/lib/systemd/system/apache2.service; disabilitato; preimpostazione del fornitore: abilitato) Drop-In: /lib/systemd/system/apache2.service. d └─apache2-systemd.conf Attivo: attivo (in esecuzione) da Mar 2018-09-25 10:03:28 IST; 3 secondi fa Processo: 3294 ExecStart = / usr / sbin / apachectl start (codice = terminato, stato = 0 / SUCCESSO) PID principale: 3317 (apache2) Compiti: 55 (limite: 4915) Memoria: 7,9 M CPU: 71 ms Gruppo C: /system.slice/apache2.service ├─3317 / usr / sbin / apache2 -k start ├─3318 / usr / sbin / apache2 -k start └ ─3319 / usr / sbin / apache2 -k start 25 settembre 10:03:28 ubuntu systemd: avvio del server HTTP Apache ... 25 settembre 10:03:28 ubuntu systemd: avvio del server HTTP Apache.

Sistema operativo UNIX Robachevsky Andrey M.

ID processo ID processo (PID)

Ogni processo ha un PID univoco che consente al kernel di distinguere i processi. Quando viene creato un nuovo processo, il kernel gli assegna il successivo identificatore libero (cioè non associato ad alcun processo). L'assegnazione degli identificatori è crescente, cioè l'ID del nuovo processo è maggiore dell'ID del processo creato prima di esso. Se l'identificatore ha raggiunto il suo valore massimo, il processo successivo riceverà il PID libero minimo e il ciclo si ripete. Quando il processo termina, il kernel rilascia l'identificatore che occupava.

Questo testo è un frammento introduttivo. Dal libro L'architettura del sistema operativo UNIX autore Bach Maurice J.

4.4 CONVERTIRE IL NOME COMPOSITO DI UN FILE (PERCORSO DI RICERCA) IN UN ID INDICE Inizialmente si accede a un file tramite il suo nome composto (percorso di ricerca), come nei comandi open, chdir (cambia directory) o link. Poiché internamente, il kernel funziona con gli indici e non con

Dal libro Una professione rara l'autore Zuev Evgeniy

Che cos'è un identificatore? Oltre alle ambiguità sintattiche, sono emersi rapidamente altri fastidi. È più difficile mostrarli con esempi, quindi devi parlare a parole.La sintassi del linguaggio C ++ è scomoda anche sotto un altro aspetto. In breve, diretto

Dal libro Programmazione l'autore Kozlova Irina Sergeevna

11. Identificatore. Parole chiave Un identificatore è una sequenza di numeri, lettere e caratteri speciali. In questo caso, il primo è una lettera o un carattere speciale. Per ottenere gli identificatori, puoi utilizzare le lettere minuscole o maiuscole dell'alfabeto latino.

Dal libro dei 200 migliori programmi per Internet. Tutorial popolare autore Krainsky I

Process Guardian XP Produttore: T.A.S. Programmazione indipendente (http://www.tas-independent-programming.com) Stato: Download gratuito Link: http://www.tas-independent-programming.com/cgi-bin/countdown.pl?Guardian exe Dimensioni: 2,4 MB Lo scopo principale di questa utility è gestire i processi in esecuzione sul computer.

Dal libro Microsoft Visual C++ e MFC. Programmazione per Windows 95 e Windows NT l'autore Frolov Alexander Vyacheslavovich

Identificatore file aperto La classe CFile include l'elemento dati m_hFile di tipo UINT. Memorizza l'identificatore del file aperto. Se hai creato un oggetto della classe CFile, ma non hai ancora aperto alcun file, allora la costante hFileNull viene scritta in m_hFile, di solito non è necessaria

Dal libro UNIX: Process Communication l'autore Stevens William Richard

ID transazione Un'altra parte della strategia di timeout e ritrasmissione consiste nell'utilizzare gli ID transazione (XID) per distinguere tra richieste client e risposte server. Quando il client chiama la funzione RPC, la libreria assegna questo

Dal libro TCP/IP Architecture, Protocols, Implementation (incluso IP versione 6 e IP Security) di Faith Sidney M

16.7 Timestamp e ID messaggio Quando si riceve la posta, è interessante sapere l'ora in cui è stata inviata e ricevuta. SMTP aggiunge queste informazioni al messaggio inoltrato. Inoltre, questo protocollo tiene traccia di tutti gli host che hanno inviato il messaggio di posta e l'ora

Dal libro Tutorial Adobe Audition 3 l'autore autore sconosciuto

Dynamic EQ (processo) L'effetto Dynamic EQ varia la quantità di filtraggio nel tempo. Ad esempio, nella prima metà dell'onda, puoi aumentare le frequenze alte e nella seconda puoi modificare l'ampiezza della banda di frequenza interessata. La finestra Dynamic EQ ha tre schede: Guadagno, Frequenza e Q (larghezza di banda). 1. Grafico della frequenza

Dal libro PHP Author's Reference

Pan/Expander (processo) L'effetto Pan/Expand consente di spostare il canale centrale (mono) fuori dal segnale stereo ed espandere o restringere la separazione stereo dei canali sinistro e destro. canali surround della registrazione stereo.

Dal libro Sviluppo di applicazioni in Linux. Seconda edizione l'autore JohnsonMichael K.

Stretch (processo) L'effetto Stretch consente di modificare il tono (altezza) di un segnale audio, il tempo o entrambi. Ad esempio, puoi usare questo effetto per aumentare il tono di un fonogramma senza cambiarne la durata, o viceversa, cambiare la durata senza cambiare

Dal libro Firebird DATABASE DESIGNER'S GUIDE di Borri Helen

ID sessione Quindi, l'ID sessione è il nome della memoria temporanea che verrà utilizzata per memorizzare i dati della sessione tra le esecuzioni dello script. Un SID - un negozio. Nessun SID, nessuna memoria e viceversa. Quindi, come sono correlati l'identificatore e il nome?

Dal libro Sistema operativo UNIX l'autore Robachevsky Andrey M.

10.2.1. ID processo e lignaggio Due degli attributi più fondamentali sono l'ID processo, o pid, e l'ID del suo processo padre. Pid è un numero intero positivo che identifica in modo univoco

Dal libro dell'autore

10.2.3. Uid del filesystem In casi molto speciali, un programma potrebbe aver bisogno di mantenere i suoi permessi di root per tutto tranne l'accesso al filesystem, che usa l'uid dell'utente. Originariamente utilizzato nello spazio del server NFS Linux

Dal libro dell'autore

ID dominio Quando si crea un dominio nel database, è necessario specificare un ID dominio che sia univoco a livello globale nel database. Gli sviluppatori utilizzano spesso un prefisso o un suffisso negli identificatori di dominio per migliorare la documentazione. Ad esempio: CREA

Dal libro dell'autore

Dal libro dell'autore

ID processo padre (PPID) L'identificatore del processo che lo ha generato

Ci sono momenti in cui l'applicazione inizia a presentare problemi e con essa l'intero ambiente di lavoro, ovviamente, è possibile riavviare il computer e la funzionalità stessa scomparirà, ma questa non è un'opzione per riavviare il computer ogni volta. E per questo c'è un comando Uccisione per aiutarti a fermare il processo congelato.

Squadra Uccisione può essere utilizzato per uccidere o terminare un processo utilizzando "Segnale" o "PID". Il comando Kill invia il segnale specificato per terminare l'applicazione che si comporta in modo anomalo. Se non viene specificato alcun segnale, viene inviato il segnale TERM. Questo segnale TERM ucciderà i processi che non lo catturano; per altri processi potrebbe essere necessario utilizzare il segnale Kill (numero 9), in quanto questo segnale non può essere intercettato.

SIGTERM è un segnale che richiede l'arresto del processo. A questo processo viene concesso del tempo per completare il suo lavoro.

Bene, con l'aiuto del segnale SIGKILL, possiamo forzare l'interruzione immediata del processo. E il Programma non ha il diritto di ignorare questo segnale e termina l'applicazione.

Il seguente è il formato del comando Kill:

uccidere [-segnale | -s segnale] pid ...

Il modo più semplice per terminare un processo è trovare il PID della risorsa e quindi eseguire il PID come argomento con il comando Kill.

Cos'è il PID?

A ogni processo o programma Linux o Unix in esecuzione viene assegnato automaticamente un numero di identificazione del processo (PID) univoco. Il PID assegna automaticamente un numero a ciascun processo nel sistema.

Puoi trovare il PID di una risorsa usando il comando "pidof" o il comando "ps". Per scoprire il PID di un processo (diciamo Firefox) usa il seguente comando

Pidof firefox

Puoi anche usare il comando in una forma diversa:

Ps -A | grep -i firefox

Nell'esempio sopra, viene visualizzato il numero "23814", che è il PID del processo Firefox. Una volta che conosci il PID del processo (firefox), puoi utilizzare il comando Kill per terminare il processo (Firefox) come mostrato di seguito.

Uccidi 23814

Quando il comando esegue la distruzione, ovvero invia un segnale al processo il cui PID viene passato insieme al comando come argomento.

Per essere più specifici, il comando Kill ha le seguenti forme:

  • uccidere PID
  • uccidere -15 PID
  • uccidere -9 PID
  • kill -SIGTERM PID
  • kill -SIGTERM PID

Il comando Kill ha i seguenti codici di ritorno:

  • 0 - in caso di successo
  • 1 - fallimento
  • 64 - successo parziale (se è specificato più di un processo)

Un altro comando che puoi usare è Uccidi tutti... Killall utilizza anche il nome del processo invece del PID e uccide tutte le istanze del processo con quel nome. Ad esempio, se hai avviato più istanze di Firefox, puoi terminarle tutte con il comando

Killall firefox

Per il server X, c'è un altro comando chiamato Xkill che può uccidere i processi. Il comando Xkill è per la modalità grafica, senza passare attraverso il nome del processo o il PID, cioè se si esegue in un terminale

Oggi parleremo di come gestire i processi che sono congelati e non è possibile terminarli in Ubuntu Linux. Divorano le risorse di sistema caricando il sistema, consumando una parte decente della RAM, il che crea problemi come il rallentamento del computer o il congelamento parziale del sistema per brevi periodi di tempo. Le situazioni sono diverse, a volte il desktop si blocca, a volte l'applicazione si blocca, a volte l'ambiente desktop si blocca, è da queste situazioni che cercheremo una via d'uscita su come fare senza riavviare il sistema e non spegnere il computer con un pulsante sull'unità di sistema del computer, poiché questa non è una buona soluzione.

A volte è necessario interrompere un processo in Ubuntu Linux, come farlo correttamente e non danneggiarlo, discuteremo sia delle soluzioni console che tramite un'interfaccia grafica.

Oggi parleremo di come gestire i processi che sono congelati e non è possibile terminarli in Ubuntu Linux. Divorano le risorse di sistema caricando il sistema, consumando una parte decente della RAM, il che crea problemi come il rallentamento del computer o il congelamento parziale del sistema per brevi periodi di tempo. Le situazioni sono diverse, a volte il desktop si blocca, a volte l'applicazione si blocca, a volte l'ambiente desktop si blocca, è da queste situazioni che cercheremo una via d'uscita, come fare senza riavviare il sistema e non spegnere il computer con un pulsante sull'unità di sistema del computer, poiché questa non è una buona soluzione ...

Quando lavori con Ubuntu Linux, probabilmente hai già delle domande:

Come determinare il PID per terminare successivamente il processo/l'applicazione

Se non vuoi eseguire il comando superiore o un altro analogo più potente htop, quindi preoccupati di cercare l'ID di questo o quell'ID del processo, c'è una via d'uscita / soluzione più semplice da trovare PID processo, puoi usare il comando " pidof" o " PS".

Diciamo che dobbiamo scoprire l'ID del processo dell'applicazione Google Chrome, cosa stiamo facendo in questa situazione, apriamo il terminale Ctrl + Alt + T ed eseguiamo il comando nel terminale:

Pidof chrome

otteniamo l'output:

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

quasi pronto, abbiamo determinato il PID, leggi come terminare il processo di seguito.

Come uccidere un processo in Linux tramite PID

Abbiamo determinato quale PID nell'applicazione vogliamo eliminare, da quanto sopra, puoi vedere che ho molte schede in esecuzione nel browser ora e oltre a processi del browser separati, di conseguenza, 16 idi, per ucciderli tutti, noi eseguire il comando:

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

puoi anche visualizzare tutti i processi attivi nel sistema eseguendo il comando:

Sudo ps axu

si, proprio così. Invece di Chrome, può esserci qualsiasi altra applicazione, skype o qualcos'altro.

Puoi anche utilizzare un comando aggiuntivo per rilevare l'id del processo dell'applicazione che desideri eliminare:

Ps -A | grep -i nome-app

invece di nome-app scriviamo il nome dell'applicazione, non inserire manualmente il nome completo, usa il rilevamento automatico usando i tasti " TAB". Di conseguenza, questo comando visualizzerà il tempo di esecuzione del processo richiesto e, di conseguenza, il suo PID che puoi usare per uccidere, testiamo il comando eseguendo nel terminale:

Ps -A | grep -i skype

otteniamo il seguente risultato:

9257? 00:00:57 skype

tutto ciò di cui abbiamo bisogno è nel palmo della nostra mano, c'è un ID, vediamo anche da quanto tempo questo processo è già in esecuzione.

Come usare il comando Kill in Linux

Ho descritto come ottenere l'identificatore PID sopra, quindi dobbiamo solo usare questo PID insieme a kill per uccidere il processo indesiderato, vedere i dettagli un po' sotto.

Abbiamo capito e ora possiamo uccidere l'applicazione:

Sudo uccidere 9257

tutto qui, l'applicazione viene uccisa.

Come uccidere un processo in Linux per nome

Per uccidere un processo per nome, puoi usare il comando killall, devi prima capire che questo comando uccide tutti i processi che hanno lo stesso nome. Questo è molto conveniente, poiché in questa situazione non abbiamo bisogno di cercare il PID del processo di cui abbiamo bisogno, ad esempio, vogliamo chiudere l'applicazione Skype, eseguire il comando nel terminale:

Sudo killall skype

la stessa opzione:

Sudo killall -s 9 skype

nello stesso momento in cui l'applicazione smette di funzionare, ecco come puoi facilmente uccidere i processi che non ti piacciono.

Comando di morte, che non dovrebbe essere eseguito nel terminale

In precedenza ho scritto materiale sui cattivi consigli, quali comandi non dovrebbero essere eseguiti nel terminale per non uccidere il sistema, ma l'elenco non è perfetto e può essere integrato con molti altri comandi, uno con quello che troverai di seguito.

Lascia che ti faccia un esempio di comando di morte:

Sudo kill -9 -1

questo comando ucciderà tutti i processi attualmente in esecuzione. Non ti consiglierei di eseguirlo, poiché le conseguenze possono essere imprevedibili e molto probabilmente dovrai riavviare il sistema senza un'interfaccia grafica. Nel caso in cui l'interfaccia grafica si guasti improvvisamente, apri il terminale usando i comandi CTRL + ALT + F1, ogni nuova finestra viene aperta con la stessa analogia, cambia semplicemente F1 in F2 e così via.

Puoi anche ottenere aiuto sui comandi che sono stati usati sopra, tramite il terminale, eseguendo i comandi:

Man ps man grep man pidof man kill man killall

Questo conclude il nostro breve materiale, se non capisci qualcosa, chiedi nei commenti al materiale qui sotto.


In questo articolo, proveremo a creare un modulo del kernel in grado di modificare il PID di un processo già in esecuzione in Linux, nonché a sperimentare processi che hanno ricevuto un PID modificato.


Avvertimento Nota: la modifica del PID è un processo non standard e in determinate circostanze può portare al panico del kernel.

La nostra unità di test implementerà il dispositivo a caratteri / dev / test, che cambierà il PID del processo quando viene letto. Per un esempio dell'implementazione di un dispositivo a caratteri, grazie a questo articolo. Il codice completo del modulo è riportato alla fine dell'articolo. Ovviamente, la soluzione più corretta era aggiungere una chiamata di sistema al kernel stesso, ma ciò richiederebbe una ricompilazione del kernel.

Ambiente

Tutte le azioni per testare il modulo sono state eseguite in una macchina virtuale VirtualBox con una distribuzione Linux a 64 bit e una versione del kernel 4.14.4-1. La comunicazione con la macchina è stata effettuata tramite SSH.

Tentativo n. 1 soluzione semplice

Qualche parola sull'attuale: la variabile current punta a una struttura task_struct con una descrizione del processo nel kernel (PID, UID, GID, cmdline, namespace, ecc.)

La prima idea era semplicemente cambiare il parametro current-> pid dal modulo del kernel a quello desiderato.

Statico ssize_t device_read (file struct * filp, char * buffer, size_t length, loff_t * offset) (printk ("PID:% d. \ N", current-> pid); current-> pid = 1; printk ("new PID:% d. \ N ", corrente-> pid);,)
Per verificare la funzionalità del modulo, ho scritto un programma in C++:

#includere #includere #includere 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); }
Carica il modulo con insmod, crea / dev / test e provalo.

# ./a.out Il mio PID genitore 293 Il mio PID 782 Il mio nuovo PID 782
Il PID non è cambiato. Questo potrebbe non essere l'unico posto in cui è elencato il PID.

Tentativo # 2 campi PID aggiuntivi

Se current-> pid non è l'ID del processo, allora qual è? Una rapida occhiata al codice getpid() ha indicato la struttura task_struct che descrive il processo Linux e il file pid.c nel sorgente del kernel. La funzione richiesta è __task_pid_nr_ns. Il codice della funzione contiene la chiamata task-> pids.pid, cambieremo questo parametro

Compilare, provare

Dato che ho testato su SSH, sono stato in grado di ottenere l'output del programma prima che il kernel si bloccasse:

Il mio genitore PID 293 Il mio PID 1689 Il mio nuovo PID 1689
Il primo risultato è già qualcosa. Ma il PID non è ancora cambiato.

Tentativo n. 3 simboli del kernel non esportati

Uno sguardo più attento a pid.c ha prodotto una funzione che fa ciò che vogliamo.
static void __change_pid (struct task_struct * task, enum pid_type tipo,
struttura pid * nuova)
La funzione accetta un compito per il quale è necessario modificare il PID, il tipo di PID e, di fatto, il nuovo PID. Il nuovo PID viene creato dalla funzione
struct pid * alloc_pid (struct pid_namespace * ns)

Questa funzione accetta solo lo spazio dei nomi in cui si troverà il nuovo PID, questo spazio può essere ottenuto utilizzando task_active_pid_ns.
Ma c'è un problema: questi simboli del kernel non vengono esportati dal kernel e non possono essere usati nei moduli. Nel risolvere questo problema, uno meraviglioso mi ha aiutato. Il codice della funzione find_sym è preso da lì.

Asmlinkage void statico (* 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 "TEST driver caricato! \ n"); change_pidR = find_sym ("change_pid"); alloc_pidR = find_sym ("alloc_pid"); ...) static ssize_t device_read (file struct * 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 ("nuovo PID:% d. \ N", corrente-> pid); ...)
Complimenti, lancio

Il mio genitore PID 299 Il mio PID 750 Il mio nuovo PID 751
PID cambiato! Il kernel ha assegnato automaticamente un PID gratuito al nostro programma. Ma è possibile utilizzare un PID che ha preso il sopravvento su un altro processo, come il PID 1? Aggiungi il codice dopo l'assegnazione

Newpid-> numeri.nr = 1;
Complimenti, lancio

Il mio genitore PID 314 Il mio PID 1172 Il mio nuovo PID 1
Otteniamo il vero PID 1!

Bash ha dato un errore in cui l'attivazione dell'attività su comando% n non funzionerà, ma tutte le altre funzioni funzionano correttamente.

Caratteristiche interessanti dei processi con PID modificato

PID 0: non si può uscire da invio

Torniamo al codice e cambiamo il PID a 0.

Newpid-> numeri.nr = 0;
Complimenti, lancio

Il mio genitore PID284 Il mio PID 1517 Il mio nuovo PID 0
Quindi il PID 0 non è così speciale? Siamo contenti, scrivi exit e...

Il nucleo sta cadendo! Il kernel ha definito il nostro compito come IDLE TASK e quando ha visto il completamento si è semplicemente bloccato. Apparentemente, prima della conclusione, il nostro programma dovrebbe restituire a se stesso il PID "normale".

Il processo invisibile

Torniamo al codice e impostiamo il PID, che è garantito non occupato
newpid-> numeri.nr = 12345;

Complimenti, lancio

Il mio genitore PID296 Il mio PID 735 Il mio nuovo PID 12345
Vediamo cosa c'è in / proc

1 148 19 224 288 37 79 86 93 console fb kcore blocca partizioni scambia versione 10 149 2 226 29 4 8 87 acpi cpuinfo filesystem key-users meminfo sched_debug sys vmallocinfo 102 15 20 23 290 5 80 88 asound crypto fs keys misc schedstat sysrq- trigger vmstat 11 16 208 24 291 6 81 89 dispositivi buddyinfo interrupt kmsg moduli 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 cgroups dma ioports 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 pagetypeinfo stat uptime
Come puoi vedere / proc non definisce il nostro processo, anche se abbiamo preso in prestito un PID gratuito. Anche il PID precedente non è in / proc, il che è molto strano. Potremmo trovarci in uno spazio dei nomi diverso e quindi non visibile al main / proc. Montiamo un nuovo / proc e vediamo cosa c'è dentro

1 14 18 210 25 291 738 81 9 dispositivi bus fs key-user locks pagetypeinfo softirqs timer_list 10 148 182 22 26 296 741 82 90 cgroups diskstats interrompe le chiavi meminfo partizioni stat tty 102 149 19 222 27 30 76 83 92 cmdline dma iomem kmsg misc sched_debug scambia uptime 11 15 2 224 28 37 78 84 93 driver config.gz ioports kpagecgroup moduli schedstat sys versione 12 16 20 226 288 4 79 85 console acpi execdomains irq kpagecount monta scsi sysrq-trigger vmallocinfo 13 17 208 23 29 6 8 86 asound cpuinfo fb ​​​​kallsyms kpageflags mtrr self sysvipc vmstat 139 176 21 24 290 7 80 87 buddyinfo crypto filesystem kcore loadavg net slabinfo thread-self zoneinfo
Come prima, il nostro processo non è presente, il che significa che siamo in un normale spazio dei nomi. Dai un'occhiata

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

Solo una bash, da cui abbiamo eseguito il programma. Né il PID precedente né quello attuale sono nell'elenco.

Principali articoli correlati