Linux 由于glibc内存损坏,Xilinx fuse在debian上编译vhdl代码失败

Linux 由于glibc内存损坏,Xilinx fuse在debian上编译vhdl代码失败,linux,gcc,vhdl,xilinx,Linux,Gcc,Vhdl,Xilinx,我正在尝试使用xilinx的fuse(ISE的一部分)编译一个vhdl文件,使用我从大学获得的库--pgm\u pkg.vhd。该库用于将*.pgm图像格式读入vhdl模拟器。在windows的Modelsim中进行模拟时,它可以正常工作,但不幸的是,在使用fuse在debian上编译时,它会产生以下错误: ***glibc检测到***/opt/Xilinx/14.4/ISE\u DS/ISE/bin/lin64/unwrapped/fuse:malloc():内存损坏(fast):0x0000

我正在尝试使用xilinx的fuse(ISE的一部分)编译一个vhdl文件,使用我从大学获得的库--
pgm\u pkg.vhd
。该库用于将*.pgm图像格式读入vhdl模拟器。在windows的Modelsim中进行模拟时,它可以正常工作,但不幸的是,在使用fuse在debian上编译时,它会产生以下错误:
***glibc检测到***/opt/Xilinx/14.4/ISE\u DS/ISE/bin/lin64/unwrapped/fuse:malloc():内存损坏(fast):0x00000000019c7780***

在运行windows的虚拟机上使用Modelsim(在学生版中速度非常慢)(这使它更慢)是我愿意不惜任何代价避免的事情。 我已将问题缩小到函数
read_pgm_file()
,该函数迭代*.pgm文件并提供图像的后续像素

我读过gcc经常在编译崩溃之前的许多行中提出这种错误,但即使这样也没有帮助,因为fuse是一个封闭源代码的应用程序。我尝试过使用不同的*.pgm图片,我也尝试过使用详细模式编译它(我没有发现任何有用的东西),并且在编译多线程关闭的情况下-仍然会发生相同的错误

1) 我如何处理这样的错误?编译过程中是否有调试工具? 2) 图书馆怎么了?我看不到任何可能导致问题的东西,尤其是同一个库在windows上运行得非常好

vhdl测试文件: 图书馆IEEE; 使用IEEE.std_logic_1164.all; 使用IEEE.std_logic_arith.all; 使用IEEE.std_logic_unsigned.all

    USE work.pgm_pkg.ALL; -- read and write pgm format files package (max 512x512)

    entity test_raw_tb is
        GENERIC (
                    ifile : STRING := "pepper.ascii.pgm"
        );
    end test_raw_tb;

    architecture behavioral of test_raw_tb is
        constant infile : pgm_record_type := read_pgm_file(ifile);
    begin   -- architecture

    end behavioral;
pgm_pkg.vhd库:

PACKAGE pgm_pkg IS

    constant max : NATURAL := 640;
    constant pgm_row_size : integer :=18;

  TYPE pixel_array_type IS ARRAY(0 TO max-1, 0 TO max - 1) OF integer;

  TYPE pgm_record_type IS RECORD
    magic_number : STRING(1 TO 2);
    width        : NATURAL;
    height       : NATURAL;
    max_val      : NATURAL;
    pixel        : pixel_array_type;
  END RECORD;

  IMPURE FUNCTION read_pgm_file(filename : IN STRING) 
  RETURN pgm_record_type;

  IMPURE FUNCTION write_pgm_file(filename : IN STRING; pgm : pgm_record_type) 
  RETURN BOOLEAN;

  IMPURE FUNCTION write_pgm_comment_file(filename : IN STRING; pgm : pgm_record_type) 
  RETURN BOOLEAN;

END pgm_pkg;
-----------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
library std;
use std.textio.all;

