2015-03-19 6 views
8

Próbuję użyć programu MATLAB Coder do konwersji kodu z Matlab na plik MEX. Jeśli mam fragment kodu z następującą postać:Jak zidentyfikować miejsca w MATLAB, gdzie dane są przechowywane poza granicami tablicy?

x = zeros(a,1) 
x(a+1) = 1 

następnie w Matlab będzie to rozmiar tablicy, aby pomieścić nowy element, natomiast w MEX plik ten będzie stanowił „indeksu przekracza wymiary matrycy” błąd. Oczekuję, że w kodzie jest wiele miejsc, w których to się dzieje.

Co chcę zrobić, to uruchomić wersję kodu MATLAB (bez korzystania z kodera), ale mam MATLAB generuje błąd lub ostrzeżenie, gdy zmienia rozmiar tablicy, ponieważ przypisać do czegoś poza granicami. (Mógłbym po prostu użyć pliku MEX i zobaczyć, gdzie pojawiają się błędy, ale to wymaga przebudowania całego pliku MEX przy użyciu kodera MATLAB za każdym razem, gdy zmieniam kod w ogóle, co zajmuje chwilę.)

Czy istnieje sposób to zrobić? Czy istnieje jakieś ustawienie w MATLAB, które wyłączy "automatyczną zmianę rozmiaru, jeśli przypiszesz indeksowi poza zasięgiem", lub może ostrzeżenie, jeśli tak się stanie?

+0

Interesujące pytanie. "_Automatyczna zmiana rozmiaru, jeśli przypiszesz indeksowi poza polem_", jest podstawową cechą Matlaba. Przechwytywanie tego zachowania wydaje się być trudne. –

+0

Czy jesteś zainteresowany tylko zadaniami _jedno-wymiarowymi, _jedno-indeksowymi? To znaczy, czy twój kod może zawierać coś w rodzaju 'x = zera (a, 1) x (a + 1: a + 10) = 1;'? Lub 'x = zera (a, b) x (a + 1, b) = 1;'? –

+0

Prawie chcę powiedzieć nie, aby to było możliwe tylko dlatego, że czuję, że niektóre z podstawowych narzędzi Matlaba polegają na tej funkcjonalności ... –

Odpowiedz

2

EDIT:As of Matlab 2015b, Coder ma teraz błąd wykonania kontroli jako opcja (od release notes Matlab):

W R2015b, generowane jednostkowe biblioteki i pliki wykonywalne mogą wykrywać błędy i Runtime taki raport jako indeksowanie tablic out-of-bounds. W poprzednich wersjach tylko wygenerowane przez MEX wykryte i zgłoszone błędy w czasie wykonywania: .

Domyślnie wykrywanie błędów uruchamiania jest włączone dla MEX. Domyślnie wykrywanie błędów podczas wykonywania jest wyłączone dla autonomicznych bibliotek i plików wykonywalnych.

Aby umożliwić wykrywanie błędów w czasie wykonywania samodzielnych dla bibliotek i plików wykonywalnych:

W wierszu poleceń, należy użyć właściwości konfiguracji kod RuntimeChecks.

cfg = coder.config ('lib'); % lub 'dll' lub 'exe'

cfg.RuntimeChecks = true;

Codegen -config cfg myfunction

Korzystanie z aplikacji MATLAB Coder, w ustawieniach Build Project, na karcie debugowania, wybierz sprawdzić Generowanie sprawdza błąd czasu pudełko.

Wygenerowane biblioteki i pliki wykonywalne używają fprintf do pisania komunikatów o błędach do stderr i przerywania w celu zakończenia aplikacji. Jeśli nie są dostępne fprintf i abort , musisz je podać. Komunikaty o błędzie są w języku angielskim.

Zobacz Run-Time Error Detection and Reporting in Standalone C/C++ Code i Generate Standalone Code That Detects and Reports Run-Time Errors.

odpowiedź oryginalny: odpowiedź w komentarzach dotyczących deklarowania klasy podklasy z podwójnym którym sposób subsref jest przeciążony zabronić uprawy byłyby Dobrym sposobem, aby to zrobić.

Innym prostym sposobem na to jest posypywanie poleceń assert w całym kodzie (w każdej iteracji pętli lub na dole funkcji), aby potwierdzić, że rozmiar nie zwiększył się nad przydzielonym rozmiarem.

Na przykład, jeśli miał kod w formacie:

