私は現在、メモリアロケータを開発していますが、実装のLD_PRELOADを実行すると、ほぼすべてのコマンドでsegfaultの下にこのコードがあります。ここでメモリアロケータの実装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);
}
は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;
私はセグメンテーション違反の可能性が高いwhileループget_free_blockで()関数から来ているが、私は理由を理解することができないことが判明しました。
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);
}
まあ、デバッガを使いましたか? SOはそれを置き換えるものではありません。 – OldProgrammer
これは、エラーが発生したアセンブラオペコードであると仮定していますか?腕章か別のもの?また、悪いアクセスが発生したライン上でデバッガが停止することを期待しています。そうではありませんか? –
コードは "ほぼすべてのコマンド"でsegfaultsを実行してから、いくつかの機能を提供し、どのセグメンテーションが一貫しているかを教えてくれません。 [最小完全な例](http://stackoverflow.com/help/mcve)を構築しようとすると、それはすべてを助けるでしょう。 – Beta