(Δεν εξηγούνται ελέγχοι σε αυτήν τη σύνοψη και κάποιες περιπτώσεις έχουν παραλειφθεί για συντομία)
Η __libc_malloc προσπαθεί να αποκτήσει ένα κομμάτι από το tcache, αν δεν υπάρχει καλεί το _int_malloc
_int_malloc :
Προσπαθεί να δημιουργήσει την αρένα αν δεν υπάρχει
Αν υπάρχει οποιοδήποτε fast bin chunk του σωστού μεγέθους, το χρησιμοποιεί
Γεμίζει το tcache με άλλα fast chunks
Αν υπάρχει οποιοδήποτε small bin chunk του σωστού μεγέθους, το χρησιμοποιεί
Γεμίζει το tcache με άλλα κομμάτια του ίδιου μεγέθους
Αν το ζητούμενο μέγεθος δεν είναι για small bins, συγχωνεύει το fast bin στο unsorted bin
Ελέγχει το unsorted bin, χρησιμοποιεί το πρώτο κομμάτι με αρκετό χώρο
Αν το βρεθέν κομμάτι είναι μεγαλύτερο, το διαιρεί για να επιστρέψει ένα μέρος και προσθέτει το υπόλοιπο πίσω στο unsorted bin
Αν ένα κομμάτι είναι του ίδιου μεγέθους με το ζητούμενο μέγεθος, το χρησιμοποιεί για να γεμίσει το tcache αντί να το επιστρέψει (μέχρι το tcache να γεμίσει, τότε επιστρέφει το επόμενο)
Για κάθε κομμάτι μικρότερου μεγέθους που ελέγχεται, το τοποθετεί στο αντίστοιχο small ή large bin
Ελέγχει το large bin στο δείκτη του ζητούμενου μεγέθους
Ξεκινά από το πρώτο κομμάτι που είναι μεγαλύτερο από το ζητούμενο μέγεθος, αν βρεθεί κάποιο επιστρέφει αυτό και προσθέτει τα υπόλοιπα στο small bin
Ελέγχει τα large bins από τους επόμενους δείκτες μέχρι το τέλος
Από τον επόμενο μεγαλύτερο δείκτη ελέγχει για οποιοδήποτε κομμάτι, διαιρεί το πρώτο βρεθέν κομμάτι για να το χρησιμοποιήσει για το ζητούμενο μέγεθος και προσθέτει το υπόλοιπο στο unsorted bin
Αν δεν βρεθεί τίποτα στα προηγούμενα bins, παίρνει ένα κομμάτι από το top chunk
Αν το top chunk δεν ήταν αρκετά μεγάλο, το μεγαλώνει με το sysmalloc
__libc_malloc
Η συνάρτηση malloc καλεί πραγματικά την __libc_malloc. Αυτή η συνάρτηση θα ελέγξει το tcache για να δει αν υπάρχει διαθέσιμο κομμάτι του επιθυμητού μεγέθους. Αν υπάρχει, θα το χρησιμοποιήσει και αν όχι, θα ελέγξει αν είναι μονό νήμα και σε αυτήν την περίπτωση θα καλέσει το _int_malloc στην κύρια αρένα, και αν όχι, θα καλέσει το _int_malloc στην αρένα του νήματος.
Κώδικας __libc_malloc
```c // From https://github.com/bminor/glibc/blob/master/malloc/malloc.c
victim = _int_malloc (ar_ptr, bytes); /* Retry with another arena only if we were able to find a usable arena before. */ if (!victim && ar_ptr != NULL) { LIBC_PROBE (memory_malloc_retry, 1, bytes); ar_ptr = arena_get_retry (ar_ptr, bytes); victim = _int_malloc (ar_ptr, bytes); }
if (ar_ptr != NULL) __libc_lock_unlock (ar_ptr->mutex);
</details>
Σημειώστε πώς πάντα θα επισημαίνει τον επιστρεφόμενο δείκτη με `tag_new_usable`, από τον κώδικα:
```c
void *tag_new_usable (void *ptr)
Allocate a new random color and use it to color the user region of
a chunk; this may include data from the subsequent chunk's header
if tagging is sufficiently fine grained. Returns PTR suitably
recolored for accessing the memory there.
_int_malloc
Αυτή είναι η συνάρτηση που εκχωρεί μνήμη χρησιμοποιώντας τα άλλα bins και το top chunk.
Έναρξη
Ξεκινάει ορίζοντας μερικές μεταβλητές και παίρνοντας το πραγματικό μέγεθος που χρειάζεται ο χώρος μνήμης που ζητείται:
Γρήγορος Κάδος
Εάν το απαιτούμενο μέγεθος βρίσκεται μέσα στα μεγέθη των Γρήγορων Κάδων, προσπαθήστε να χρησιμοποιήσετε ένα κομμάτι από τον γρήγορο κάδο. Βασικά, με βάση το μέγεθος, θα βρει το δείκτη του γρήγορου κάδου όπου θα πρέπει να βρίσκονται έγκυρα κομμάτια και, αν υπάρχει κάποιο, θα επιστρέψει ένα από αυτά.
Επιπλέον, εάν ο tcache είναι ενεργοποιημένος, θα γεμίσει τον tcache κάδο αυτού του μεγέθους με γρήγορους κάδους.
Κατά τη διάρκεια αυτών των ενεργειών, πραγματοποιούνται ορισμένοι έλεγχοι ασφαλείας εδώ:
Εάν το κομμάτι δεν είναι σωστά ευθυγραμμισμένο: malloc(): unaligned fastbin chunk detected 2
Εάν το επόμενο κομμάτι δεν είναι σωστά ευθυγραμμισμένο: malloc(): unaligned fastbin chunk detected
Εάν το επιστρεφόμενο κομμάτι έχει ένα μέγεθος που δεν είναι σωστό λόγω του δείκτη του στον γρήγορο κάδο: malloc(): memory corruption (fast)
Εάν οποιοδήποτε κομμάτι που χρησιμοποιείται για να γεμίσει τον tcache δεν είναι σωστά ευθυγραμμισμένο: malloc(): unaligned fastbin chunk detected 3
malloc_συγχώνευση
Αν δεν πρόκειται για ένα μικρό κομμάτι, είναι ένα μεγάλο κομμάτι, και σε αυτήν την περίπτωση καλείται το malloc_consolidate για να αποφευχθεί η διάσπαση μνήμης.
Μη ταξινομημένος κάδος
Είναι καιρός να ελέγξουμε τον μη ταξινομημένο κάδο για ένα πιθανό έγκυρο κομμάτι που μπορούμε να χρησιμοποιήσουμε.
Έναρξη
Αυτό ξεκινά με ένα μεγάλο βρόχο που θα διατρέχει τον μη ταξινομημένο κάδο προς την κατεύθυνση bk μέχρι να φτάσει στο τέλος (τη δομή arena) με while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av))
Επιπλέον, πραγματοποιούνται ορισμένοι έλεγχοι ασφαλείας κάθε φορά που λαμβάνεται υπόψη ένα νέο κομμάτι:
Εάν το μέγεθος του κομματιού είναι παράξενο (πολύ μικρό ή πολύ μεγάλο): malloc(): invalid size (unsorted)
Εάν το μέγεθος του επόμενου κομματιού είναι παράξενο (πολύ μικρό ή πολύ μεγάλο): malloc(): invalid next size (unsorted)
Εάν το προηγούμενο μέγεθος που υποδηλώνεται από το επόμενο κομμάτι διαφέρει από το μέγεθος του κομματιού: malloc(): mismatching next->prev_size (unsorted)
Εάν δεν ισχύει victim->bck->fd == victim ή δεν ισχύει victim->fd == av (arena): malloc(): unsorted double linked list corrupted
Δεδομένου ότι ελέγχουμε πάντα τον τελευταίο, το fd του πρέπει να δείχνει πάντα προς τη δομή arena.
Εάν το επόμενο κομμάτι δεν υποδηλώνει ότι το προηγούμενο είναι σε χρήση: malloc(): invalid next->prev_inuse (unsorted)
Εάν αυτό ήταν επιτυχές, επιστρέψτε το κομμάτι και τελειώσαμε, αλλιώς συνεχίστε την εκτέλεση της συνάρτησης...
εάν η διάσταση είναι ίση
Συνεχίστε να αφαιρείτε το κομμάτι από το bin, σε περίπτωση που το ζητούμενο μέγεθος είναι ακριβώς όπως του κομματιού:
Εάν το tcache δεν είναι γεμάτο, προσθέστε το στο tcache και συνεχίστε να υποδεικνύετε ότι υπάρχει ένα κομμάτι tcache που θα μπορούσε να χρησιμοποιηθεί
Εάν το tcache είναι γεμάτο, απλώς χρησιμοποιήστε το επιστρέφοντάς το
Όρια _int_malloc
Σε αυτό το σημείο, αν κάποιο τμήμα αποθηκεύτηκε στο tcache που μπορεί να χρησιμοποιηθεί και έχει φτάσει το όριο, απλά επιστρέψτε ένα tcache τμήμα.
Επιπλέον, αν φτάσει το MAX_ITERS, διακόψτε τον βρόγχο και αποκτήστε ένα τμήμα με διαφορετικό τρόπο (top chunk).
Αν η return_cached έχει οριστεί, απλά επιστρέψτε ένα τμήμα από το tcache για να αποφύγετε μεγαλύτερες αναζητήσεις.
Αν δεν βρεθεί ένα κομμάτι που να είναι κατάλληλο για αυτό, συνεχίστε
Μεγάλο Bin (επόμενο μεγαλύτερο)
Αν στο συγκεκριμένο μεγάλο bin δεν υπήρχε κανένα κομμάτι που θα μπορούσε να χρησιμοποιηθεί, ξεκινήστε έναν βρόχο μέσω όλων των επόμενων μεγάλων bin (ξεκινώντας από τον αμέσως μεγαλύτερο) μέχρι να βρεθεί ένα (αν υπάρχει).
Το υπόλοιπο του κομματιού που χωρίστηκε προστίθεται στον μη ταξινομημένο bin, ενημερώνεται το last_reminder και πραγματοποιείται έλεγχος ασφαλείας:
bck->fd-> bk != bck: malloc(): corrupted unsorted chunks2
Έλεγχοι sysmalloc
Ξεκινά ανακτώντας πληροφορίες για τον παλιό κορυφαίο κομμάτι και ελέγχοντας ότι κάποιες από τις ακόλουθες συνθήκες είναι αληθείς:
Το παλιό μέγεθος του σωρού είναι 0 (νέος σωρός)
Το μέγεθος του προηγούμενου σωρού είναι μεγαλύτερο από το MINSIZE και ο παλιός Κορυφή είναι σε χρήση
Ο σωρός είναι ευθυγραμμισμένος με το μέγεθος της σελίδας (0x1000 έτσι ώστε τα χαμηλότερα 12 bits να είναι 0)
Στη συνέχεια ελέγχει επίσης ότι:
Το παλιό μέγεθος δεν έχει αρκετό χώρο για να δημιουργηθεί ένα κομμάτι για το ζητούμενο μέγεθος
Κύριος χώρος sysmalloc
Ξεκινά υπολογίζοντας το ποσό της μνήμης που χρειάζεται. Θα ξεκινήσει ζητώντας συνεχόμενη μνήμη, έτσι ώστε σε αυτήν την περίπτωση να είναι δυνατή η χρήση της παλιάς μνήμης που δεν χρησιμοποιείται. Επίσης, πραγματοποιούνται κάποιες λειτουργίες ευθυγράμμισης.
sysmalloc κυρίως συνέχεια αρένας
Αν το προηγούμενο δεν επέστρεψε MORECORE_FAILURE, αν λειτούργησε δημιουργήστε κάποιες ευθυγραμμίσεις: