Использование GDB для исправления ошибки двойного освобождения или повреждения (! Prev) в большом проекте

Вам нужно использовать SET в вашем обновленном запросе, вы, вероятно, просто пропустили его со всеми экстрактивными материалами VBA, которые вам нужно было добавить в запрос.

Мое предложение (в общем) - это запись как обычно, через Access, а затем изменить этот запрос для использования в VBA.

Например, сначала напишите этот запрос так (в Access SQL Editor для тестирования):

UPDATE [Tbl - HOP Loan Data]
SET [Tbl - HOP Loan Data].[Row ID] = 1
WHERE [Tbl - HOP Loan Data].[Row ID] < 1

В любом случае попробуйте это:

sql = "UPDATE [Tbl - HOP Loan Data] " & _
    "SET [Tbl - HOP Loan Data].[Row ID] = " & Row_Counter & _
    "WHERE [Tbl - HOP Loan Data].[Row ID] < " & Row_Counter & " ;"

ПРИМЕЧАНИЕ : оператор WHERE является скорее всего ненужным, в зависимости от вашей структуры таблицы .

1
задан puk 18 January 2019 в 18:56
поделиться

1 ответ

Есть ли лучший способ в gdb точно определить, где в коде возникает ошибка двойного освобождения или повреждения (! prev)?

Да: Valgrind и AddressSanitizer очень помогают найти основную причину ошибок повреждения кучи.

Похоже, Valgrind также только сообщает, что произошло двойное освобождение, но не там, где в вашем коде это возникает

. Это неверно . Valgrind (и AddressSanitizer) точно скажет вам, где проблема. Для двойного освобождения они сообщают вам, где первое освобождение произошло раньше, и где второе освобождение происходит сейчас (и где изначально был выделен блок).

Вот отчет sampe от sanitizer адреса для программы, которая показывает двойное освобождение:

#include <malloc.h>

int use_and_free(int *p)
{
  int result = *p;
  free(p);
}

int main(void)
{
  const int num_pointers = 2;
  int *p[num_pointers];

  for (int j = 0; j < num_pointers; j++) {
    p[j] = malloc(sizeof(int));
    *p[j] = j;
  }

  int sum = 0;
  for (int j = 0; j < num_pointers; j++) {
    sum += use_and_free(p[j]);
  }

  // Oops: double-free.
  free(p[0]);

  return sum;
}

gcc -g t.c -fsanitize=address && ./a.out

=================================================================
==132174==ERROR: AddressSanitizer: attempting double-free on 0x602000000010 in thread T0:
    #0 0x7fa305b698c8 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xd98c8)
    #1 0x5654448c1ba9 in main /tmp/t.c:25
    #2 0x7fa3057112b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #3 0x5654448c18a9 in _start (/tmp/a.out+0x8a9)

0x602000000010 is located 0 bytes inside of 4-byte region [0x602000000010,0x602000000014)
freed by thread T0 here:
    #0 0x7fa305b698c8 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xd98c8)
    #1 0x5654448c19e1 in use_and_free /tmp/t.c:6
    #2 0x5654448c1b6a in main /tmp/t.c:21
    #3 0x7fa3057112b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

previously allocated by thread T0 here:
    #0 0x7fa305b69c20 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xd9c20)
    #1 0x5654448c1a77 in main /tmp/t.c:15
    #2 0x7fa3057112b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

SUMMARY: AddressSanitizer: double-free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xd98c8) in __interceptor_free
==132174==ABORTING

Вы можете ясно видеть 1), где происходит ошибка 2), где проблемный блок был освобожден; и 3) где он был первоначально выделен.

Вот вывод Valgrind для той же программы:

==132339== Invalid free() / delete / delete[] / realloc()
==132339==    at 0x4C2CD57: free (vg_replace_malloc.c:530)
==132339==    by 0x1087B1: main (t.c:25)
==132339==  Address 0x51d7040 is 0 bytes inside a block of size 4 free'd
==132339==    at 0x4C2CD57: free (vg_replace_malloc.c:530)
==132339==    by 0x1086AA: use_and_free (t.c:6)
==132339==    by 0x108793: main (t.c:21)

Выше вы видите 1) и 2).

0
ответ дан Employed Russian 18 January 2019 в 18:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: