Autor Wątek: [c++, allegro][rozwiązany] Problem z uruchomieniem programu(Unhandled exception)  (Przeczytany 1664 razy)

Offline absount

  • Użytkownik

# Luty 15, 2013, 22:11:51
Witam
Od razu zaznaczam, że rozwiązania problemu szukam już kilka godzin, i nie wiem - coś nie tak z biblioteką, czy ze mną ;)
Zaznaczam, że jestem początkujący w te klocki, również z allegro.

Napisałem program w allegro 4.4.2, (visual c++ 2010), który wyświetla parę figur. Po zlikwidowaniu wszelkich błędów, próbuję go uruchomić, ale nic się nie uruchamia. Po ręcznym uruchomieniu programu windows informuje o błędnym zakończeniu działania programu (słynne okienko "czy wysłać komunikat o błędzie"). Wchodzę w tryb debugowania, i natychmiast w konsoli pojawia się okienko z informacją:

Unhandled exception at 0x100010e4 in Wykresy_meteo.exe: 0xC0000005: Access violation reading location 0x0000001c

i pod spodem przyciski break i continue, okno mojego programu nie wyświetla się, choć jest na pasku zadań.
komunikaty w konsoli:
'Wykresy_meteo.exe': Loaded 'C:\Documents and Settings\Piotrek\Desktop\projekty\Wykresy_meteo\Debug\Wykresy_meteo.exe', Symbols loaded.
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\Documents and Settings\Piotrek\Desktop\projekty\Wykresy_meteo\Debug\allegro-4.4.2-md.dll', Binary was not built with debug information.
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\ddraw.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\secur32.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\dciman32.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\user32.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\dsound.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\version.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\winmm.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\msvcr100.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\uxtheme.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\dinput.dll', Cannot find or open the PDB file
'Wykresy_meteo.exe': Unloaded 'C:\WINDOWS\system32\dinput.dll'
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\PROCHLP.DLL', Binary was not built with debug information.
'Wykresy_meteo.exe': Loaded 'C:\WINDOWS\system32\msctf.dll', Cannot find or open the PDB file
First-chance exception at 0x100010e4 in Wykresy_meteo.exe: 0xC0000005: Access violation reading location 0x0000001c.
Unhandled exception at 0x100010e4 in Wykresy_meteo.exe: 0xC0000005: Access violation reading location 0x0000001c.
The program '[944] Wykresy_meteo.exe: Native' has exited with code 0 (0x0).

kod programu:
main.cpp

#include "headers.h"
//#include "allegro.cpp"

cAllegro Allegro;

int main()
{
    allegro_init();
    set_color_depth( 32 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, 1018, 700, 0, 0 );
    set_palette( default_palette );
   
    show_mouse( screen );
    unscare_mouse();

    clear_to_color( screen, makecol( 0, 0, 0 ) );  //#### TUTAJ ZATRZYMUJE SIĘ PROGRAM (podświetlona linia po błędzie) #####

    install_mouse();
    install_keyboard();


    Allegro.rysuj_prostokat(0,0,800,500,128,128,128, true);
    Allegro.rysuj_linie(50,50,400,300, 255,0,0);
    Allegro.rysuj_kolo(300,300, 30, 255,255,255, false);
    Allegro.rysuj_tekst("Testujemy Allegro :) ASCÓąśćźżÓĄ", 100, 200, 255,255,255);
    Allegro.zapisz_wykres("wykres.bmp");
    Allegro.obsloz_zdarzania();
    return 0;
}
END_OF_MAIN();

headers.h
#include <allegro.h>
#include <iostream>

class cAllegro
{
public:
    cAllegro();
    ~cAllegro();
    void obsloz_zdarzania();
    void rysuj_prostokat(int x1, int y1, int x2, int y2, int r, int g, int b, bool wypelniony);
    void rysuj_linie(int x1, int y1, int x2, int y2, int r, int g, int b);
    void rysuj_kolo(int x, int y, int promien, int r, int g, int b, bool wypelniony);
    void rysuj_tekst(std::string tekst, int x, int y, int r, int g, int b);
    void zapisz_wykres( std::string nazwa);
    void czysc_okno();
};