x = zeros(a,1) 
x(a+1) = 1 
... lots of other operations 

if coder.target('MATLAB') 
    assert(isequal(size(x), [a,1]), 'x has been indexed out of bounds') 
end 

byłoby to niech masz twierdzenie powiedzie się, jeśli jakakolwiek wartość przypisano że rozszerzył wachlarz.

Aby uczynić to nieco bardziej uporządkowanym, możesz nawet utworzyć funkcję, która obejmie zaznaczone wszystkie zmienne, które Cię interesują, ponownie owijając instrukcję coder.target. Potem możesz posypać to całym kodem.

To nie jest tak eleganckie jak przeciążenie podwójnej klasy, ale z drugiej strony nie dodaje żadnego dodatkowego obciążenia do skompilowanego kodu. Nie spowoduje to również błędów dokładnie w momencie przekroczenia limitu, ale da pewność, że kod działa dobrze w różnych sytuacjach.

Innym sposobem na zwiększenie pewności zleceń jest samodzielne sprawdzenie przypisania zlecenia w sytuacjach, w których może to być właściwe. Typowy problem, który widziałem w zadaniu, ma coś takiego. Mamy przydzieloną tablicę i kopiujemy dane z innej tablicy z przypisaniem wektora. Na przykład, należy rozważyć następującą sytuację:

t = char(zeros(5,7));    % Allocate a 5 by 7 char array 
tempstring = 'hello to anyone'; % Here's a string we want to put into it. 
t(1, 1:numel(tempstring)) = tempstring; % A valid assignment in MATLAB 

>> size(t) 
ans = 
5 15 

Uh oh, co dokładnie jesteś zaniepokojony w pytaniu działo się: tablica t została automatycznie zmieniany podczas cesji, która działa w MATLAB-ie, ale w Coder utworzony kod spowoduje błąd segfault lub MEX. Alternatywą jest użycie siły funkcji end zachować zadanie schludny Jeśli mamy zmienić przypisanie do (ale obcięty.):

t(1,1:min(end,numel(tempstring))) = tempstring(1:size(t, 2)); 

Wielkość t pozostanie niezmieniona, ale przypisanie zostanie obcięty. Korzystanie z end umożliwia sprawdzanie granic podczas przypisywania. W niektórych sytuacjach może to być dobry sposób na rozwiązanie tego problemu i da pewność, że granice nigdy nie zostaną przekroczone, ale oczywiście w niektórych sytuacjach jest to bardzo niepożądane (i nie spowoduje wyświetlenie komunikatów o błędach w MATLAB.)

Innym przydatnym narzędziem, które MATLAB zapewnia, jest sam edytor. Jeśli użyjesz znacznika %#codegen w swoim kodzie, to zasygnalizuje to narzędzie do sprawdzania składni edytora, aby podkreślić różne problemy z generowaniem kodu, w tym miejsca, w których oczywiście zwiększasz rozmiar tablicy przez indeksowanie. Nie może to złapać każdej sytuacji, ale jest to dobra pomoc.

Editor example with codegen

ostatnia uwaga. Jak wspomniano w pytaniu, plik MEX wygenerowany przez program Coder da ci błąd "Indeks przekracza wymiary matrycy" w momencie przypisania i z gracją wyjdzie, a nawet powie ci pierwotny wiersz kodu, w którym wystąpił błąd. Biblioteka C wygenerowana z kodera nie ma takiego miłego zachowania lub sprawdzania granic i całkowicie się odłączy bez żadnej diagnostyki.Odpowiedź pośrednia polega na wykonaniu dokładnie tego, co robisz, czyli na uruchomieniu kodu jako MEX. To nie jest pomocne dla twojego pytania (jak mówisz, przebudowa MEX-a może zająć trochę czasu), ale dla tych z nas, którzy kodują zimny, okrutny świat zewnętrznego kodu C, pośredni test na to, by móc uruchomić MEX, aby znaleźć te błędy to ratownik.

Najważniejsze jest to, że jest to rozbieżność między kodowaniem MATLAB i Coder generowanym przez kod C, co może być źródłem znaczących problemów. W moim własnym kodzie, jestem bardzo ostrożny z dostępem do tablicy i wzrostem właśnie z tego powodu. To obszar, w którym chciałbym zobaczyć ulepszenie samego narzędzia Coder, ale są sposoby, aby być bardzo ostrożnym przy pisaniu kodu MATLAB skierowanego do Coder'a.

Powiązane problemy