optymalizacja petli w dll zeby nie crashowala

1

Yo,
Walcze z malym problemem w mojej dll do gierki a mianowicie duza petla crashuje mi exe. Petla musi byc niestety tak dluga, gdyz jest mi to potrzebne do wyciagniecia wszystkich oczekiwanych wynikow. Gierka jest napisana w c++, ale ma tez wbudowane api z pythona ;) Gdy puszczalem ten sam kod ale przepisany na pythona, injectujac go wczesniej do gierki przy pomocy pierwszego lepszego pyloadera, nic nie crashowalo. Myslalem, zeby wrzucic akurat ta jedna funkcje na odzielny watek, ale byc moze ktos podzieli sie innymi pomyslami :)

for (int i = 1; i < 60000; i++) {
                PyObject* args = PyTuple_New(1);
                PyTuple_SetItem(args, 0, PyInt_FromLong(i));
                PyObject* mob = PyObject_CallObject(PyObject_GetAttrString(PyImport_AddModule("player"), "GetCharacterDistance"), args);
                if (PyInt_AsLong(mob) > 0 && PyInt_AsLong(mob) < 1000) {
                    std::cout << i << std::endl;
                }
                Py_DECREF(mob);
                Py_XDECREF(args);
            }
1
ledi12 napisał(a):

Yo,
Walcze z malym problemem w mojej dll do gierki a mianowicie duza petla crashuje mi exe. Petla musi byc niestety tak dluga, gdyz jest mi to potrzebne do wyciagniecia wszystkich oczekiwanych wynikow.

Ale skąd w ogóle wiesz, że to wielkość pętli wywołuje crash? I czy wielkość określasz przez liczbę iteracji? To nie powinno mieć znaczenia, dopóki obiekty są lokalne. I jakiego rodzaju jest to crash? Segmentation fault? Brak pamięci? W Twoim kodzie mam podejrzenia co do wskaźników args i mob. Widzę że dekrementujesz ich referencje, ale na 2 różne sposoby (XDECREF i DECREF). Czy ma to uzasadnienie?

Jeśli faktycznie wielkość pętli wywołuje crash (przy której iteracji?) możesz analizować zajęcie pamięci przez proces, choćby w systemowym resource monitorze. Jeśli z kolejną iteracją wzrasta, i nie jesteś w stanie wyjaśnić tego wzrostu, to masz pewnie wycieki.

0

Ustawialem do 10 iteracji na probe i przechodzilo. Crash polega na tym ze freezuje mi klienta gry na 2-3sec po czym klient sie zamyka.

3

Nigdy nie korzystałem z pythona w C++, ale twój opis wskazuje, że nadal nie umiesz dobrze i technicznie poprawnie opisać swojego problemu (być może wynika to z braków w podstawowych umiejętności).
Napisanie "crash" to nie jest dobry opis problemu.
Tak samo napisanie działa dla 10 iteracji nie działa dla 60000 też nie jest zbyt pomocne.

  1. Odtwórz crash uruchamiając aplikację w debugerze
  2. Jak crash wystąpi to podaj rodzaj crasha: niezłapany wyjątek? Dostęp do niewłaściwej pamięci? Przepełnienie stosu? ....
  3. Przeanalizuj call stack z-crash'owanego wątku i upewnij się, że dostarczyłeś kod związany z crash-em
  4. Wskaż nam dokładnie co ci pokazuje ten call stack, przez jakie linie przechodzi.
  5. Opisz co zawierają zmienne powiązane z crashem.

Inną techniką umożliwiającą ustalenie źródła problemu jest wykorzystanie address sanitizer z clang lub gcc (msvc ma też od niedawna to narzędzie w wersji eksperymentalnej).

0

0xC0000409 - STATUS_STACK_BUFFER_OVERRUN

Znalazlem juz nawet miejsce gdzie to wystepuje i sproboje to zmodyfikowac

2
  1. Robisz tu całą masę dziwnych rzeczy. Przecież te wszystkie PyObject_GetAttrString(PyImport_AddModule("player"), "GetCharacterDistance") czy tworzenie tupli z argumentami wywołania to są stałe. Możesz to zrobić raz a w pętli tylko wołać call.
  2. crash to mało precyzyjne pojęcie i trudno powiedziec co dokładnie się dzieje. Sprawdź konkretnie debuggerem CO crashuje.
0

Dobra dziala juz ;) Dzieki za rady - Kazda iteracja jest teraz sprawdzana i czyszczona.

PyObject* mod = PyObject_GetAttrString(PyImport_AddModule("player"), "GetCharacterDistance");
            PyObject* mod2 = PyObject_GetAttrString(PyImport_AddModule("chr"), "GetInstanceType");
            PyObject* args = PyTuple_New(1);
            std::vector<int> mobs;
            for (int i = 1; i < 100000; i++) {
                PyTuple_SetItem(args, 0, PyInt_FromLong(i));
                PyObject* mob = PyObject_CallObject(mod, args);
                if (!mob) {
                    Py_DECREF(mob);
                    Py_XDECREF(args);
                }
                else{
                    PyObject* enemy = PyObject_CallObject(mod2, args);
                    if (!enemy) {
                        Py_DECREF(enemy);
                        Py_XDECREF(args);
                    }
                    else {
                        if (PyInt_AsLong(mob) > 0 && PyInt_AsLong(mob) < 1000 && PyInt_AsLong(enemy) == 0) {
                            std::cout << i << std::endl;
                        }
                    }
                }
            }

1 użytkowników online, w tym zalogowanych: 0, gości: 1