allegro.cpp ominę, same nakładki na funkcje allegro
« Ostatnia zmiana: Luty 16, 2013, 12:09:10 wysłana przez absount »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Avaj

  • Użytkownik

# Luty 15, 2013, 22:24:17
Czy robisz coś w konstruktorze klasy cAllegro? Bo konstruktor klasy cAllegro odpali się przed odpaleniem allegro_init(), więc pewnie jeśli używasz czegoś z allegro w konstruktorze to spowodujesz wysyp aplikacji zanim dojdzie w ogóle do maina().

edit: btw, obsłuż a nie obsłóż :)

Offline absount

  • Użytkownik

# Luty 15, 2013, 22:33:30
Nie, starając się jakoś naprawić ten problem przeniosłem całą zawartość z konstruktora do funkcji main - tj. wszystko do Allegro.rysuj_.....

obsłuż - już wiem, dlaczego komplikator nie odnajdywał tej funkcji, z automatu przepisałem, to błąd nie-programistyczny ;)

No więc podam też allegro.cpp:
#include "headers.h"

cAllegro::cAllegro()
{

}
cAllegro::~cAllegro()
{
    allegro_exit();
}
void cAllegro::obsloz_zdarzania()
{
    while( 1 )
    {
        if(!key[ KEY_ESC ])
            return;
        readkey();
        //klawisz = readkey();
        //textprintf( screen, font, 20, 20, makecol( 255, 255, 128 ), "Klawisz to : %c", (char)klawisz );
       
    }
}
void cAllegro::rysuj_prostokat(int x1, int y1, int x2, int y2, int r, int g, int b, bool wypelniony = true)
{
    if(wypelniony)
        rectfill( screen, x1, y1, x2, y2, makecol( r, g, b ) );
    else
        rect( screen, x1, y1, x2, y2, makecol( r, g, b ) );
}
void cAllegro::rysuj_linie(int x1, int y1, int x2, int y2, int r, int g, int b)
{
    line( screen, x1, y1, x2, y2, makecol( r, g, b));
}
void cAllegro::rysuj_kolo(int x, int y, int promien, int r, int g, int b, bool wypelniony = true)
{
    if(wypelniony)
        circlefill( screen, x, y, promien, makecol( r, g, b ) );
    else
        circle( screen, x, y, promien, makecol( r, g, b ) );
}

void cAllegro::rysuj_tekst(std::string tekst, int x, int y, int r, int g, int b)
{
    textout_ex( screen, font, tekst.c_str(), x, y, makecol( r, g, b),-1);
}
void cAllegro::zapisz_wykres( std::string nazwa)
{
    BITMAP * obrazek = NULL;
    obrazek = create_bitmap(800,500);
    blit( screen, obrazek, 0,0, 0,0, 800,500);
    save_bitmap( nazwa.c_str(), obrazek, default_palette);
    destroy_bitmap(obrazek);
}

void cAllegro::czysc_okno()
{
    clear_to_color( screen, makecol( 10, 10, 10 ) );
}

Offline Avaj

  • Użytkownik

# Luty 15, 2013, 22:36:35
To pewnie głupie, ale może linkujesz bibliotekę 64bitową pod 32bitowy kompilator albo coś w tym rodzaju?

Offline flexi

  • Użytkownik

# Luty 15, 2013, 22:39:42
Z tego co widze nigdzie nie alokujesz pamieci dla screen.

Offline absount

  • Użytkownik

# Luty 15, 2013, 23:06:22
Z dokumentacji:

screen - Global pointer to the screen hardware video memory.

W żadnym przykładzie nigdy nie widziałem alokowania pamięci dla screen, to po prostu jest.

Nie wiem, sprawdzam, co tylko wpadnie mi do głowy, nie rozumiem tego...
« Ostatnia zmiana: Luty 15, 2013, 23:15:03 wysłana przez absount »

Offline flexi

  • Użytkownik

# Luty 15, 2013, 23:20:03
Niewazne, dawno w Allegro nie pisalem i myslalem ze to od double bufferingu.

Offline Liosan

  • Redaktor

