[solved] OS łapie nieznany błąd podczas uruchamiania apki...

0

...czyli taki po którym chce wysłać raport do M$. Z tym, że apka na moim sprzęcie działa jak powinna, a na każdej innej maszynie dzieje się to co napisałem zdanie wcześniej. Mam na myśli release build oczywiście. Do tej pory jakoś radziłem sobie z reliskami, pierwszy raz na oczy widzę takie coś. Kod kompilowałem VS i QtCreatorem (mingw) i efekt taki sam, u mnie działa a gdzie indziej lipa. Mogę jeszcze napisać że apka startuje prawidłowo (wyświetla się okno potwierdzenia warunków licencji zawartej w dllce), ale po potwierdzeniu warunków licencji crash.
Ktoś spotkał się z takim czymś?

(edit literówki)

0

A co ma się wyświetlić po potwierdzeniu warunków ?
Ustawienia, główna forma...rejestracja ?

1

Znając życie gdzieś Ci inicjalizacji zmiennej brakuje, ma ona wartość osobliwą, zależną od wersji systemu, bibliotek i fazy księżyca. U Ciebie działa 'poprawnie', gdzie indziej się sypie. Weź debugger (chociażby WinDBG) i sprawdź, gdzie się sypie na innej maszynie. Równie dobrze może chodzić o coś z plikami/rejestrem/uprawnieniami - Process Monitor powinien pokazać trochę przydatnych rzeczy.

0

Masz usłyszeć w głośnikach zsyntezowane zdanie. Zacząłem właśnie robić końcowe testy "silnika" mojego syntezera mowy przed rozpoczęciem prac nad GUI.

edit
@deus: Gdyby chodziło o nie zainicjalizowane zmienne to reliska na moim kompie powinna zachowywać się inaczej niż debug build, albo jakieś błędy wyrzucić. A ja mam tak że i debug i release build zachowują się tak samo, niezależnie jakie zdanie wrzucę do syntezy. Dzięki za wskazanie narzędzi, do tej pory nie potrzebowałem tego typu rzeczy.

0

Kompilacja debug teoretycznie powinna i takie rzeczy wychwycić, ale nie zawsze się to udaje - nie ma narzędzi idealnych. Jak będziesz miał razem z binarką (nawet release) plik PDB to wspomniany WinDBG powie Ci, gdzie leci wyjątek, pokaże symbole z callstacka itd. Żeby źródła złapał to muszą być bodaj w tej samej lokalizacji co pierwotnie.

...gorzej jak pod WinDBG się sypać NIE będzie, natomiast bez niego już tak. Zawsze pozostaje opcja ustawienia WinDBG jako runtime debugger, w momencie wyłożenia się aplikacji będzie można mu przekazać kontrolę i podejrzeć co się święci.

0

Zaraz po załadowaniu binarki WnDBG wyrzuca mi takie cuś:

ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll

Potem dostaję jeszcze dwa errory ale podejrzewam że są spowodowane przez ten pierwszy, ten err to błąd binarki czy WinDBG ?

0

Nie masz ustawionych symboli dla systemu. Na to jest prosta rada, wpisz napierw .symfix, potem .reload (dociągnie sobie trochę rzeczy z serwerów Microsoftu). Przy uruchomieniu pierwsze 'błędy' to uruchomienie programu itd. - czytaj opisy. Daj F5 i rób to co zwykle, aż się program wysypie. Możesz albo sam spróbować się rozeznać, co się dzieje, albo dać !analyze -v, przez co WinDBG postara się podać jak najwięcej przydatnych informacji i możliwie najdokładniej ustalić przyczynę błędu. Wynik komendy możesz tutaj wkleić jeżeli nic konkretnego Ci nie powie, pomyślimy.

0

Ewentualnie wyślij mi ten program (o ile nie tajny) to też popatrzę, może mi też coś się uda znaleźć.

0

