2016-03-01 1 views
3

Я работаю с C/CPP для встроенных систем, а в своем коде у меня есть некоторые разделы, которые запускаются из некоторой «недопустимой» памяти и НЕ ДОЛЖЕН вызывать до тех пор, пока не будет выполнено какое-либо условие.Как обеспечить, чтобы конкретный код не выполнялся во время выполнения условия

для простоты:
Допустим, foo() такая функция и является недействительным, а g_isMemoryValid == false

для обув кроме() есть несколько houndred других функций в разделе недействительных памяти с несколькими вызовами каждый из всех модулей.

моя проблема заключается в том, чтобы найти все экземпляры, где я вхожу в недействительный раздел и проверять, что я пропустил любой звонок!

Как я могу гарантировать, что все отрасли, где foo() управляют являются отвечают g_isMemoryValid == true


решение должно выход:
линия, которая переходит на код (или адрес инструкции), , но даже если это будет испускают имя модуля только
Или ад ... [OK, NOT_OK] будет делать :)

Примечание: Даже решения, которые будут решать только подмножество в f сценарии будут делать!


Обратите внимание, что существует много сценариев, в дополнении к простому if(g_isMemoryValid) обертке, как СЦЕПЛЕНИЕ функции вызова в себе вызов не вызывается, а условие не выполняются или несколько отличается синтаксисом ветви

if (g_isMemoryValid) 
    foo(); // should pass 

if (!g_isMemoryValid) 
    return; 
foo(); // should pass too 
+0

Оберните их мьютексом, который разблокирован, когда 'g_isMemoryValid' станет истинным? – Shark

+0

У вас есть доступ к исходному коду 'foo()', чтобы вы могли самостоятельно изменить эту функцию? В качестве альтернативы, вы можете реализовать функцию-оболочку для 'foo()'? –

+4

'#define CHECKED_FOO() if (g_isMemoryValid == true) foo();' – LPs

ответ

2

Если вы не можете изменить способ foo называется, вы должны изменить саму Foo:

  • переименовать функцию foo к inner_foo
  • написать себе foo, что делает все проверки, печатает все сообщения, а там, где это все в порядке, называют себя inner_foo
  • перекомпилировать модуль, содержащий старый Foo и новый Foo и перелинковать все модули, где foo называется.

теперь все ветки будут называть ваши собственные новые функции foo.

+0

Это, безусловно, самый чистый и самый прямой способ сделать это. Для чего это стоит, так как пост помечен как «C++» тоже ... оболочка может «бросать», если память недействительна. –

3

Одно из решений, которые, на мой взгляд, по крайней мере, более элегантно, чем макрос будет использовать указатель на функцию:

#include <stdio.h> 

// The real foo() 
void foo() 
{ 
    puts("OK"); 
} 

// Handle 'invalid' memory (error message?) 
void mem_invalid() 
{ 
    puts("Not OK"); 
} 

typedef void (*foo_t)(); 

foo_t foo_ptr = &mem_invalid; 

void main(void) 
{ 
    // Memory is 'invalid', calls error routine 
    foo_ptr(); 
    ... 

    // Memory became good somehow 
    foo_ptr = &foo; 
    ... 

    // Call now succeeds 
    foo_ptr(); 
} 

Это использует указатель на функцию вместо флага.

В зависимости от вашей встроенной системы могут быть некоторые накладные расходы, связанные с вызовом косвенной функции, но если она не находится в критической области, такой как внутренний цикл, это не должно быть проблемой. Обработчик ошибок даже не нужно ничего делать - или это может быть так сложно, как вам нравится.

+0

Некоторые руководства по стилю кодирования, ориентированные на безопасность, на встроенных системах запрещают указатели на функции. – Olaf

+0

@Olaf, какой стиль кодирования вы имеете в виду? Правило 104 Misra C, которое с тех пор было отменено, используется, чтобы сказать: «Непостоянные указатели на функции не должны использоваться», но я понимаю, что это означало, что «указатели на функции не должны вычисляться во время выполнения». Риск заключается в ошибках при вычислении адреса, и это не произойдет здесь, потому что адрес известен во время компиляции и будет закодирован как литерал. В этом случае он не менее безопасен, чем прямой вызов. – Trevor

+0

Это не только из-за этого, но и потому, что указатель может быть поврежден доступом к данным. Я согласен, что такие правила сомнительны, но это не меняет того факта, что они существуют. Однако я не буду защищать их. – Olaf