Domanda

sto attuando un divide et impera algoritmo polinomiale così posso punto di riferimento contro un'implementazione OpenCL, ma non riesco a ottenere malloc al lavoro. Quando eseguo il programma, assegna un mucchio di roba, controlla alcune cose, quindi invia il size/2 all'algoritmo. Poi, quando mi ha colpito di nuovo la linea malloc sputa fuori questo:

malloc.c: 3096: sYSMALLOc: Asserzione `(old_top == (((mbinptr) (((char *) & ((AV) -> bidoni [((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((Unsigned long) (old_size)> = (unsigned long) ((((__ builtin_offsetof (struct malloc_chunk, fd_nextsize)) + ((2 * (sizeof (size_t))) - 1)) e ~ ((2 * (sizeof (size_t))) - 1))) && ((old_top) -> dimensioni e 0x1) && ((unsigned long) old_end & pagemask) == 0)' fallito. Annullato

La linea in questione è:

int *mult(int size, int *a, int *b) {
    int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2;
    fprintf(stdout, "size: %d\n", size);

    out = (int *)malloc(sizeof(int) * size * 2);
}

I controllato dimensioni con un fprintf, ed è un numero intero positivo (di solito 50 a questo punto). Ho provato a chiamare malloc con un numero semplice come bene e ho ancora ottenere l'errore. Sto solo perplesso a quello che sta succedendo, e nulla da parte di Google che ho trovato finora è utile.

Tutte le idee che cosa sta succedendo? Sto cercando di capire come compilare un GCC più recente nel caso in cui si tratta di un errore di compilazione, ma davvero dubito.

È stato utile?

Soluzione

99,9% di probabilità di avere corrotto memoria (sovra o sotto-scorreva un buffer, scrisse a un puntatore dopo che è stato liberato, chiamata gratuita due volte sullo stesso puntatore, ecc.)

Esegui il codice sotto Valgrind per vedere dove il programma ha fatto qualcosa di scorretto.

Altri suggerimenti

Per darvi una migliore comprensione del perché questo accade, mi piacerebbe estendere alla risposta di @ r-samuel-klatchko un po '.

Quando si chiama malloc, cosa sta realmente accadendo è un po 'più complicato di un semplice ti dà un pezzo di memoria con cui giocare. Sotto il cofano, malloc mantiene anche alcune informazioni di pulizia sulla memoria che vi ha dato (cosa più importante, le sue dimensioni), in modo che quando si chiama free, sa cose come la quantità di memoria per liberare. Questa informazione è comunemente mantenuto a destra prima la posizione di memoria restituita a voi da malloc. Informazioni più esaustivo si possono trovare su internet ™ , ma la (molto) idea di base è qualcosa di simile:

+------+-------------------------------------------------+
+ size |                  malloc'd memory                +
+------+-------------------------------------------------+
       ^-- location in pointer returned by malloc

Sulla base di questo (e semplificando notevolmente le cose), quando si chiama malloc, ha bisogno di ottenere un puntatore alla prossima parte della memoria che è disponibile. Un modo molto semplice per farlo è quello di guardare il precedente bit di memoria che ha dato via, e spostare size byte, più in basso (o verso l'alto) in memoria. Con questa implementazione, si finisce con la memoria cercando qualcosa di simile dopo l'attribuzione di p1, p2 e p3:

+------+----------------+------+--------------------+------+----------+
+ size |                | size |                    | size |          +
+------+----------------+------+--------------------+------+----------+
       ^- p1                   ^- p2                       ^- p3

Quindi, che cosa sta causando il vostro errore?

Bene, immaginate che il vostro codice scrive erroneamente oltre la quantità di memoria che avete assegnato (o perché avete assegnato meno di quanto si aveva bisogno, come è stato il tuo problema o perché si sta utilizzando le condizioni al contorno sbagliato da qualche parte nel codice). Dire il codice scrive così tanti dati per p2 che inizia a sovrascrivere ciò che è in campo p3 di size. Quando ora chiamata successiva malloc, si guarderà alla ultima posizione di memoria è tornato, sguardo al suo campo formato, passare a p3 + size e quindi avviare l'allocazione di memoria da lì. Dal momento che il codice ha size sovrascritto, tuttavia, questa posizione di memoria non è più dopo che la memoria precedentemente allocato.

Inutile dire che questo può relitto caos! Gli implementatori di malloc hanno quindi messo in un certo numero di "asserzioni", o assegni, che cercano di fare un po 'di sanità mentale controllo per la cattura di questa (e altre questioni), se sono per accadere. Nel vostro caso particolare, queste affermazioni sono violati e, quindi, di interrompere la malloc, che indica che il codice è stato sul punto di fare qualcosa che in realtà non dovrebbe fare.

Come detto in precedenza, questa è una grossolana semplificazione, ma è sufficiente per illustrare il punto. L'implementazione di glibc malloc è più di 5K linee, e ci sono stati notevoli quantità di ricerca su come costruire buoni meccanismi di allocazione dinamica della memoria, in modo da coprire tutto in una risposta così non è possibile. Speriamo che questo vi ha dato un po 'di vista di ciò che è realmente la causa del problema però!

La mia soluzione alternativa all'utilizzo Valgrind:

Sono molto contento perché ho appena aiutato il mio amico di debug di un programma. Il suo programma ha avuto questo problema esatto (malloc() causando interruzione), con lo stesso messaggio di errore da GDB.

Ho compilato il suo programma utilizzando Indirizzo Sanitizer con

gcc -Wall -g3 -fsanitize=address -o new new.c
              ^^^^^^^^^^^^^^^^^^

E poi corse gdb new. Quando il programma viene terminato da SIGABRT causato in un successivo malloc(), viene stampato un sacco di informazioni utili:

=================================================================
==407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000000b4 at pc 0x7ffffe49ed1a bp 0x7ffffffedc20 sp 0x7ffffffed3c8
WRITE of size 104 at 0x6060000000b4 thread T0
    #0 0x7ffffe49ed19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x8001dab in CreatHT2 /home/wsl/Desktop/hash/new.c:59
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #4 0x8001679 in _start (/mnt/d/Desktop/hash/new+0x1679)

0x6060000000b4 is located 0 bytes to the right of 52-byte region [0x606000000080,0x6060000000b4)
allocated by thread T0 here:
    #0 0x7ffffe51eb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x8001d56 in CreatHT2 /home/wsl/Desktop/hash/new.c:55
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

Diamo uno sguardo in uscita, in particolare l'analisi dello stack:

La prima parte dice che c'è un'operazione di scrittura non valida a new.c:59. Quella linea si legge

memset(len,0,sizeof(int*)*p);
             ^^^^^^^^^^^^

La seconda parte dice che la memoria che la cattiva scrittura è accaduto è stato creato a new.c:55. Quella linea si legge

if(!(len=(int*)malloc(sizeof(int)*p))){
                      ^^^^^^^^^^^

Questo è tutto. Mi ci sono voluti solo meno di mezzo minuto per individuare il bug che confuso il mio amico per un paio d'ore. Egli è riuscito a localizzare il guasto, ma è una chiamata successiva malloc() che non è riuscita, senza essere in grado di individuare questo errore nel codice precedente.

sintesi: Prova la -fsanitize=address di GCC o Clang. Può essere molto utile durante il debug problemi di memoria.

Probabilmente si sta a ruota libera al di là del posto mem assegnato. poi il sw sottostante non prendere su di esso fino a quando si chiama malloc

Non ci può essere un valore di guardia clobbered che viene catturato da malloc.

modifica ... aggiunto questo per controllo dei limiti aiuto

http: //www.lrde.epita. fr / ~ Akim / CCMP / doc / limiti-checking.html

ho ottenuto il seguente messaggio, simile al vostro uno:

    program: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.

ha fatto un errore che alcuni chiamano metodo prima, quando si utilizza malloc. Erroneamente sovrascritto il segno di moltiplicazione '*' con un '+', quando si aggiorna il fattore dopo sizeof () -. Operatore aggiunta di un campo di matrice char unsigned

Ecco il codice responsabile per l'errore nel mio caso:

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)+5);
    b[INTBITS]=(some calculation);
    b[BUFSPC]=(some calculation);
    b[BUFOVR]=(some calculation);
    b[BUFMEM]=(some calculation);
    b[MATCHBITS]=(some calculation);

In un altro metodo dopo, ho usato di nuovo malloc e ha prodotto il messaggio di errore sopra indicato. La chiamata era (abbastanza semplice):

    UCHAR* b=(UCHAR*)malloc(sizeof(UCHAR)*50);

Credo utilizzando il '+' - segno al 1 ° chiamata, che portano a mis-calcolo in combinazione con l'inizializzazione immediata della matrice dopo (sovrascrittura memoria non allocato alla matrice), ha portato qualche confusione mappa della memoria di malloc. Pertanto, la seconda chiamata è andato storto.

Abbiamo ottenuto questo errore perché abbiamo dimenticato di moltiplicare per sizeof (int). Nota l'argomento per malloc (..) è un numero di byte, senza numero di parole della macchina o qualsiasi altra cosa.

I è stato il porting di un'applicazione da Visual C a gcc su Linux e ho avuto lo stesso problema con

malloc.c: 3096: sYSMALLOc:. Assertion usando gcc su Ubuntu 11

I spostato lo stesso codice per una distribuzione Suse (su un altro computer) e non ho alcun problema.

Ho il sospetto che i problemi non sono nei nostri programmi, ma nella propria libc.

ho avuto lo stesso problema, ho usato malloc sopra n più volte in un ciclo per l'aggiunta di nuovi char * dati stringa. ho affrontato lo stesso problema, ma dopo aver rilasciato la memoria allocata void free() problema fosse ordinato

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top