home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / unix / programm / 4022 < prev    next >
Encoding:
Internet Message Format  |  1992-07-30  |  4.5 KB

  1. Path: sparky!uunet!cs.utexas.edu!ut-emx!tivoli!shasta!bjv
  2. From: bjv@shasta.tivoli.com (Brian Vetter)
  3. Newsgroups: comp.unix.programmer
  4. Subject: Re: I am stumped by this one!!!
  5. Message-ID: <2283@tivoli.UUCP>
  6. Date: 30 Jul 92 18:24:38 GMT
  7. References: <1992Jul24.204944.18516@cbfsb.cb.att.com> <Brx394.4qL@undergrad.math.waterloo.edu> <13744@auspex-gw.auspex.com> <1992Jul27.134826.5592@cbfsb.cb.att.com>
  8. Sender: news@tivoli.UUCP
  9. Distribution: usa
  10. Organization: TIVOLI Systems
  11. Lines: 117
  12.  
  13. In article <1992Jul27.134826.5592@cbfsb.cb.att.com>, rajeev@cbnewsf.cb.att.com (rajeev.dolas) writes:
  14. |> 
  15. |>     I realize the error on sizeof instead of strlen() for malloc. But
  16. |>     I don't think that is the cause of SEGV error. If you look at my
  17. |>     original posting, you will notice that I am able to copy selected
  18. |>     characters to cp_line.
  19. |> 
  20. |>     In my original code I wasn't even using the cp_line. I was reading
  21. |>     a char pointed to by *pbuf and was writing that to the file. I
  22. |>     got the SEGV error on the putc()!!! Now I am using fputs() to
  23. |>     write a string instead of a char and I get the same error on
  24. |>     fputs(). Also fputs(tmp_line,stdout) works fine while 
  25. |>     fputs(tmp_line,fp1) does not!!! That's what is driving me nuts.
  26.  
  27. It looks to me that you have several problems with your code.  First,
  28. the sizeof is a serious problem.  If you look at your code, you'll see that
  29. once you copy more than 4 bytes from the pbuf to cp_line, you will
  30. start overwriting the data you allocated for cp_line.  This can cause
  31. all kinds of unpredictable errors.
  32.  
  33. Secondly, after you complete your loop "while (*pbuf != '\0')", you
  34. never terminate the cp_line string with a NULL character.  fputs() would
  35. continue writing data after the end of your string (potentially many bytes).
  36.  
  37. The SEGV message you get is in the malloc code.  fputs() and all of the
  38. stdio functions that write using a FILE * may (and frequently do) call
  39. malloc to keep a buffer so that writes perform better.  In general, when
  40. you get SEGVs and BUSERRs in malloc, it is due to dynamically allocated
  41. buffers being overwritten.  malloc() keeps information about the allocation
  42. pool mixed in with your allocated data so it is easy to confuse.
  43.  
  44. The bug you are looking for may not even be in the code you have provided.
  45. Based on what I can see here, you must be fairly new to C or to some of the
  46. more common extensions.  I would suggest you get a debug version of malloc
  47. to link against your code or try a commercial product such as Purify.
  48. They can help you find such problems if you aren't familiar enough debugging
  49. dynamic memory bashing code.
  50.  
  51. As a critique of your code:
  52.  
  53. pars_wbuf[strlen(pars_wbuf)] = '\0'    Isn't needed - fgets already put the
  54.                     null byte at the end - otherwise the
  55.                     strlen would fail.
  56.  
  57. The sizeof is WRONG and your code WILL FAIL if you don't fix it.
  58.  
  59. It looks like the else clause just strips out the \r character (CR).
  60. Why do the malloc at all?  Why not just copy the data in place? ie:
  61.  
  62.     for (to=pars_wbuf, from=pars_wbuf; *from; from++) {
  63.         if (*from != '\r') {
  64.             *to++ = *from;
  65.         }
  66.     }
  67.     fputs(pars_wbuf, fp1);
  68.  
  69. This isn't even optimal since you don't need to do the assignments until
  70. you find the first CR.
  71.  
  72. |>     
  73. |>     I am including the relevant portion of the code to clarify my
  74. |>     point and not to drive the 2400 baud-ers nuts :-)
  75. |> 
  76. |>     /* str_comp is my function which returns -1 if match is not found */
  77. |>     while((fgets(pars_wbuf, 80, fp2) != NULL) &&
  78. |>         ((parse_ret = str_comp(cmp, pars_wbuf)) != 0))
  79. |>     {
  80. |>         pars_wbuf[strlen(pars_wbuf)] = '\0';
  81. |>         pbuf = pars_wbuf;
  82. |>         cp_line = (char *)malloc(sizeof(strlen(pars_wbuf)));
  83. |>         strcpy(cp_line, "\0");
  84. |>         tmp_line = cp_line;
  85. |> 
  86. |>         if((comp = line_comp(pars_wbuf)) == 0)
  87. |>             ;
  88. |>         else 
  89. |>         {
  90. |>             /* Traverse thru pbuf, skip "
  91. |>             while(*pbuf != '\0')
  92. |>             {
  93. |>                 if(*pbuf != 0x0D)
  94. |>                 {
  95. |>                     /* I was writing a char at a time to
  96. |>                        the file before. This part works
  97. |>                        on Amdahl but not on a sun.    */
  98. |> 
  99. |>                     /**
  100. |>                     ch = *pbuf;
  101. |>                     fprintf(stdout, "%c", ch); 
  102. |>                     if((he = putc(ch, fp1)) < 0)
  103. |>                     {
  104. |>                          printf("pars_conf: Write error\n");
  105. |>                         return(-13);
  106. |>                     }
  107. |>                     **/
  108. |> 
  109. |>                     /* Now I save it to a buffer */
  110. |>                     *cp_line++ = *pbuf;
  111. |>                 }
  112. |>                 *pbuf++;
  113. |>             }
  114. |>             /* If I do a fputs to stdout, it works fine */
  115. |>             /**
  116. |>             fputs(tmp_line, stdout);
  117. |>             fflush(stdout);
  118. |>             **/
  119. |> 
  120. |>             /* dbxtool shows the following error on this instr -
  121. |>              signal SEGV in malloc at 0xf773634
  122. |>              malloc+0x150:    st    %o0, [%15]
  123. |>              */
  124. |>             fputs(tmp_line, fp1);
  125. |>         }
  126. |>         free(cp_line);
  127. |>     }
  128. |>     
  129. |> }
  130.