Deus ma rację, ale absolutnie nic nie szkodzi mi wrzucić binarkę, przecież nie musisz się specjalnie spieszyć ze swoimi wnioskami ;)
Mingw release build:
http://www.wrzuc.to/7lDrbW.wt

edit
VS build z plikiem PCB

http://www.wrzuc.to/3DAJJgrV.wt

0

SynEngine!SyntSettings::LoadSets+0x66a [d:\kody visual studio\syntezer\syntezer\synengine\syntsettings.cpp @ 267] - null pointer dereference, a konkretnie call pod zerowy pointer, główna przyczyna problemów. Przy okazji przy odpalaniu pod WinDBG program marudzi co do alokacji, operator new wyjątkiem rzuca, masz tu callstack:

0012f690 004146a2 SynEngine!_CxxThrowException+0x48 [f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\throw.cpp @ 161]
0012f6ac 0040a679 SynEngine!operator new+0x64 [f:\dd\vctools\crt_bld\self_x86\crt\src\new.cpp @ 63]
0012f7d8 0040a267 SynEngine!SyntSettings::ImportSetsFromCfg+0x319 [d:\kody visual studio\syntezer\syntezer\synengine\syntsettings.cpp @ 103]
0012f83c 0040ad8e SynEngine!SyntSettings::CurrentSetInfo+0x47 [d:\kody visual studio\syntezer\syntezer\synengine\syntsettings.cpp @ 67]
0012fe90 00403144 SynEngine!SyntSettings::LoadSets+0x4e [d:\kody visual studio\syntezer\syntezer\synengine\syntsettings.cpp @ 238]
0012ff70 0040265b SynEngine!SyntCore::SayIt+0x54 [d:\kody visual studio\syntezer\syntezer\synengine\syntcore.cpp @ 24]
0012ff78 00415d1a SynEngine!main+0xb [d:\kody visual studio\syntezer\syntezer\synengine\main.cpp @ 27]
0

Heh w końcu ogarnąłem jak się WinDBG posłużyć, chciałem się pochwalić a tu lipa...teraz nikt mi nie uwierzy.

deus napisał(a)

Przy okazji przy odpalaniu pod WinDBG program marudzi co do alokacji, operator new wyjątkiem rzuca

Tutaj sprawa wydaje mi się prosta, inicjalizuję dynamiczną tablicę z tym że rozmiar siedzi w zmiennej typu std::pos_type, rzutowanie na inta powinno załatwić sprawę. Ale ogólnie w tym fragmencie kodu jeszcze nie podpiąłem mojego wrappera stdio tylko nadal używam iostreamn także rozmiar będę miał typu long. Dlaczego nie chce iostream? Miałem z nim niezły bajzel na wcześniejszym etapie tworzenia kodu i mimo że używa się go wygodnie to trochę się zraziłem.

Co do właściwego błędu to sprawa jest trochę trudniejsza. W tym miejscu gdzie jest call na zerowy pointer wywołuję funkcję z drugiej dllki. Czyli podejrzewam że coś przy ładowaniu dll się krzaczy, akurat z tą jedną dllką to od początku miałem problem. Funkcje akurat z tej felernej dllki mogę załadować statycznie, może to pomoże.

0

