[personal profile] dememax
Имеется код примера:
void function(int * array, int index)
{
    array[index] = 23;
}

int main(void)
{
    int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    function(array, 75);
    return 0;
}
Вопрос: как штатными средствами выявить выход за пределы массива в функции примера? (штатными: т.е., взял и поставил недостающий пакет в систему; компилятор, линкер, valgrind, ...)
Условие: изменить пример - не предлагать.
Что имею:
  • Gentoo Linux x86_64
  • gcc 9.3.0
  • GNU ld.bfd 2.33.1
  • clang 9.0.1
  • Valgrind-3.15.0
Что пробовал:
  • gcc with sanitize address and undefined
  • clang with sanitize address, undefined, memory
  • valgrind with memcheck and exp-sgcheck
  • одну динамическую тулзу, которая мне нашла выход за пределы, но...
Что я знаю: Да, я знаю, что valgrind здесь бессилен, о чём они пишут у себя в часто задаваемых вопросах, а недавно они выпустили свежую версию, из которой выкинули вообще exp-sgcheck со следующим объяснением:
* exp-sgcheck:
  - The exprimental Stack and Global Array Checking tool has been removed.
It only ever worked on x86 and amd64, and even on those it had a high false positive rate and was slow. An alternative for detecting stack and global array overruns is using the AddressSanitizer (ASAN) facility of the GCC and Clang compilers, which require you to rebuild your code with -fsanitize=address.
Какие будут предложения?

Date: 2020-06-01 01:57 pm (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi
Сменить язык программирования.
vak: (Default)
From: [personal profile] vak
Если нет желания или возможности менять исходный код - тогда выискивать и покрывать все такие случаи тестами.
vit_r: default (Default)
From: [personal profile] vit_r
Нормальные стандарты требуют не тестов (которые даже теоретически всё покрыть не могут), а assert и проверку входных параметров. Ну и, да, там много чего ещё.

А так, подобное видел только в коммерческих тулах, которые вставляют такие проверки в режиме отладки.

Date: 2020-06-01 08:31 pm (UTC)
vak: (Default)
From: [personal profile] vak
Нормальные стандарты и code review требуют. Такой код не прошёл бы code review.

Date: 2020-06-02 06:48 am (UTC)
vak: (Default)
From: [personal profile] vak
Да я тоже на своём горбу аналогичные штуки проезжаю. тут проблема чисто языка Си. Да, дополнительные тулы помогают. Язык Си++ частично исправляет проблему ценой перехода на std::array<> и прочие навороченные типы вместо сишных. Но по большому счёту помогает только переход на более современные языки типа Go или Rust.

Date: 2020-06-03 03:36 pm (UTC)
fatoff: What? (Default)
From: [personal profile] fatoff
sizeof(array) / sizeof(array[0]) даёт тебе размер массива. Compile time only. Но с макро ты можешь всегда отправлять в функцию реальный размер массива.

void func(int * array, int arr_size, int index); // you know what to do here

#define HANDLE_ARR(array) func(array, sizeof(array) / sizeof(array[0]), index)

вызов "штатного средства"

HANDLE_ARR(myArr, wrongIndex);
Edited Date: 2020-06-03 03:38 pm (UTC)
fatoff: What? (Default)
From: [personal profile] fatoff
Средства штатные. Не менять код с ними, чтобы достичь результата, не есть возможно.

Date: 2020-06-14 01:03 pm (UTC)
From: (Anonymous)

$ g++ -std=c++17 -O3 -fsanitize=address -Warray-bounds -o t main.cpp
main.cpp: In function ‘int main()’:
main.cpp:2:18: warning: array subscript 42 is outside array bounds of ‘int [10]’ [-Warray-bounds]
2 | array[index] = 23;
| ~~~~~~~~~~~~~^~~~
main.cpp:6:9: note: while referencing ‘array’
6 | int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
| ^~~~~


g++ 9.30.

Profile

dememax

May 2023

S M T W T F S
 123456
78910111213
14151617181920
21 2223 24252627
28293031   

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 12th, 2026 12:47 am
Powered by Dreamwidth Studios