Malloc断言问题

时间:2014-12-09 03:20:57

标签: c file malloc valgrind

我正在尝试初始化结构:

struct OpenFile
{
    unsigned short inuse;
    unsigned short inode;
    unsigned short currpos;
    unsigned short currbloqueenmemoria;
    unsigned char* buffer;
    unsigned short* indirectBuff;
};

有一个功能:

void inicializa_openfiles(){
    int i;
                            printf("Entra incializador\n");
    if(!openfiles_inicializada)
    {                                           printf("Abre\n");
        openfiles = malloc(sizeof(struct OpenFile) * 16);           

        for(i = 3; i < 16; i++)                             
        {
            openfiles[i].inuse = 0;
            openfiles[i].currbloqueenmemoria = -1;
            openfiles[i].buffer = malloc(secboot.sectores_x_bloque * BYTES_SECTOR);
        }
                                    printf("termina\n");
        openfiles_inicializada = 1;
    }
}

我在openfiles = malloc(sizeof(struct OpenFile)* 16)中得到一个断言错误; ,我尝试使用Valgrind,但我不知道如何检测问题或如何解决它。任何sugestions?提前谢谢。

编辑:这是我用Valgrind得到的,没有额外的参数:

==11136== Memcheck, a memory error detector
==11136== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==11136== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==11136== Command: ./shell1
==11136== 
vshell > copy //Test.txt text.txt
Abre y copia
Crea
Revisa existencia
==11136== Syscall param read(buf) points to unaddressable byte(s)
==11136==    at 0x4F22350: __read_nocancel (syscall-template.S:81)
==11136==    by 0x40393B: vdreadsector (in /home/svaejat/Pr8/shell1)
==11136==    by 0x400F39: vdreadseclog (in /home/svaejat/Pr8/shell1)
==11136==    by 0x401008: test_mapa_bits_nodos_i_en_memoria (in /home/svaejat/Pr8/shell1)
==11136==    by 0x401588: searchinode (in /home/svaejat/Pr8/shell1)
==11136==    by 0x401FBF: vdcreat (in /home/svaejat/Pr8/shell1)
==11136==    by 0x403072: copyuv (in /home/svaejat/Pr8/shell1)
==11136==    by 0x402DAC: executecmd (in /home/svaejat/Pr8/shell1)
==11136==    by 0x402BFA: main (in /home/svaejat/Pr8/shell1)
==11136==  Address 0x51fc240 is 0 bytes after a block of size 512 alloc'd
==11136==    at 0x4C2ABBD: malloc (vg_replace_malloc.c:296)
==11136==    by 0x400FD2: test_mapa_bits_nodos_i_en_memoria (in /home/svaejat/Pr8/shell1)
==11136==    by 0x401588: searchinode (in /home/svaejat/Pr8/shell1)
==11136==    by 0x401FBF: vdcreat (in /home/svaejat/Pr8/shell1)
==11136==    by 0x403072: copyuv (in /home/svaejat/Pr8/shell1)
==11136==    by 0x402DAC: executecmd (in /home/svaejat/Pr8/shell1)
==11136==    by 0x402BFA: main (in /home/svaejat/Pr8/shell1)
==11136== 

valgrind: m_mallocfree.c:278 (mk_plain_bszB): Assertion 'bszB != 0' failed.
valgrind: This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.


host stacktrace:
==11136==    at 0x3805DAE6: show_sched_status_wrk (m_libcassert.c:319)
==11136==    by 0x3805DBF4: report_and_quit (m_libcassert.c:390)
==11136==    by 0x3805DD76: vgPlain_assert_fail (m_libcassert.c:455)
==11136==    by 0x380688AA: mk_plain_bszB.part.8 (m_mallocfree.c:278)
==11136==    by 0x3806B057: mk_plain_bszB (m_mallocfree.c:302)
==11136==    by 0x3806B057: get_bszB_as_is (m_mallocfree.c:301)
==11136==    by 0x3806B057: get_bszB (m_mallocfree.c:312)
==11136==    by 0x3806B057: vgPlain_arena_malloc (m_mallocfree.c:1739)
==11136==    by 0x3802CC74: vgMemCheck_new_block (mc_malloc_wrappers.c:350)
==11136==    by 0x3802CE47: vgMemCheck_malloc (mc_malloc_wrappers.c:385)
==11136==    by 0x380AF1C5: do_client_request (scheduler.c:1840)
==11136==    by 0x380AF1C5: vgPlain_scheduler (scheduler.c:1409)
==11136==    by 0x380BDC8C: thread_wrapper (syswrap-linux.c:103)
==11136==    by 0x380BDC8C: run_a_thread_NORETURN (syswrap-linux.c:156)

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==11136==    at 0x4C2ABBD: malloc (vg_replace_malloc.c:296)
==11136==    by 0x401053: test_nodos_i_en_memoria (in /home/svaejat/Pr8/shell1)
==11136==    by 0x401592: searchinode (in /home/svaejat/Pr8/shell1)
==11136==    by 0x401FBF: vdcreat (in /home/svaejat/Pr8/shell1)
==11136==    by 0x403072: copyuv (in /home/svaejat/Pr8/shell1)
==11136==    by 0x402DAC: executecmd (in /home/svaejat/Pr8/shell1)
==11136==    by 0x402BFA: main (in /home/svaejat/Pr8/shell1)

编辑2:

