User forums > Help

Malloc() / Heap issue with debug build target

<< < (2/3) > >>

Marnix:
Watch variables was enabled. I turned it off, but without success.

The crash reason is a SIGSEGV.

I F7-ed through the code and I narrowed it down to this for loop:


--- Code: ---    for (i=0; i<nr_of_lflags; i++) {
      if ( ((loc_flag_dbug[i]).name = ReadString()) == NULL)
        return(ERROR);

      if (!GetNextCode32(&(loc_flag_dbug[i]).owner))
        return(ERROR);
    }
--- End code ---

The ReadString() function (listed in the opening post) has a malloc() that crashes.

loc_flag_dbug is an array of structs wirh a char* and an int32_t, this array is malloced as well with length nr_of_lflags:



--- Code: ---    /* Malloc() space for local flags debug info. */
    if ((loc_flag_dbug = (debugInfo *) malloc(nr_of_lflags*sizeof(debugInfo))) == NULL) {
      PrintError(15, NULL, "local flags debug info");
      return(ERROR);
    }
--- End code ---

Strange thing is that the iteration of the loop when it crashes differs. This afternoon after I restarted my computer it did not crash at all. Now, after I saw your post I tried again and now it crashes again.

BlueHazzard:
So it crashes also if no watches are enables and the watch view is empty?

The debug log is not about the warnings, but about the difference between release and debug build, so you should post a build log of the release build and the debug build, so we can compare the compiler flags. But this is only for the future, or for other reader, i do not suspect that this is the problem here...

Have you checked if the len variable has a reasonable size?