Ok, więc mi się udało zauważyć tyle (w sumie nie mam specjalnego doświadczenia w tych sprawach, więc mogę się mylić):

  1. Ładujesz dynamicznie (albo chyba raczej prolog kompilatora ładuje) bibliotekę mbrola.dll
  2. Pobierasz po kolei z niej adresy funkcji - naliczyłem 23 ładowane funkcje, chociaż biblioteka eksportuje 25. Nie wiem jakie bo nie chciało mi się sprawdzać :P (pesymistycznie ponad 500 porównań) i to pewnie nic ważnego (patrz koniec i obrazy pamięci, tam jest lista wczytanych). Ważne: wszystkie adresy, razem z HMODULE otrzymanym z LoadLibrary zostają zapisane w pamięci. (patrz p. B)
  3. Następnie wykonywanie kodu leci dalej, przez main, wchodzi do SyntCore::SayIt(char *)
  4. Wywołuje MbrolaDllLoading::MbrStart(void), wszystko jak na razie OK.
  5. Sterowanie przechodzi do SyntSettings::LoadSets(void), przy czym otrzymuje 2 parametry. Na początku się nad tym głowiłem a później załapałem że to __thiscall - metoda klasy otrzymuje pewnie instancje klasy. Tak czy inaczej (jeśli wierzyć temu co widzę - a mogę źle interpretować) drugi parametr to wskaźnik do HMODULE z mbrola.dll
  6. Wywołanie leci w tej funkcji, kilka wywołań typu SyntSettings::CurrentSetInfo(void), porównanie czegoś z "NO ERROR" i takie tam.
  7. dużo wywołań na istreamach
  8. już prawie koniec - stworzenie (?) ostringstreama.
  9. do edi przenosimy drugi (a właświe pierwszy) argument funkcji - czyli HMODULE mbrola.dll
    A. do edx przenosimy [edi + 70h] (czyli w c++ w rodzaju edx = edi[0x70] - w sumie raczej edi[28] bo mówimy o dwordach )
    B. zapomniałem napisać... to niby-hmodule w pamięci wygląda tak:
    [wskaźnik do załadowanej do pamięci biblioteki]
    [wskaźniki do eksportowanych funkcji * 23 (te 23 ładowane funkcje) ]
    czyli edi[X] oznacza odwołanie do X funkcji
    C. No a odwołanie do edi[28] oznacza odwołanie do 28 funkcji, której nie ma.
    D. i wywołujemy edx.

dokładnie fragment [8..D] wygląda tak:

.text:0130B38B call    ??0?$basic_ostringstream@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@H@Z
.text:0130B390 mov     edi, [esp+64Ch+arg_do_calla]
.text:0130B397 mov     byte ptr [esp+64Ch+var_4], 1Ch
.text:0130B39F fld     [esp+64Ch+var_5D0]
.text:0130B3A3 mov     edx, [edi+70h]                  ; 70-ty element tablicy czy co 0_o Tak czy inaczej [0 + 70]
.text:0130B3A6 push    ecx
.text:0130B3A7 fstp    [esp+650h+var_650]
.text:0130B3AA call    edx

a niby-hmodule w pamięci wygląda tak:

.data:013358CC ParametrDoEdi dd offset unk_10000000    ; DATA XREF: SyntCore::SyntCore(void)+33o
.data:013358CC                                         ; SyntCore::~SyntCore(void):loc_13030A8o ...
.data:013358D0 dd offset mbrola_init_MBR
.data:013358D4 dd offset mbrola_init_rename_MBR
.data:013358D8 dd offset mbrola_write_MBR
.data:013358DC dd offset mbrola_flush_MBR
.data:013358E0 dd offset mbrola_read_MBR
.data:013358E4 dd offset mbrola_readtype_MBR
.data:013358E8 dd offset mbrola_close_MBR
.data:013358EC dd offset mbrola_reset_MBR
.data:013358F0 dd offset mbrola_lastError_MBR
.data:013358F4 dd offset mbrola_lastErrorStr_MBR
.data:013358F8 dd offset mbrola_setNoError_MBR
.data:013358FC dd offset mbrola_getNoError_MBR
.data:01335900 dd offset mbrola_setFreq_MBR
.data:01335904 dd offset mbrola_getFreq_MBR
.data:01335908 dd offset mbrola_setVolumeRatio_MBR
.data:0133590C dd offset mbrola_getVolumeRatio_MBR
.data:01335910 dd offset mbrola_getVersion_MBR
.data:01335914 dd offset mbrola_getDatabaseInfo_MBR
.data:01335918 dd offset mbrola_setParser_MBR
.data:0133591C dd offset mbrola_init_Phone
.data:01335920 dd offset mbrola_reset_Phone
.data:01335924 dd offset mbrola_close_Phone
.data:01335928 dd offset mbrola_appendf0_Phone
.data:0133592C dd 0
.data:01335930 dd 0
.data:01335934 dd 0
.data:01335938 dd 0
.data:0133593C dd 0                                    ; a do tego się odwołujesz