我按照Valgrind中显示的轨迹,这是所有提到的功能:

    int vdreadsector(int drive, int head, int cylinder, int sector, int nsecs, char *buffer)
    {
        char filename[20];
        int fp;
        int timecyl,timesec;
        int sl,offset;
        sprintf(filename,"disco%c.vd",(char) drive+'0');
        fp=open(filename,O_RDONLY);
        if(fp==-1)
            return(-1);

        // Valida parámetros
        if(drive<0 || drive>3)
            return(-1);

        if(head<0 || head>=HEADS)
            return(-1);

        if(cylinder<0 || cylinder>=CYLINDERS)
            return(-1);

        if(sector<1 || sector>SECTORS)
            return(-1);

        if(sector+nsecs-1>SECTORS)
            return(-1);

        // Hace el retardo
        timesec=sector-currentsec[drive];
        if(timesec<0)
            timesec+=SECTORS;
        usleep(timesec*1000);
        currentsec[drive]=sector;

        timecyl=abs(currentcyl[drive]-cylinder);
        usleep(timecyl*1000);
        currentcyl[drive]=cylinder;

        // Calcula la posición en el archivo
        sl=cylinder*SECTORS*HEADS+head*SECTORS+(sector-1);
        offset=sl*512;
        lseek(fp,offset,SEEK_SET);
        read(fp,buffer,512*nsecs);
        close(fp);
        return(nsecs);
    }

int vdreadseclog(int sector_logico, int numero_de_sectores, char * buffer)
{
    int cilindro;
    int superficie;
    int sector_fisico;

    if(sector_logico >= 0 && sector_logico < secboot.sectores_logicos_x_unidad)
    {
        /* Calcular ubicación del sector lógico */
        cilindro = sector_logico / (secboot.sectores_fisicos * secboot.superficies);
        superficie = (sector_logico / secboot.sectores_fisicos) % secboot.superficies;
        sector_fisico = (sector_logico % secboot.sectores_fisicos) + 1;

        /* Leer el sector físico en el disco al buffer */
        if(vdreadsector(DISCO_DEFAULT, superficie, cilindro, sector_fisico, numero_de_sectores, buffer) == -1)
        {
            fprintf(stderr, "Error en vdreadsector\n");
            exit(1);
        }
    }
    else
    {
        fprintf(stderr, "Número de sector lógico inválido\n");
        exit(1);
    }
    return 1;
}

void test_mapa_bits_nodos_i_en_memoria()
{
    /* Sector donde comienza el mapa de bits de nodos i */
    int inicio = secboot.sectores_reservados + 1;
    int i;

    if(!mapa_bits_nodos_i_en_memoria)
    {
        mapa_bits_nodos_i = malloc(secboot.sectores_mapa_bits_nodos_i * BYTES_SECTOR);
        for(i = 0; i < secboot.sectores_mapa_bits_nodos_i + 1; i++)
        {
            vdreadseclog(inicio, 1, mapa_bits_nodos_i + (i * BYTES_SECTOR));
        }
        mapa_bits_nodos_i_en_memoria = 1;
    }
}

int searchinode(char *filename, int firstFileOnDir, int iNodeSearch)
{
    int i = 0, j = 0;
    int result;

    /* Si el super bloque no esta en memoria, lo leo del primer sector físico */
    test_secboot_en_memoria();

    /* Si el mapa de bits de nodos i no esta en memoria, lo leo del disco */
    test_mapa_bits_nodos_i_en_memoria();

    /* Si la tabla de nodos i no esta en memoria, la leo del disco */
    test_nodos_i_en_memoria();

    /* Recorre mientras no llegue al final del mapa de bits */
    while(i < (secboot.sectores_mapa_bits_nodos_i * BYTES_SECTOR))
    {
        // Si no está libre, entra
        if(mapa_bits_nodos_i[i] != 0x00)
        {       
            j = 0;

            /* Recorre bit por bit, probando si donde hay un '1' es el nombre
               de archivo que estamos buscando  */
            while(j < 8)
            {
                // Si es uno, verifica si el nombre de archivo es el buscado
                if(mapa_bits_nodos_i[i] & (1<<j))
                {
                    // Si estás buscando el primer archivo de root, regresa el índice
                    if(firstFileOnDir == 1)
                    {
                        return((i * 8) + j);
                    }

                    //nTest
                    if(firstFileOnDir == 2)
                    {
                        if(iNodeSearch < ((i * 8) + j))
                        {
                            return((i * 8) + j);
                        }
                    }

                    // Si es el nombre que buscamos
                    if(strcmp(nodos_i[(i * 8) + j].nombre, filename) == 0)
                    {
                        return((i * 8) + j);
                    }
                }

                j++;
            }
        }

        i++;
    }
    return (-1); /* Llego al final del mapa de bits sin encontrar un sólo bit en cero */
}

我认为searchinode存在问题,搜索出参数,但我无法解决这个问题

1 个答案:

答案 0 :(得分:1)

您观察到的行为表示,当您呼叫malloc时,听到已损坏。您的malloc电话只是检测到损坏,它不会导致

找到损坏源的最简单的特殊技巧之一是在代码中更高的上游某处插入一个具有相同请求内存大小(即malloc)的额外sizeof(struct OpenFile) * 16调用。如果它也在那里失败,你可以将更多的额外呼叫移到更高的上游。如果它没有失败,则将其向下游移动。这样你最终就能够找到破坏堆的确切罪魁祸首。 (这可能需要一些创造性来确保在您的代码中可能具有的各种循环的适当迭代和/或函数的正确调用上执行额外的malloc调用,但它是可行的。)

或者您可以将valgrind用于此目的。虽然我发现在某些情况下,如果故障很快发生并且您在支持快速重新编译代码的环境中工作,上述临时过程被证明是一种更有效的查找损坏源的方法。