免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3496 | 回复: 5
打印 上一主题 下一主题

请教segmentation fault [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-10-04 09:52 |只看该作者 |倒序浏览
Centos 5.5 X64

如果 MAXDIRLOGSIZE 大于 1499999 就执行 segmentation fault ,同样的在 freebsd 下就ok。

请问修改centos那个参数 可以避免 segmentation fault ,谢谢

代码:
  1. int replace_dirlog = 0;      /* change this to 1 if you want to replace
  2.                                 the old dirlog with the new one by default   */
  3. int delete_orig_dirlog = 0;  /* set this to 1 if you don't want a backup
  4.                                 of the original dirlog                       */

  5. #define MAXDIRLOGSIZE 10000

  6. #include <sys/param.h>
  7. #include <sys/stat.h>
  8. #include <sys/types.h>

  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <unistd.h>
  14. #include "glconf.h"

  15. char datapath[255] = "/ftp-data";        /* assign default datapath, will use value from conf if defined there */
  16. char rootpath[255] = "/glftpd";                /* assign default rootpath, will use value from conf if defined there */
  17. char config_file[MAXPATHLEN];

  18. void trim(char *str) {
  19.     char *ibuf, *obuf;

  20.     if (str) {
  21.         for (ibuf = obuf = str; *ibuf;) {
  22.             while (*ibuf && (isspace(*ibuf)))
  23.                 ibuf++;
  24.             if (*ibuf && (obuf != str))
  25.                 *(obuf++) = ' ';
  26.             while (*ibuf && (!isspace(*ibuf)))
  27.                 *(obuf++) = *(ibuf++);
  28.         }
  29.         *obuf = '\0';
  30.     }
  31.     return;
  32. }

  33. void load_sysconfig(void) {
  34.     FILE *configfile;
  35.     char lvalue[64], rvalue[MAXPATHLEN], work_buff[MAXPATHLEN];
  36.     int  x, y;

  37.     if ((configfile = fopen(config_file, "r")) == NULL) {
  38.         fprintf(stderr, "Unable to open config file %s, using defaults.\n", config_file);
  39.         return;
  40.     }

  41.     while (fgets(work_buff, sizeof(work_buff), configfile) != NULL) {
  42.       for (x = 0; x < (int)strlen(work_buff); x++)  /* Clip out comments */
  43.          if (work_buff[x] == '#')
  44.             work_buff[x] = '\0';

  45.       trim(work_buff);
  46.       memset(lvalue, '\0', sizeof(lvalue));
  47.       memset(rvalue, '\0', sizeof(rvalue));

  48.       y = 0;
  49.       for (x = 0; x < (int)strlen(work_buff) && work_buff[x] != ' '; x++)
  50.          if (isprint(work_buff[x]))
  51.             lvalue[y++] = work_buff[x];

  52.       y = 0; x++;
  53.       for (; x < (int)strlen(work_buff); x++)
  54.          if (isprint(work_buff[x]))
  55.             rvalue[y++] = work_buff[x];

  56.       if (strcasecmp(lvalue, "datapath") == 0)
  57.                 strncpy( datapath, rvalue, sizeof(datapath));
  58.       if (strcasecmp(lvalue, "rootpath") == 0)
  59.                 strncpy( rootpath, rvalue, sizeof(rootpath));
  60.     }

  61.     fclose(configfile);
  62.     return;
  63. }
  64. void show_help(char *argv) {
  65.         printf("\nThis util removes non-existent directories from your dirlog and\n");
  66.         printf(" sorts it so that newest directories show up first in \"site new\".\n");
  67.         printf("\nUsage: %s [options]\n",argv);
  68.         printf("Options:\n");
  69.         printf("         -r path   Specify alternate path to config file\n");
  70.         printf("         -P        Force replacing of dirlog\n");
  71.         printf("         -p        Force not replacing of dirlog [default]\n");
  72.         printf("         -D        Force deleting of old dirlog\n");
  73.         printf("         -d        Force keeping of old dirlog [default]\n");
  74.         printf("\n");
  75.         exit(0);
  76. }

  77. int main(int argc, char *argv[]) {
  78.   FILE *file, *file2;
  79.   uid_t oldid = geteuid();
  80.   char dirlogpath[MAXPATHLEN], newdirlog[MAXPATHLEN], testdir[MAXPATHLEN+8];
  81.   struct dirlog direntry, *dirptr, *dirlist[MAXDIRLOGSIZE];
  82.   struct stat st;
  83.   int curr=0, curr2, ArgCounter;

  84.   strcpy(config_file, GLCONF);

  85.   printf("Olddirclean for glftpd, v2.2 by Usurper, November 2000\n");
  86.   printf("Use option -h (%s -h) for syntax help.\n", argv[0]);

  87.   ArgCounter = 1;
  88.   while (argc > ArgCounter) {
  89.         if (argv[ArgCounter][0] != '-') {
  90.           printf("Unknown option, skipping [%s]\n",argv[ArgCounter]);
  91.         } else {
  92.           switch (argv[ArgCounter][1]) {
  93.                 case 'r':
  94.                     if (argv[ArgCounter][2])
  95.                       strcpy(config_file, argv[ArgCounter]+2);
  96.                     else if (argv[ArgCounter+1])
  97.                       strcpy(config_file, argv[++ArgCounter]);
  98.                     else
  99.                       printf("No argument to the r option\n");
  100.                     break;
  101.                 case 'P':
  102.                     replace_dirlog = 1;
  103.                     break;
  104.                 case 'p':
  105.                     replace_dirlog = 0;
  106.                     break;
  107.                 case 'D':
  108.                     delete_orig_dirlog = 1;
  109.                     break;
  110.                 case 'd':
  111.                     delete_orig_dirlog = 0;
  112.                     break;
  113.                 case 'h':
  114.                 case '?':
  115.                     show_help(argv[0]);
  116.                     break;
  117.                 default:
  118.                     printf("Unknown option, skipping [%s]",argv[ArgCounter]);
  119.             } /* switch */
  120.         } /* else */
  121.         ArgCounter++;
  122.   } /* while */

  123.   load_sysconfig();
  124.   sprintf(dirlogpath,"%s%s/logs/dirlog", rootpath, datapath);
  125.   printf("\nReading %s\n", dirlogpath);

  126.   seteuid(0);
  127.   if ((file = fopen(dirlogpath, "r+b")) == NULL) {
  128.     fprintf(stderr, "Unable to open dirlog\n");
  129.     return 0;
  130.   }
  131.   snprintf(newdirlog, sizeof(newdirlog), "%s2", dirlogpath);
  132.   if((file2 = fopen(newdirlog, "w+b")) == NULL) {
  133.     fprintf(stderr, "Unable to create dirlog2\n");
  134.     return 0;
  135.   }
  136.   while(!feof(file)) {
  137.      if (fread(&direntry, sizeof(struct dirlog), 1, file) < 1)
  138.        break;
  139.      snprintf(testdir, sizeof(testdir),"%s%s", rootpath, direntry.dirname);
  140.      if (stat(testdir, &st) != 0)
  141.        printf("Removing %s\n",direntry.dirname);
  142.      else {
  143.     /*  fwrite(&direntry, sizeof(struct dirlog), 1, file2);  */
  144.         dirlist[curr] = (struct dirlog *)malloc(sizeof (struct dirlog));
  145.         *dirlist[curr++] = direntry;
  146.         if (curr >= MAXDIRLOGSIZE) {
  147.           printf("Too many records in dirlog - recompile %s with MAXDIRLOGSIZE set to a greater value!\n", argv[0]);
  148.           exit(1);
  149.         }
  150.      }
  151.   }
  152.   fclose(file);
  153.   printf("\nSorting dirlog");
  154.   for (curr=0; dirlist[curr] != NULL; curr++) {
  155.     for (curr2=curr+1; dirlist[curr2] != NULL; curr2++) {
  156.       if (dirlist[curr]->uptime > dirlist[curr2]->uptime) {
  157.         dirptr = dirlist[curr];
  158.         dirlist[curr] = dirlist[curr2];
  159.         dirlist[curr2] = dirptr;
  160.       }
  161.     }
  162.     printf(".");
  163.   }
  164.   printf("\n\nWriting new dirlog...\n");
  165.   for (curr=0; dirlist[curr] != NULL; curr++)
  166.     fwrite(dirlist[curr], sizeof(struct dirlog), 1, file2);
  167.   fclose(file2);
  168.   if (replace_dirlog) {
  169.     /* using testdir as a temporary buffer */
  170.     snprintf(testdir, sizeof(testdir), "%stmp", dirlogpath);
  171.     if (rename(dirlogpath, testdir) != 0) {
  172.       fprintf(stderr, "Unable to rename %s!\n", dirlogpath);
  173.       return 0;
  174.     }
  175.     if (rename(newdirlog, dirlogpath) != 0) {
  176.       fprintf(stderr, "Unable to rename %s!\n", newdirlog);
  177.       return 0;
  178.     }
  179.     if (rename(testdir, newdirlog) != 0) {
  180.       fprintf(stderr, "Unable to rename %s!\n", testdir);
  181.       return 0;
  182.     }
  183.     printf("Dirlog replaced.\n");
  184.     if (delete_orig_dirlog) {
  185.       if (unlink(newdirlog) != 0)
  186.         fprintf(stderr, "Unable to delete %s\n", newdirlog);
  187.       else
  188.         printf("%s deleted.\n",newdirlog);
  189.     }
  190.   } else
  191.     printf("Done. Rename %s to %s for changes to take effect.\n",newdirlog,dirlogpath);
  192.   setuid(oldid);
  193.   return 0;
  194. }
复制代码

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2010-10-04 12:40 |只看该作者
栈溢出了,那个大数组改用动态申请

论坛徽章:
0
3 [报告]
发表于 2010-10-05 09:55 |只看该作者
怎么修改呢?

论坛徽章:
0
4 [报告]
发表于 2010-10-05 10:29 |只看该作者
回复 3# slowhand


    malloc

论坛徽章:
0
5 [报告]
发表于 2010-10-06 11:12 |只看该作者
Segmentation fault 是不应该避免的,接收到这个信号表明程序存在严重的错误,比如越界或者方式不正确的内存访问。

从第 96 行可以找到一处定义:

struct dirlog direntry, *dirptr, *dirlist[MAXDIRLOGSIZE];

显然,这个 dirlist 是定义在函数内部的,通常是把该对象放到栈上。进程的栈空间极其宝贵,这样做的后果当然是栈溢出。最省事的 workaround 是把它改变为“全局”对象。

但是,请注意,我坚持认为你这样继续试图分配很大的数组是不正确的,你的程序突然需要大量的空间就一定存在着设计上的不足,也许代码应该重写。

论坛徽章:
0
6 [报告]
发表于 2010-10-10 12:39 |只看该作者
谢谢,各位的解答
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP