Помогите новичку

Applications development, KoOS API questions
  • Туплю очень конкретно. У меня есть файл tos.h, подключенный из файла tos.c:

    Code: Select all

    extern bool bIsEmuTOS;
    extern Uint16 TosVersion;
    extern Uint32 TosAddress, TosSize;
    extern bool bTosImageLoaded;
    extern bool bRamTosImage;
    extern unsigned int ConnectedDriveMask;
    extern int nNumDrives;
    
    extern void TOS_MemorySnapShot_Capture(bool bSave);
    extern void TOS_AutoStart(const char *prgname);
    extern FILE *TOS_AutoStartOpen(const char *filename);
    extern bool TOS_AutoStartClose(FILE *fp);
    extern int TOS_LoadImage(void);
    
    Эти же переменные определены в tos.c:

    Code: Select all

    
    bool bIsEmuTOS;
    Uint16 TosVersion;                      /* eg. 0x0100, 0x0102 */
    Uint32 TosAddress, TosSize;             /* Address in ST memory and size of TOS image */
    bool bTosImageLoaded = false;           /* Successfully loaded a TOS image? */
    bool bRamTosImage;                      /* true if we loaded a RAM TOS image */
    unsigned int ConnectedDriveMask = 0x03; /* Bit mask of connected drives, eg 0x7 is A,B,C */
    int nNumDrives = 2;                     /* Number of drives, default is 2 for A: and B: - Strictly, this is the highest mapped drive letter, in-between drives may not be allocated */
    
    При обращении к этим переменным из функции внутри файла tos.c получаю ошибку сегментации:

    Code: Select all

    int TOS_LoadImage(void)
    {
    __menuet__debug_out ("in loadimg\n");
    	Uint8 *pTosFile = NULL;
    	long nFileSize;
    __menuet__debug_out ("in loadimg2\n");
    	bTosImageLoaded = false;
    __menuet__debug_out ("in loadimg3\n");
    	/* Load TOS image into memory so that we can check its version */
    	TosVersion = 0;
    __menuet__debug_out ("in loadimg4\n");
    
    Получаю на доску отладки
    in loadimg
    in loadimg2
    in loadimg3
    И сразу сегфолт. Чем такое может быть вызвано? Почему тот же код работает в Linux?

    Ассемблерный листинг затронутого куска:

    Code: Select all

    .LC1:
    	.string	"in loadimg\n"
    .LC2:
    	.string	"in loadimg2\n"
    .LC3:
    	.string	"in loadimg3\n"
    .LC4:
    	.string	"in loadimg4\n"
    .globl TOS_LoadImage
    	.type	TOS_LoadImage, @function
    TOS_LoadImage:
    	pushl	%ebp
    	movl	%esp, %ebp
    	pushl	%edi
    	pushl	%esi
    	pushl	%ebx
    	subl	$56, %esp
    	pushl	$.LC1
    	call	__menuet__debug_out
    	movl	$.LC2, (%esp)
    	call	__menuet__debug_out
    	movl	$.LC3, (%esp)
    	movl	$0, bTosImageLoaded
    	call	__menuet__debug_out
    	movl	$.LC4, (%esp)
            movw	$0, TosVersion
    	call	__menuet__debug_out
    ....
    
    .globl bTosImageLoaded
    	.bss
    	.align 4
    	.type	bTosImageLoaded, @object
    	.size	bTosImageLoaded, 4
    bTosImageLoaded:
    	.zero	4
    
    
    Эм, а определения TosVersion в ассемблерном листинге нет - то есть переменная undefined? o_O как так?
    Копать в сторону uint16 и uint32?
    При попытке

    Code: Select all

    bRamTosImage = false;
    
    Тоже падает, и тоже в ассемблерном листинге отсутствует определение этой переменной. Что за хрень вообще?:(
  • Для тех, кто смотрит форум через rss - обновил в прошлом сообщении информацию. В ассемблерный листинг определения некоторых переменных не попадают.
  • Ты собираешь СOFF библиотеку ? Тогда все надо компилировать одним файлом.
  • Нет, я собираю static-файл. Ага, кажется, догадался. Оригинал состоит из трех a-библиотек и одного файла, а я все o-файлы линкую в один файл. Это есть неправильно?
  • Если собираешь обычную программу сделай mapfile. Поставь перед вылетами контрольные точки
    asm volatile ("int3"); и запусти под отладчиком. Будет видно что именно происходит.
  • Ага, поэкспериментирую. Справочников-мануалов кроме встроенной справки kolibri debug нет случайно?
    И все равно не понимат, почему в асм-листингах нет переменных.
  • Падает на

    Code: Select all

    mov word, [13676B4h], 0
    

    Code: Select all

    COMMON         0x00000000013676b4       0x14 tos.o
                    0x00000000013676b4                TosVersion
                    0x00000000013676b8                TosSize
                    0x00000000013676bc                bIsEmuTOS
                    0x00000000013676c0                TosAddress
                    0x00000000013676c4                bRamTosImage
    В то время как переменная, изменение которой не вызывает зависаний,

    Code: Select all

     .bss           0x0000000000296228       0x24 tos.o
                    0x0000000000296228                bTosImageLoaded
    Ваши мысли?
  • Задал всем переменным начальные состояния, они переместились в bss из Common.
    Теперь обращения к другим переменным - а результат тот же. В чём мой косяк?
  • Я имею в виду, что при обращении к переменным, которые не в bss, а в common, происходит крэш :(
  • Посмотри в заголовке программы сколько там выделено памяти. Скорее всего меньше, чем нужно реально. Если линкуешь с menuetlibc то там 4Mb на всё.
  • Офигеть! Serge, спасибо! Оказывается, этой дуре нужно овер дофига ОЗУ.
  • А что ты такое замечательное собираешь, что оно больше 20 метров кушает ?
    newlib не пробовал ? Там нет этой проблемы.
    Проверь ещё размер стека. Дефолтный в menuetlibc 128 Кб. Если в программе есть alloca может не хватить.
  • Эмулятор одной 32-битной машины. Newlib не пробовал, для него придется пересобирать libSDL, у меня пока на это смелости не хватает. Сейчас эмулятор запускается, но эмулировать нормально не может - уходит в вечный цикл.
  • Новые, еще более безумные глюки.

    Code: Select all

    __menuet__debug_out("scrinit\n");
    __menuet__debug_out("yeah\n");
    Screen_Init();
    __menuet__debug_out("ttl\n");
    
    В ассемблере:

    Code: Select all

    movl	$.LC20, (%esp)
    call	__menuet__debug_out
    movl	$.LC21, (%esp)
    call	__menuet__debug_out
    call	Screen_Init
    movl	$.LC22, (%esp)
    call	__menuet__debug_out
    

    Code: Select all

    void Screen_Init(void)
    {
    __menuet__debug_out("lool\n");
    __menuet__debug_out("yeah\n");
    int i;
    

    Code: Select all

    .globl Screen_Init
    	.type	Screen_Init, @function
    Screen_Init:
    pushl	%ebp
    movl	%esp, %ebp
    pushl	%ebx
    subl	$288, %esp
    pushl	$.LC10
    call	__menuet__debug_out
    movl	$.LC11, (%esp)
    call	__menuet__debug_out
    

    На доске отладки из одной папки вижу
    scrinit
    и крэш, который даже отладчик не может поймать

    Из другой папки-
    scrinit
    yeah
    yeah
    И так же крэш. Где мой лоол? :(

    Памяти не может не хватать, я этой дуре выделяю теперь 256 мегабайт ОЗУ (пробовал и больше). Какая-то фигня со стеком? Как проверить? Как узнать, в чем дело?

    Upd. Стек заполниться не успевает, в момент креша esp всего байт на 300 ниже, чем вершина стека, установленная в заголовке.
  • Who is online

    Users browsing this forum: No registered users and 0 guests