今天碰到一个问题,在网上查了一下,发现有人碰到。转一下

本文解决Linux内核2.6.18版本中exception_handler函数编译时出现的undefined reference to `memset'错误。通过修改makefile添加-lc选项,并采用手动逐个赋值替代memset函数初始化二维数组的方法,成功解决了编译问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

老于第五章P209的exception_handler函数在我的2.6.18的内核编译的时候会出现一个错误:undefined reference to `memset'
这是因为(推断一下应该是这个原因):其中的二维数组err_description[][64]的赋值造成的。在linux编译这段二维数组赋值的时候会调用到C库函数memset。而老于这章的makefile中用ld连接的时候并没有使用-lc选项,所以会有上面提到的错误。当修改makefile增加-lc选项的时候再使用make all,会发现出现一个新的警告:dot moved backwards before `.text'。至于这个是怎么回事以及怎么解决我就不清楚了,也懒得管了,因为我知道所有的这些都是二维数组的赋值方式造成的。所以我就不再采用二维数组的初始化方式赋值(避免库调用memset),而用先定义后赋值的方法(每个人都可以用自己喜欢的方式)。果然程序跑通了,结果和后面老于的例子一致。
PS:如果仍使用-lc选项而忽略由此带来的警告的话程序在虚拟机下运行时会出现错误并让你选择重启。

附上我自己的修改方法:


char *p,*q;//08-11-20----kkk修改
char err_description[20][64];

q=&err_description[0][0];
p="#DE Divide Error";
while((*p!=0))   *q++=*p++;
q=&err_description[1][0];
p="#DB RESERVED";
while((*p!=0))   *q++=*p++;
q=&err_description[2][0];
p="— NMI Interrupt";
while((*p!=0))   *q++=*p++;
q=&err_description[3][0];
p="#BP Breakpoint";
while((*p!=0))   *q++=*p++;
q=&err_description[4][0];
p="#OF Overflow";
while((*p!=0))   *q++=*p++;
q=&err_description[5][0];
p="#BR BOUND Range Exceeded";
while((*p!=0))   *q++=*p++;
q=&err_description[6][0];
p="#UD Invalid Opcode (Undefined Opcode)";
while((*p!=0))   *q++=*p++;
q=&err_description[7][0];
p="#NM Device Not Available (No Math Coprocessor)";
while((*p!=0))   *q++=*p++;
q=&err_description[8][0];
p="#DF Double Fault";
while((*p!=0))   *q++=*p++;
q=&err_description[9][0];
p="    Coprocessor Segment Overrun (reserved)";
while((*p!=0))   *q++=*p++;
q=&err_description[10][0];
p="#TS Invalid TSS";
while((*p!=0))   *q++=*p++;
q=&err_description[11][0];
p="#NP Segment Not Present";
while((*p!=0))   *q++=*p++;
q=&err_description[12][0];
q="#SS Stack-Segment Fault";
while((*p!=0))   *q++=*p++;
q=&err_description[13][0];
p="#GP General Protection";
while((*p!=0))   *q++=*p++;
q=&err_description[14][0];
p="#PF Page Fault";
while((*p!=0))   *q++=*p++;
q=&err_description[15][0];
p="— (Intel reserved. Do not use.)";
while((*p!=0))   *q++=*p++;
q=&err_description[16][0];
p="#MF x87 FPU Floating-Point Error (Math Fault)";
while((*p!=0))   *q++=*p++;
q=&err_description[17][0];
p="#AC Alignment Check";
while((*p!=0))   *q++=*p++;
q=&err_description[18][0];
p="#MC Machine Check";
while((*p!=0))   *q++=*p++;
q=&err_description[19][0];
p="#XF SIMD Floating-Point Exception";
while((*p!=0))   *q++=*p++;


/*
char err_description[][64] = { "#DE Divide Error",
      "#DB RESERVED",
      "— NMI Interrupt",
      "#BP Breakpoint",
      "#OF Overflow",
      "#BR BOUND Range Exceeded",
      "#UD Invalid Opcode (Undefined Opcode)",
      "#NM Device Not Available (No Math Coprocessor)",
      "#DF Double Fault",
      "    Coprocessor Segment Overrun (reserved)",
      "#TS Invalid TSS",
      "#NP Segment Not Present",
      "#SS Stack-Segment Fault",
      "#GP General Protection",
      "#PF Page Fault",
      "— (Intel reserved. Do not use.)",
      "#MF x87 FPU Floating-Point Error (Math Fault)",
      "#AC Alignment Check",
      "#MC Machine Check",
      "#XF SIMD Floating-Point Exception"
     };
*/

暂时还没想到不引发像C库函数memset的其他更好的方法。

根据引用中提到的问题,当你在使用C生成的静态库时,可能会遇到"undefined reference to"的错误。解决这个问题的方法可以有多种途径,下面我将为你介绍两种常见的解决方案。 第一种方法是确保你的代码正确链接了所需的静态库。你可以使用-l选项来告诉编译器链接特定的库。例如,如果你想链接名为"mylib"的静态库,你可以在编译命令中加入-lmylib。这样编译器就会去找名为libmylib.a的静态库文件并将其链接到你的代码中。请注意,静态库的名称通常以"lib"开头,后面跟着库的名称。所以在链接时使用-l选项时需要省略掉"lib"前缀。 第二种方法是检你的代码是否正确包含了所需的头文件。头文件包含了函数和变量的声明,但不包含其定义。如果你的代码中使用了未声明的函数或变量,编译器就会报告"undefined reference to"的错误。确保你正确地包含了头文件,并且头文件中包含了所需函数和变量的声明。 根据引用中提到的信息,你在使用gcc命令时,可以不加-lc选项来链接C库,因为默认情况下会自动链接C库。所以如果你编译的是C文件,你可以省略-lc选项。 综上所述,如果你遇到"more undefined references to"的错误,请按照以下步骤解决: 1. 确保你的代码正确链接了所需的静态库。使用-l选项来告诉编译器链接特定的库,例如-lmylib。 2. 检你的代码是否正确包含了所需的头文件。确保头文件中包含了所需函数和变量的声明。 请根据你的具体情况选择适用的解决方法,并对照上述步骤进行排和修正。希望这些解决方案能帮助你解决"more undefined references to"的问题。如果还有其他问题,请随时向我提问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值