Page 26 of 77

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

Posted: Mon Jan 09, 2012 8:08 pm
by Serge
Для MSVC #pragma pack(push, 1) перед объявлением структур и #pragma pack(pop) после или /Zp

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

Posted: Sun Jan 22, 2012 12:54 pm
by SoUrcerer
Туплю очень конкретно. У меня есть файл 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;
Тоже падает, и тоже в ассемблерном листинге отсутствует определение этой переменной. Что за хрень вообще?:(

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

Posted: Sun Jan 22, 2012 1:08 pm
by SoUrcerer
Для тех, кто смотрит форум через rss - обновил в прошлом сообщении информацию. В ассемблерный листинг определения некоторых переменных не попадают.

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

Posted: Sun Jan 22, 2012 3:36 pm
by Serge
Ты собираешь СOFF библиотеку ? Тогда все надо компилировать одним файлом.

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

Posted: Sun Jan 22, 2012 4:21 pm
by SoUrcerer
Нет, я собираю static-файл. Ага, кажется, догадался. Оригинал состоит из трех a-библиотек и одного файла, а я все o-файлы линкую в один файл. Это есть неправильно?

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

Posted: Sun Jan 22, 2012 4:25 pm
by Serge
Если собираешь обычную программу сделай mapfile. Поставь перед вылетами контрольные точки
asm volatile ("int3"); и запусти под отладчиком. Будет видно что именно происходит.

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

Posted: Sun Jan 22, 2012 4:33 pm
by SoUrcerer
Ага, поэкспериментирую. Справочников-мануалов кроме встроенной справки kolibri debug нет случайно?
И все равно не понимат, почему в асм-листингах нет переменных.

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

Posted: Mon Jan 23, 2012 7:13 pm
by SoUrcerer
Падает на

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
Ваши мысли?

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

Posted: Mon Jan 23, 2012 7:26 pm
by SoUrcerer
Задал всем переменным начальные состояния, они переместились в bss из Common.
Теперь обращения к другим переменным - а результат тот же. В чём мой косяк?

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

Posted: Mon Jan 23, 2012 7:37 pm
by SoUrcerer
Я имею в виду, что при обращении к переменным, которые не в bss, а в common, происходит крэш :(

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

Posted: Mon Jan 23, 2012 7:53 pm
by Serge
Посмотри в заголовке программы сколько там выделено памяти. Скорее всего меньше, чем нужно реально. Если линкуешь с menuetlibc то там 4Mb на всё.

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

Posted: Mon Jan 23, 2012 8:06 pm
by SoUrcerer
Офигеть! Serge, спасибо! Оказывается, этой дуре нужно овер дофига ОЗУ.

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

Posted: Mon Jan 23, 2012 8:13 pm
by Serge
А что ты такое замечательное собираешь, что оно больше 20 метров кушает ?
newlib не пробовал ? Там нет этой проблемы.
Проверь ещё размер стека. Дефолтный в menuetlibc 128 Кб. Если в программе есть alloca может не хватить.

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

Posted: Mon Jan 23, 2012 8:25 pm
by SoUrcerer
Эмулятор одной 32-битной машины. Newlib не пробовал, для него придется пересобирать libSDL, у меня пока на это смелости не хватает. Сейчас эмулятор запускается, но эмулировать нормально не может - уходит в вечный цикл.

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

Posted: Mon Jan 23, 2012 10:13 pm
by SoUrcerer
Новые, еще более безумные глюки.

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 ниже, чем вершина стека, установленная в заголовке.