2017-01-30 1 views
2

Ich entwickle derzeit eine Speicherzuweisung, ich habe mit diesem Code einen Moment, aber diesen Code unter segfault auf fast alle Befehle, wenn ich eine LD_PRELOAD meiner Implementierung. HierMemory Allocator Implementierung segfault

#include <pthread.h> 
#include "malloc.h" 

t_mem_map  g_map; 
int   g_empty_map = TRUE; 

static t_ctrl  *get_free_block(size_t size) 
{ 
    t_ctrl  *tmp; 

    tmp = g_map.head; 
    while (tmp != NULL) 
    { 
     if (tmp->is_free == TRUE && tmp->size < size) 
    { 
     tmp->is_free = FALSE; 
     return (tmp); 
    } 
     tmp = tmp->next; 
    } 
    return (NULL); 
} 

static void  *init_map(size_t size) 
{ 
    t_ctrl  *tmp; 

    g_map.map_size = DEFAULT_MAP_SIZE; 
    while (g_map.map_size < size + sizeof(t_ctrl)) 
    g_map.map_size += DEFAULT_MAP_SIZE; 
    if ((g_map.head = (t_ctrl *)sbrk(g_map.map_size)) == (void *)-1) 
    return (NULL); 
    tmp = g_map.head; 
    tmp->next = NULL; 
    tmp->prev = NULL; 
    tmp->size = size; 
    tmp->is_free = FALSE; 
    g_map.free_space = g_map.map_size - size - sizeof(t_ctrl); 
    g_empty_map = FALSE; 
    unlock_thread(); 
    return ((void *)((char *)tmp + sizeof(t_ctrl))); 
} 

static void  *add_block(size_t size) 
{ 
    t_ctrl  *tmp; 
    t_ctrl  *new; 

    tmp = get_free_block(size); 
    if (tmp != NULL) 
    return ((void *)((char *)tmp + sizeof(t_ctrl))); 
    tmp = g_map.head; 
    while (tmp->next != NULL) 
    tmp = tmp->next; 
    new = (t_ctrl *)((char *)tmp + sizeof(t_ctrl) + tmp->size); 
    new->prev = tmp; 
    new->next = NULL; 
    tmp->next = new; 
    new->size = size; 
    new->is_free = FALSE; 
    g_map.free_space -= (new->size + sizeof(t_ctrl)); 
    unlock_thread(); 
    return ((void *)((char *)new + sizeof(t_ctrl))); 
} 

static void  *resize_map(size_t size) 
{ 
    size_t  size_shift; 

    size_shift = 0; 
    while (g_map.free_space < size + sizeof(t_ctrl)) 
    { 
     g_map.map_size += DEFAULT_MAP_SIZE; 
     g_map.free_space += DEFAULT_MAP_SIZE; 
     size_shift += DEFAULT_MAP_SIZE; 
    } 
    if (sbrk(size_shift) == (void *)-1) 
    return (NULL); 
    return (add_block(size)); 
} 

void   *malloc(size_t size) 
{ 
    size_t  a_size; 

    lock_thread(); 
    a_size = ALIGN(size); 
    if (g_empty_map == TRUE) 
    return (init_map(a_size)); 
    else 
    { 
     if ((a_size + sizeof(t_ctrl)) <= g_map.free_space) 
     return (add_block(a_size)); 
     else 
    return (resize_map(a_size)); 
    } 
    return (NULL); 
} 

ist die malloc.h:

# include <stdio.h> 
# include <stddef.h> 
# include <unistd.h> 

# define TRUE 0 
# define FALSE 1 

# define SUCCESS 0 
# define FAILURE 1 


# ifndef __X86_64__ 
# define ALIGNMENT (16) 
# else 
# define ALIGNMENT (8) 
# endif 

# define ALIGN(size) (((size) + (ALIGNMENT - 1)) &~ (ALIGNMENT - 1)) 
# define DEFAULT_MAP_SIZE (ALIGN(sysconf(_SC_PAGESIZE))) 

typedef struct  s_ctrl 
{ 
    size_t  is_free; 
    size_t  size; 
    struct s_ctrl  *next; 
    struct s_ctrl  *prev; 
}   t_ctrl; 

typedef struct  s_mem_map 
{ 
    size_t  map_size; 
    size_t  free_space; 
    // int   free_blocks; 
    //int   nb_blocks; 
    t_ctrl  *head; 
}   t_mem_map; 

Mit einigen Recherchen fand ich heraus, dass die segfault wahrscheinlich aus der while-Schleife kommt in der get_free_block() Funktion, aber ich kann nicht verstehen, warum .

static t_ctrl  *get_free_block(size_t size) 
{ 
    t_ctrl  *tmp; 

    tmp = g_map.head; 
    while (tmp != NULL) 
    { 
     if (tmp->is_free == TRUE && tmp->size < size) 
     { 
      tmp->is_free = FALSE; 
      return (tmp); 
     } 
     tmp = tmp->next; 
    } 
    return (NULL); 
} 
+3

Nun, haben Sie einen Debugger verwendet? SO ist kein Ersatz dafür. – OldProgrammer

+0

Ich nehme an, dass das ein Assembler-Opcode ist, auf dem der Fehler auftritt? Arm-ish oder etwas anderes? ALSO würde ich erwarten, dass der Debugger genau in der Zeile stoppt, in der der schlechte Zugriff auftritt - nicht wahr? –

+0

Sie sagen uns, dass der Code segfold auf "fast jeden Befehl", dann geben Sie uns mehrere Funktionen und sagen uns nicht, welche - wenn überhaupt - segfaults konsistent. Versuchen Sie, ein [minimales vollständiges Beispiel] (http://stackoverflow.com/help/mcve) zu konstruieren, es wird alles helfen. – Beta

Antwort

4

kann nicht überprüfen, ob dies das einzige Problem ist, aber Sie überprüfen tmp->size < size, wenn Sie wahrscheinlich tmp->size >= size statt überprüfen sollten.

+0

Oh mein Gott, ich habe meinen Code mehrmals überprüft und diesen Fehler nicht gesehen, danke. – Epoch

+1

@ Epoch: Ja, ich kenne dieses Gefühl. Kennen Sie [Rubber Duck Debugging] (https://de.m.wikipedia.org/wiki/Rubber_duck_debugging)? Das hilft manchmal. – MikeMB

+0

Nein, ich kannte diese Methode nicht, danke für den Hinweis. – Epoch