Kernel: το kill δεν πιάνει, τί σημαίνει αυτο

Giorgos Keramidas keramida at ceid.upatras.gr
Wed Dec 4 04:45:02 EET 2002


On 2002-12-03 02:17, "P. Christeas" <p_christ at hol.gr> wrote:
> Στις Δευ 02 Δεκ 2002 8:14 μμ, ο/η Giorgos Keramidas έγραψε:
> > Μπορούμε να μην γινόμαστε προσβλητικοί χωρίς λόγο στη λίστα; :PPP
>
> βλ. τα πρώτα (από Ιαν. 2002) μου postings.

Άσχετο το τι έκανες post πριν από ένα χρόνο σχεδόν.  Το παρελθόν, όσο
καλό και να είναι, δεν δικιολογεί τις βλακείες του παρόντος ή του
μέλλοντος.  Αν είσαι κόσμιος φέτος, δεν σημαίνει πως του χρόνου έχεις
κάθε δικαίωμα να βρίζεις θεούς και δαίμονες.

> > Συγγνώμη που δεν απάντησα στο mail σου που ρώταγε για σημεία που
> > μπορεί να κολλήσει κάποια process.  [...]
>
> Φαίνεται οτι τα παρακάτω είναι BSD-specific. Υποψιάζομαι οτι το πρόβλημά μου
> εμφανίζεται μονο στο Linux. Όταν το εντοπίσω (δηλ. τις ακριβείς συνθήκες) [...]

Αν θες στείλε όλο το source ή βάλτο κάπου online και να είσαι σίγουρος
ότι μπορώ άνετα να το δοκιμάσω τουλάχιστον σε οποιοδήποτε version του
FreeBSD θες.  Υπάρχουν διαφορές στο delivery των signals από το 3.X
στο 4.X και στο 5.X, αλλά μπορώ να στήσω όποιο version χρειάζεται στο
άδειο 1 GB partition μου, και να σου πω τι παίζει κι εδώ :P

> Ευχαριστώ, έδωσες την πιό πλήρη απάντηση μέχρι τώρα. Σίγουρα θα
> πρέπει να μπώ στα ενδότερα του Linux kernel για να δω τι συμβαίνει.

Μόνο αν είσαι σίγουρος ότι δεν έχεις κάνει πατάτα στο userlevel
κομμάτι θα είναι απαραίτητο κάτι τέτοιο.  Χωρίς να δει κάποιος το
source, δεν μπορεί κανείς να σου πει ότι κάτι τέτοιο είναι όντως
απαραίτητο.

> Η δική μου περίπτωση είναι πολύ πιό απλή. Μιλάω για ένα TCP socket και μερικά
> αρχεία (fd με select). Στο TCP ήταν συνδεδεμένο ένα client από τον localhost
> (οπότε δεν υπάρχουν προβλήματα δικτύου).  Το πρόβλημα είναι κατά τον
> τερματισμό του app (δεν ξέρα αν είναι πριν την exit() ή μέσα σ' αυτήν).
> Το signal-handler μου είναι της μορφής
> void hnd_signal(ing signum){
> 	if (signum==SIGTERM)
> 		has_to_close=true;
> }
>
> και όπως καταλαβαίνεις δεν υπάρχει περίπτωση να κολλήσει εκεί μέσα.

Σαφώς και υπάρχει περίπτωση να κολλήσει.  Αν στο socket σου είναι
ενεργοποιημένο το SO_LINGER, και υπάρχουν δεδομένα που ο receiver δεν
τα έχει διαβάσει, μπορεί στην exit() να μείνεις μέσα σε system call
όταν πάει η exit να κάνει flush όλα τα δεδομένα που μπορεί να έχει το
πρόγραμμά σου σε buffers.  Και πάλι... χωρίς source το μόνο που μπορεί
να πει κάποιος για το πρόγραμμά σου είναι "ναι, όντως κάποιος, κάπου
έχει πρόβλημα".

> δευτερο σενάριο: να έρχονται τα signals τη στιγμή που η εφαρμογή
> είναι zombie και το kernel να προσπαθεί να της τα δώσει (κρατώντας
> την ενεργή), ενώ δεν υπάρχει εφαρμογή.

Τα zombie δεν δέχονται signals.  Δεν είναι runnable διεργασίες, και το
kernel δεν στέλνει signals σε διεργασία που δεν έχει πιθανότητα ποτέ
να τρέξει.

> Εγώ έχω στείλει αρκετά (5-10 τουλάχιστον) signals, από τα οποία τα πρώτα δεν
> είναι SIGQUIT αλλά SIGINT/TERM. Δηλ. η ουρά των signals έχει στην αρχή τα
> handleable.
> Α, σημαντικό: κατά τον τερματισμό, η εφαρμογή δεν επαναφέρει τους κανονικούς
> signal handlers [2,3]

Δεν χρειάζεται.  Ανάλογα με το αν έχεις BSD signal semantics ή όχι,
και ανάλογα με το πως έχεις ρυθμίσει τα signal handlers σου, μπορεί να
επανέρχονται στο default με το που αρχίζει το delivery ενός signal.

Στο "Advanced UNIX Programming" του Richard W. Stevens και στο FAQ του
comp.unix.programmer θα βρεις πολλές πληροφορίες για το πότε και πως
μπορεί να επανέρχεται το default signal handler.

> [2] ο κανονικός handler για το SIGINT είναι το ignore

Όχι.  Αν ήταν το SIG_IGN, τότε όσες φορές και να πατούσες ^C στο
τερματικό σου, το foreground process θα σε έγραφε στα παλιά του τα
παπούτσια.

> [3] δεν προσπαθώ να κάνω καλύτερη την εφαρμογή, προσπαθώ να διορθώσω
> τον kernel εδώ.

Γιατί;  Είσαι σίγουρος ότι το kernel φταίει;

- Γιώργος



More information about the Linux-greek-users mailing list