--- Code: --- if (!GetNextCode32(&len)) {
    PrintError(14, NULL, "ReadString()");
    return(NULL);
  }

  /* create space on heap */
  if ((str = (char *) malloc(len*sizeof(char))) == NULL) {
--- End code ---

using uninitialized variables is never the best idea, and no range checking for a malloc input also not....

Marnix:
Regarding the watch view, I have disabled it but I cannot delete the function arguments and local variables from it.

Before I continue, I'm not sure any more if this is a CB issue, so if any of the mods decide to close this thread, I'll regret it but the forum rules are clear.

I did some more testing and I see unpredictable behavior:

- if I declare one additional local variable in the function that calls the failing ReadString() it works.
- but if, additionaly to the extra declaration, I initialize the nr_of_lflags var it crashes again.

Below is the function code, see the 3 COMMENTS IN CAPS.



--- Code: ---int32_t ReadFlags(int64_t offset)
{
  int32_t code        = NO_ID;
  int32_t com_loc_len = 0; /* Length of common location flags string.                                */
  int32_t com_obj_len = 0; /* Length of common object flags string.                                  */
                           /* Length of local flags string is a global variable for save() function. */

  int32_t nr_of_lflags;  /* IF I INITIALIZE THIS VAR THE EXTRA LOCAL DECLARATION HAS NO EFFECT */
  int i  = 0;

  int test = 0;  /* WITH THIS LINE IT WORKS, IF I REMOVE IT, OR INTIALIZE nr_of_lflags THE PROBLEM RETURNS */

  /* go to offset in datafile */
  if (fseek(datafile, offset, 0) == -1) {
    PrintError(16, NULL, "ReadFlags()");
    return(ERROR);
  }

  /* check for the keyword */
  if (!GetNextCode32(&code)) {
    PrintError(23, NULL, "keyword record");
    return(ERROR);
  }
  if (code != FLAGS) {
    PrintError(21, NULL, "flags");
    return(ERROR);
  }
  /* Read number of common flagbits.                  */
  /* We need the number for the SetBitVal() function. */
  if (!GetNextCode32(&nr_of_cflags)) {
    PrintError(23, NULL, "nr_of_cflags");
    return(ERROR);
  }

  /* calculate com_loc_len and com_obj_len. */
  com_loc_len = ((nr_of_cflags*nr_of_locs)/WORD_LEN)+1;
  com_obj_len = ((nr_of_cflags*nr_of_objs)/WORD_LEN)+1;

  /* Create space on heap for com_loc_flags. */
  if ((com_loc_flags = (int32_t *) malloc(com_loc_len*sizeof(int32_t))) == NULL) {
    PrintError(15, NULL, "ReadFlags()");
    return(ERROR);
  }

  /* Create space on heap for com_obj_flags. */
  if ((com_obj_flags = (int32_t *) malloc(com_obj_len*sizeof(int32_t))) == NULL) {
    PrintError(15, NULL, "ReadFlags()");
    return(ERROR);
  }

  /* Read the com_loc_flags. */
  if (fread((void *) com_loc_flags, sizeof(int32_t), com_loc_len, datafile)
      != com_loc_len) {
    PrintError(23, NULL, "common location flags");
    return(ERROR);
  }

  /* Read the com_obj_flags. */
  if (fread((void *) com_obj_flags, sizeof(int32_t), com_obj_len, datafile)
      != com_obj_len) {
    PrintError(23, NULL, "common object flags");
    return(ERROR);
  }

  /* Read length of local flagbits string.           */
  /* We don't need the actual number of local flags. */
  if (!GetNextCode32(&loc_flags_string_len)) {
    PrintError(23, NULL, "loc_flags_string_len");
    return(ERROR);
  }

  /* Create space on heap.             */
  if ((local_flags = (int32_t *) malloc(loc_flags_string_len*sizeof(int32_t))) == NULL) {
    PrintError(15, NULL, "ReadFlags()");
    return(ERROR);
  }

  /* read the information */
  if (fread((void *) local_flags, sizeof(int32_t), loc_flags_string_len, datafile)
      != loc_flags_string_len) {
    PrintError(23, NULL, "local flags");
    return(ERROR);
  }

  /* Check if we must read debug info */  /* @@ */
  if (debug) {
    /* check for the keyword */
    if (!GetNextCode32(&code)) {
      PrintError(23, NULL, "keyword record");
      return(ERROR);
    }
    if (code != DEBUG) {
      PrintError(21, NULL, "debug");
      return(ERROR);
    }

    /* Malloc() space for common flags debug info. */
    if ((com_flag_dbug = (debugInfo *) malloc(nr_of_cflags*sizeof(debugInfo))) == NULL) {
      PrintError(15, NULL, "common flags debug info");
      return(ERROR);
    }

    /* Malloc() space for local flags debug info. */
    if ((loc_flag_dbug = (debugInfo *) malloc(nr_of_lflags*sizeof(debugInfo))) == NULL) {
      PrintError(15, NULL, "local flags debug info");
      return(ERROR);
    }

    for (i=0; i<nr_of_cflags; i++) {
      if ( ((com_flag_dbug[i]).name = ReadString()) == NULL)
        return(ERROR);
    }
    /* read the number of local flags */
    /* is is only needed when we have debug info */
    if (!GetNextCode32(&nr_of_lflags)) {
      PrintError(23, NULL, "nr_of_lflags");
      return(ERROR);
    }
    for (i=0; i<nr_of_lflags; i++) {
      if ( ((loc_flag_dbug[i]).name = ReadString()) == NULL)    /* THIS rEADsTRING() CALL FAILS */
        return(ERROR);
      if (!GetNextCode32(&(loc_flag_dbug[i]).owner))
        return(ERROR);
    }
  }

  return(OK);
}
--- End code ---

oBFusCATed:

--- Quote from: stahta01 on April 22, 2019, 05:57:28 pm ---You are going to have to wait for an CB Debugging person. They will likely ask for a full debugging log.

--- End quote ---
If you want to get help you have to accomplish this.
Full log is enabled in Settings -> Debugger -> General -> Full (debug) log.
Then copy-paste the contents of the debugger tab in the log and others.

Krice:
That's an indication of memory corruption. It's quite easy to do with C using malloc etc. It just hides problems so easily. And the best part is that the actual problem may not even be in that part of the code.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version