PACKAGE BODY pgm_pkg IS

   IMPURE FUNCTION read_pgm_file(filename : IN STRING) 
    RETURN pgm_record_type IS
    FILE     filehandle   : TEXT open read_mode is filename;
    VARIABLE inline       : LINE;
    VARIABLE inline_copy  : LINE;
    VARIABLE char         : CHARACTER;
    VARIABLE good         : BOOLEAN;
    VARIABLE number       : integer;
    VARIABLE header_index : NATURAL;
    VARIABLE magic_number : STRING(1 TO 2);
    VARIABLE got_magic_number : BOOLEAN := FALSE;
    VARIABLE width        : NATURAL;
    VARIABLE height       : NATURAL;
    VARIABLE max_val      : NATURAL;
    VARIABLE got_header   : BOOLEAN;
    VARIABLE pi,pj        : NATURAL; -- pixel index
    VARIABLE pgm          : pgm_record_type;
  BEGIN
    got_magic_number := FALSE;
    got_header := FALSE;
    header_index := 0;
    pi := 0; -- pixel index
    pj := 0;
    WHILE (NOT(ENDFILE(filehandle))) LOOP
      READLINE(filehandle, inline);
      -- make a copy of inline string for later (note it's an access type)
      inline_copy := new STRING'(inline.ALL);
      READ(inline, char, good);
      -- move on to next line if it's a comment
      NEXT WHEN char = '#';
      -- special case for magic number
      IF (got_magic_number = FALSE) THEN
        ASSERT (char = 'P' OR char = 'p')
          REPORT "Error: Not PGM format file. Magic number should start with P."
          SEVERITY FAILURE;
        READ(inline, char, good);
        ASSERT (char = '2')
          REPORT "Error: Not ASCII PGM format file. Magic number should be P2."
          SEVERITY FAILURE;
        pgm.magic_number(1) := 'P';
        pgm.magic_number(2) := '2';
        got_magic_number := TRUE;
        -- strip off first two characters of inline_copy as they were magic_number
        READ(inline_copy, char, good);
        READ(inline_copy, char, good);
      END IF;
      IF (got_magic_number = TRUE) THEN 
        good := TRUE;
        WHILE (inline_copy'LENGTH /= 0 AND good = TRUE) LOOP
          READ(inline_copy, number, good);
          IF (good = TRUE) THEN
            IF (got_header = TRUE) THEN
              pgm.pixel(pi,pj) := number;
              pj := pj + 1;
              if pj=pgm.width then
                 pj:=0;
                 pi:=pi+1;
              end if;
            ELSE
              IF (header_index = 0) THEN -- it must be width
                pgm.width := number;
                header_index := 1; -- look for height next
                ELSIF (header_index = 1) THEN -- it must be height
                pgm.height := number;
                header_index := 2; -- look for max_val next
              ELSE -- it must be max_val
                pgm.max_val := number;
                got_header := TRUE;
              END IF; -- header_index
            END IF; -- got_header
          END IF; -- good
        END LOOP;
      END IF; -- got_magic_number = TRUE
    END LOOP; -- NOT ENDFILE
    ASSERT got_header
      REPORT "Error: Can't find header information - giving up."
      SEVERITY FAILURE;      
    RETURN pgm;
  END read_pgm_file;

-----------------------------------------------------------------------

  IMPURE FUNCTION write_pgm_comment_file(filename : IN STRING;
                          pgm : pgm_record_type) 
    RETURN BOOLEAN IS
    FILE     filehandle : TEXT open write_mode is filename;
    VARIABLE outline : LINE;
    VARIABLE pi,pj : NATURAL; -- pixel index
    VARIABLE k : NATURAL := 0;
    CONSTANT row_comment : STRING := "# row ";
  BEGIN

    WRITE(outline, pgm.magic_number);
    WRITELINE(filehandle, outline);
    WRITE(outline, pgm.width);
    WRITELINE(filehandle, outline);
    WRITE(outline, pgm.height);
    WRITELINE(filehandle, outline);
    WRITE(outline, pgm.max_val);
    WRITELINE(filehandle, outline);
    pi := 0;
    pj := 0;
    k := 0;

    wfile_i: 
    for pi in 0 to pgm.height-1 loop
        write(outline, string'("# row "));
        write(outline, pi, left, 5);
        writeline(filehandle, outline);
        wfile_j: 
        for pj in 0 to pgm.width-1 loop
            write(outline,pgm.pixel(pi,pj),right,4);
            if k < (pgm_row_size - 1) then
                k:=k+1;
            else
                writeline(filehandle,outline); 
                k:=0;
            end if;
        end loop wfile_j;
        k:=0;       
        writeline(filehandle,outline); 
    end loop wfile_i;

    RETURN TRUE;
end write_pgm_comment_file;

-----------------------------------------------------------------------------

  IMPURE FUNCTION write_pgm_file(filename : IN STRING;
                          pgm : pgm_record_type) 
    RETURN BOOLEAN IS
    FILE     filehandle : TEXT open write_mode is filename;
    VARIABLE outline : LINE;
    VARIABLE pi,pj : NATURAL; -- pixel index
    VARIABLE k : NATURAL := 0;
  BEGIN

    WRITE(outline, pgm.magic_number);
    WRITELINE(filehandle, outline);
    WRITE(outline, pgm.width);
    WRITE(outline, ' ');
    WRITE(outline, pgm.height);
    WRITELINE(filehandle, outline);
    WRITE(outline, pgm.max_val);
    WRITELINE(filehandle, outline);
    pi := 0;
    pj := 0;
    k := 0;

       wfile_i: 
       for pi in 0 to pgm.height-1 loop
           wfile_j: 
           for pj in 0 to pgm.width-1 loop
               write(outline,pgm.pixel(pi,pj),right,4);
               if k < (pgm_row_size - 1) then
                   k:=k+1;
               else
                   writeline(filehandle,outline); 
                   k:=0;
               end if;
           end loop wfile_j;
           k:=0;
           writeline(filehandle,outline); 
       end loop wfile_i;

    RETURN TRUE;
    end write_pgm_file;

end pgm_pkg;

PGM是一种基于ASCII的格式,这也是因为ISE模拟器在访问二进制文件时遇到问题。(这是可以做到的,但您必须跳过一些障碍,包括Xilinx实际上拒绝记录的9字节头)

最可能的原因是您试图在堆栈上返回固定大小的640x640x4字节数组,而不管实际图像大小如何。不管是谁写的,都需要检查他们的脑袋

但在进一步进行这一推理之前,有必要检查堆栈上的小得多的数组是否可以工作。找到一个小的PGM文件(例如,16*16)并编辑包,使其“max”略大于该文件(20*20或32*32应该是安全的)

假设这是可行的,报告回来,我们就可以找到一个更合适的解决方案:要么是带有out参数的过程(调用者分配它),要么是返回实际存储的访问类型(指针)的函数

或者:尝试GHDL作为替代模拟器。它有运行时选项来控制堆栈大小,这可能会绕过问题

编辑以下一些实验: (1) “内存损坏”似乎出现在数据后面包含空格的行上。在文本编辑器中删除该选项将消除该问题(重写行解析器以消除该问题可能是更好的答案…)

(2) 在解决了这个问题之后,精化阶段似乎处于停顿状态。 行
pgm.pixel(pi,pj)后的一些断言:=number显示它实际上正在运行;爬行或滑行可能是一个更好的术语。我还没有总结出让它超过100行的耐心,所以我不能说结果是否成功

      pgm.pixel(pi,pj) := number;
      assert pi < 10 report "Pixel " & natural'image(pi) & " : " & natural'image(pj) severity note;
作为强制文件解析延迟到运行时的一种方法;编译成功,模拟以令人满意的速度进行,直到:

ERROR: Index 640 out of bound 0 to 639. 
ERROR: In process test_raw_tb.vhd:17 

(此错误不会发生在固定空白文件中,因此似乎仍有解析器问题需要解决)

感谢您的回复!我试过阅读pgm图片:256x256、250x360、400x320。它们都加载了max=640。不幸的是,它们都没有起作用。我完全同意这个图书馆是一个残酷的玩笑,仅此而已。我曾尝试改用GHDL,但这在debian上不起作用,因为在项目中使用了过时的软件包。不,我建议减小软件包的大小(对其进行修改),直到它位于kb区域,并且必须适合堆栈。到一些非常小的文件,甚至是4*4,并且找到(或写!)一个小文件来匹配。如果这样做有效,我们可以继续前进。GHDL。。。更新。。。因为Debian是可用的,我将在今晚挖掘信息。我已将其中一个pgm文件修剪为4x4,并将包的max变量更改为4,但错误不断发生。我将非常感谢一个最新的GHDL,我找不到。我在lubuntu 12.10 GHDL中发现了一些有趣的东西-r test_raw_tb--stack max size=32M./test_raw_tb:error:open:cannot open text file pepper.ascii.pgm/usr/lib/GHDL/bin/GHDL:编译错误,没有pgm文件。在网络上找到一个小的(24 x 7),它运行。OSX下的mcode版本有问题。gcc-4.7.2。(布莱恩在英国)。谢谢大卫,那是我工作时记不起来的链接!没有回答您的实际问题,但这里有一些PGM阅读代码:谢谢,但这看起来仍在开发中,而且它看起来很像我现在使用的库。不幸的是,即使可以使用,这个库也不是我真正的选择。谢谢你!整个库仍在开发中(速度非常慢!),但PGM读写功能运行良好(如果您发现错误,我将尽全力立即修复!)如果有可能,我会尝试一下。谢谢
architecture behavioral of test_raw_tb is
    --constant infile : pgm_record_type := read_pgm_file(ifile);
begin   -- architecture

 process
 variable infile : pgm_record_type;
 begin
    infile := read_pgm_file(ifile);
     wait;
 end process;

end behavioral;
ERROR: Index 640 out of bound 0 to 639. 
ERROR: In process test_raw_tb.vhd:17