# Luty 15, 2013, 23:25:29
Jak bym podszedł do debugowania tego błędu:
- wywalić cały swój kod (source control rządzi) i wkleić przykład z wiki, żywcem wkleić do TEGO SAMEGO PROJEKTU. Jeśli nie działa - problem z setupem projektu, linkowanymi bibliotekami, etc. Jeśli działa, szukamy dalej.
- wpisać na początku main(), i po każdej linii, wypisać coś na stderr (albo niebuforowane stdout). Jak coś wypisze, a potem padnie - wiemy gdzie szukać błędu; jak nie, to problem jest przed mainem.
Wyniki samemu interpretować i się podzielić na forum, ewentualnie wkleić na forum i dalej się konsultować :)

Liosan
« Ostatnia zmiana: Luty 15, 2013, 23:27:55 wysłana przez Liosan »

Offline absount

  • Użytkownik

# Luty 16, 2013, 00:58:42
Sprawdziłem ustawienia projektu, wywalając kod i wrzucając kilka bardziej skomplikowanych przykładów ze stron o allegro - wszystko działa.
Debugowałem, używając:
std::ofstream fin("data.txt");
fin << __LINE__;
fin << " linia \n";
fin.flush();
i dochodziłem do tego samego momentu, co debugger w vs c++, czyli:
clear_to_color( screen, makecol( 0, 0, 0 ) );potem już nie ma komunikatów.
Zakomentowałem - oto kolejne funkcje, na których program pada:
rectfill( screen, x1, y1, x2, y2, makecol( r, g, b ) );

line( screen, x1, y1, x2, y2, makecol( r, g, b));

circle( screen, x, y, promien, makecol( r, g, b ) );

textout_ex( screen, font, tekst.c_str(), x, y, makecol( r, g, b),-1);

itd...

wygląda na to, że program pada na funkcjach, które coś rysują na ekranie - czyli screen
Próbowałem pomysłu flexi - zaalokowałem pamięć dla screen, ale to nic nie dało, program sam się wywala (czyli pewnie screen jest już "zrobiony"). Napisałem takie coś:
BITMAP *screen = NULL;
screen = create_video_bitmap(800, 600);
i na drugiej linii się wywala

gdy próbowałem debuggerem wejść we wnętrze funkcji, to okazało się, że to plik dll, gdzie wewnątrz sam assembler

czyli co? dll'ka? jej nazwa to allegro-4.4.2-md.dll

Offline Liosan

  • Redaktor

# Luty 16, 2013, 09:49:49
No dobra, ale prawie wszystkie te funkcje które wołasz przed crashem zwracają kod błędu albo sukces. Testowałeś, że wszystkie mówią że operacja się powiodła?

Liosan

Offline absount

  • Użytkownik

# Luty 16, 2013, 11:31:27
Liosan, masz wielką rację, zapomniałem :/

więc już sprawdziłem, problem był z:
if(set_gfx_mode( GFX_AUTODETECT_WINDOWED, 1018, 700, 0, 0) != 0) //!!!!!!!!!!!!!!!!!!!!!1111!
    {
        fin << __LINE__;
        fin << " set_gfx_mode zwraca błąd \n";
        fin.flush();
    }
        fin << __LINE__;
        fin << " rozmiar screen: \n";
        fin << SCREEN_W << " " << SCREEN_H << "\n";
        fin << VIRTUAL_W << " " << VIRTUAL_H << "\n";
        fin.flush();

zwracało w pliku tekstowym:
27 set_gfx_mode zwraca błąd
31 rozmiar screen:
0 0
0 0
37 linia
43 niepoprawny wskaźnik na screen
myślałem, i wymyśliłem - niedawno kombinowałem z wielkością okna. Kiedy korzystałem z SFML to program mi się nie wywalał, a tego jeszcze nigdy nie uruchamiałem. Ustawiłem na standardowe
set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 )i wszystko dobrze, program działa :)
31 rozmiar screen:
800 600
800 600
37 linia
52 linia
co najciekawsze sprawdzałem inne kombinacje:
1024x800
800x500
800x300
200x300
1000x300
1000x700
i wszystko działa, wywala się przy np. 1018, 999, czy 211, czyli bardzo niestandardowych ustawieniach.

Więc bardzo przepraszam z kłopot i niedopatrzenie z mojej strony - tak naprawdę to jeszcze nie napisałem żadnego poważnego programu.
Dzięki Liosan, wątek niech zostanie "ku potomnym".