Sorry za chaotyczność, pisałem jednocześnie wchodząc w głąb pliku. Mam nadzieję że nie namieszałem za bardzo i nie pomyliłem się w ocenie czegoś (dalej nie wiem co to HMODULE tam robi...)

edit: minuta spóźnienia :D

0

To jest ten felerny fragment kodu

LONG err=0;
    ostringstream ossErrCode;

	err=MBR_SetPitchRatio(pitch);//o tutaj właśnie, funkcja z mbrplay.dll
	if(err!=0)
	{
		ossErrCode << err;
		m_lastLog="SetPitch fail. Error code: " + ossErrCode.str();
		m_syntSets["ERROR"]=m_lastLog;
		return m_syntSets;
	}

Ładuje dwie dllki, znaczy próbuję ładować: mbrola.dll i mbrplay.dll. Z debuga MSM wnioskuję że mbrplay.dll nie za bardzo chce współpracować. A te wywołania na stringstreamach to po prostu formatowanie wewnętrzne, może słabo to zoptymalizowałem ale nie jest z tym tak źle.

1

Ale MBR_SetPitchRatio jest eksportowany przez mbrplay... 0_o

Ok, chyba wiem coś więcej:

.text:00031360 push    offset aMbrplay_dll             ; "mbrplay.dll"
.text:00031365 call    ds:LoadLibraryA(x)
.text:0003136B mov     [esi+60h], eax
.text:0003136E test    eax, eax
.text:00031370 jz      pomijamy
; wczytywanie funkcji

EAX wynosi 0, czyli test wypada negatywnie i skok się wykonuje. To oznacza ni mniej ni więcej tylko to że żadna z funkcji z mbrplay nie jest ładowana (loadLibrary zwraca NULL). Jak tylko wpadnę dlaczego to napisze.

Edit1: Dziwne... Spatchowałem tamten kawałek kodu i wstawiłem GetLastError() które zwróciło 0x7E czyli ERROR_MOD_NOT_FOUND.

Edit2: Skoro z niej korzystasz, to w release przydała by się biblioteka TCTSAUDIO.dll... Pewnie masz ją w Windows\system32 albo podobnym miejscy i o niej zapomniałeś. Ja w każdym razie czegoś takiego nie mam na komputerze co prawdopodobnie jest bezpośrednią przyczyną błędu. Google też niezbyt o niej wie.

0
MSM napisał(a)

Edit2: Skoro z niej korzystasz, to w release przydała by się biblioteka TCTSAUDIO.dll

Panie kochany, jakie piwo pan pijesz? :) Kiedyś tam instalowałem stary syntezer stojący na mbroli, to pewnie pozostałość po deinstalacji, chyba. Pewnie głupie pytanie zadam, jak na to wpadłeś?

0

Zastanawiało mnie to ERROR_MOD_NOT_FOUND zwracane przy otwieraniu mbrplay - to by znaczyło że funkcja nie może znaleźć biblioteki, a tymczasem wyraźnie widziałem że jest w folderze z aplikacją.
Przeszukałem trochę internet i dowiedziałem się że LoadLibrary zwraca tą wartość nie tylko wtedy kiedy nie znajdzie konkretnej biblioteki, ale również w 2 innych przypadkach - kiedy użytkownik nie ma prawa dostępu do pliku(to wykluczamy) i kiedy biblioteka którą wczytujemy próbuje importować kolejną - której nie ma.
Stąd już był tylko kawałek do sprawdzenia importów mbrplay, a tam znalazłem to TCTSAUDIO :]

0

@deus,MSM: Dziękuję wam panowie, wiele pożytecznych rzeczy się od was dowiedziałem.

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