Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Undefined instruction, Data Abort, SWI - помогите локализовать проблему!
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Атмег
Тупой вопрос, но уже месяц не могу найти концов. Спецы, помогите!

Имеется отладочная плата at91sam9263-ek (то есть железо как мне кажется рабочее). Приложение работает, вроде бы все нормально. Но. Периодически возникают прерывания Undefined instruction, Prefetch abort, Data abort и Software interrupt. Возникают в произвольный момент времени. То есть иногда программа идет по одной и той же ветке нормально, иногда в какой то момент возникает прерывание.
Я могу понять причины Undefined instruction, ну скажем не туда что то записал (код из SDRAM исполняется), но SWI почему тогда возникает?
Смотрю отладчиком:

backtrace
#0 0x0000000c in ?? () // исключение по prefetch abort
#1 0xdfff9f36 in ?? () // предыдущее значение PC - из неиспользуемого диапазона, такое обращение и должно вызвать abort

Притом что никакой динамической памяти, передачи функции в качестве параметра и т.п. у меня не используется, все структуры статические.

Проект слинкован под SDRAM, собирается gcc-4.2.2, newlib-1.16.0.

Более конкретно вопросы:

1. SWI (software, не spurious), случайно возникает, хотя нигде в коде не используется - непонятно, как?

2. В gcc был (есть?) баг, касающийся генерации прологов/эпилогов в прерываниях, но у меня обработчики взяты из атмеловских примеров, ниже приведу их. Там и вложенность поддерживается и общий стек используется, переполнения быть не должно.
Тут вроде как все норм должно быть? Или я еще какой то тонкости не понимаю?

3. Программа попадает в прерывание, я отладчиком вижу конечное состояние и стек, но это мало чего дает, может есть еще какие то способы получить информацию о предыстории?

Вот мой стартап, обработчик FIQ скопирован с IRQ, выкидывать лишнее не стал для уверенности что не в нем проблема.
CODE

#define FIQ_STACK_SIZE 8*3*4
#define IRQ_STACK_SIZE 8*3*4

#define ARM_MODE_ABT 0x17
#define ARM_MODE_FIQ 0x11
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13

#define I_BIT 0x80
#define F_BIT 0x40

//------------------------------------------------------------------------------
// Startup routine
//------------------------------------------------------------------------------

.align 4
.arm

/* Exception vectors
*******************/
.section .vectors, "a", %progbits

resetVector:
ldr pc, =resetHandler /* Reset */
undefVector:
b undefVector /* Undefined instruction */
swiVector:
b swiVector /* Software interrupt */
prefetchAbortVector:
b prefetchAbortVector /* Prefetch abort */
dataAbortVector:
b dataAbortVector /* Data abort */
reservedVector:
b reservedVector /* Reserved for future use */
irqVector:
b irqHandler /* Interrupt */
fiqVector:
// b fiqHandler /* Fast interrupt */
//------------------------------------------------------------------------------
/// Handles a fast interrupt request by branching to the address defined in the
/// AIC.
//------------------------------------------------------------------------------
fiqHandler:

/* Save interrupt context on the stack to allow nesting */
sub lr, lr, #4
stmfd sp!, {lr}
mrs lr, SPSR
stmfd sp!, {r0, lr}

/* Write in the FVR to support Protect Mode */
ldr lr, =AT91C_BASE_AIC
ldr r0, [lr, #AIC_FVR]
str lr, [lr, #AIC_FVR]

/* Branch to interrupt handler in Supervisor mode */
msr CPSR_c, #ARM_MODE_SVC | F_BIT | I_BIT
stmfd sp!, {r1-r3, r4, r12, lr}
blx r0

/* Restore scratch/used registers and LR from User Stack */
/* Disable Interrupt and switch back in FIQ mode */
ldmia sp!, {r1-r3, r4, r12, lr}
msr CPSR_c, #ARM_MODE_FIQ | F_BIT | I_BIT

/* Acknowledge interrupt */
ldr lr, =AT91C_BASE_AIC
str lr, [lr, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
ldmia sp!, {r0, lr}
msr SPSR_cxsf, lr
ldmia sp!, {pc}^

//------------------------------------------------------------------------------
/// Handles incoming interrupt requests by branching to the corresponding
/// handler, as defined in the AIC. Supports interrupt nesting.
//------------------------------------------------------------------------------
irqHandler:

/* Save interrupt context on the stack to allow nesting */
sub lr, lr, #4
stmfd sp!, {lr}
mrs lr, SPSR
stmfd sp!, {r0, lr}

/* Write in the IVR to support Protect Mode */
ldr lr, =AT91C_BASE_AIC
ldr r0, [lr, #AIC_IVR]
str lr, [lr, #AIC_IVR]

/* Branch to interrupt handler in Supervisor mode */
msr CPSR_c, #ARM_MODE_SVC
stmfd sp!, {r1-r3, r4, r12, lr}
blx r0

/* Restore scratch/used registers and LR from User Stack */
/* Disable Interrupt and switch back in IRQ mode */
ldmia sp!, {r1-r3, r4, r12, lr}
msr CPSR_c, #ARM_MODE_IRQ | F_BIT | I_BIT

/* Acknowledge interrupt */
ldr lr, =AT91C_BASE_AIC
str lr, [lr, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
ldmia sp!, {r0, lr}
msr SPSR_cxsf, lr
ldmia sp!, {pc}^

//------------------------------------------------------------------------------
/// Initializes the chip and branches to the main() function.
//------------------------------------------------------------------------------
.section .text
.global entry

entry:
resetHandler:

/* Useless instruction for referencing the .vectors section */
ldr r0, =resetVector

/* Set pc to actual code location (i.e. not in remap zone) */
ldr pc, =1f

/* Initialize the prerelocate segment */
1:
ldr r0, =_efixed
ldr r1, =_sprerelocate
ldr r2, =_eprerelocate
1:
cmp r1, r2
ldrcc r3, [r0], #4
strcc r3, [r1], #4
bcc 1b

/* Perform low-level initialization of the chip using LowLevelInit() */
ldr sp, =_sstack
stmfd sp!, {r0}
ldr r0, =LowLevelInit
blx r0

/* Initialize the postrelocate segment */

ldmfd sp!, {r0}
ldr r1, =_spostrelocate
ldr r2, =_epostrelocate
1:
cmp r1, r2
ldrcc r3, [r0], #4
strcc r3, [r1], #4
bcc 1b

/* Clear the zero segment */
ldr r0, =_szero
ldr r1, =_ezero
mov r2, #0
1:
cmp r0, r1
strcc r2, [r0], #4
bcc 1b

/* Setup stacks
**************/
/* FIQ mode */
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
ldr sp, =_sstack
sub r4, sp, #FIQ_STACK_SIZE

/* IRQ mode */
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov sp, r4
sub r4, sp, #IRQ_STACK_SIZE

/* Supervisor mode (interrupts enabled) */
msr CPSR_c, #ARM_MODE_SVC
mov sp, r4

/* Branch to main()
******************/
ldr r0, =main
blx r0

/* Loop indefinitely when program is finished */
1:
b 1b



Буду благодарен любым соображениям! Подскажите хоть что нибудь. Может кто натолкнет на мысль.
aaarrr
Цитата(Атмег @ Aug 10 2010, 22:23) *
1. SWI (software, не spurious), случайно возникает, хотя нигде в коде не используется - непонятно, как?

Возникает по той же причине, что и undefined instruction. Просто этой инструкцией иногда случайно оказывается SWI.

Цитата(Атмег @ Aug 10 2010, 22:23) *
2. В gcc был (есть?) баг, касающийся генерации прологов/эпилогов в прерываниях, но у меня обработчики взяты из атмеловских примеров, ниже приведу их. Там и вложенность поддерживается и общий стек используется, переполнения быть не должно.
Тут вроде как все норм должно быть? Или я еще какой то тонкости не понимаю?

Т.к. пролог и эпилог заключены в стартапе, то проблем быть не должно. Если, конечно, не продублировать их в C-обработчиках.

Цитата(Атмег @ Aug 10 2010, 22:23) *
3. Программа попадает в прерывание, я отладчиком вижу конечное состояние и стек, но это мало чего дает, может есть еще какие то способы получить информацию о предыстории?

Как минимум можно посмотреть LR_irq (или другого режима, в котором оказались) и узнать, откуда программа попала в исключение.
В большинстве случаев адреса и содержимого регистров достаточно для локализации проблемы. Если не помогает, то можно посмотреть и
стек, только убедитесь, что он принадлежит исходному режиму.
zltigo
QUOTE (Атмег @ Aug 10 2010, 21:23) *
3. Программа попадает в прерывание, я отладчиком вижу конечное состояние и стек, но это мало чего дает, может есть еще какие то способы получить информацию о предыстории?

Что значит "мало"? В этом все есть и откуда вылетели, соответственно команда, текст, по стеку и листингу раскручивается и история вызовов, если нужно идти вглубь. Все, как на ладошке.
Ну а по простому ошибка "номер раз" приводящая к необъяснимым явлениям это проблемы с размером стека.

Атмег
Вот смотрю LR:

#0 0x0000 0004
#1 0x2000 20A4 at main.c....
#2 0xE24E E004

В LR не могло оказаться 0xE24E E004, там вообще нет кода, это зарезервированный диапазон адресов.
То есть действительно стек запорчен? Но под стек места полно и непонятно как туда что то попало.

Вот мой линкер-скрипт, может я тут чего накосячил?
CODE

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(entry)

MEMORY
{
sram (W!RX) : ORIGIN = 0x300000, LENGTH = 0x10000
sdram (W!RX) : ORIGIN = 0x20000000, LENGTH = 32M
sdram_nocache (W!RX) : ORIGIN = 0x22000000, LENGTH = 32M
}

SECTIONS
{
.fixed :
{
. = ALIGN(4);
_sfixed = .;
*(.text*)
*(.glue_7)
*(.glue_7t)
*(.rodata*)
*(.data)
. = ALIGN(4);
_efixed = .;
} > sdram

.prerelocate : AT (_efixed)
{
. = ALIGN(4);
_sprerelocate = .;
. = ALIGN(4);
_eprerelocate = .;
}

.postrelocate : AT (_efixed + SIZEOF(.prerelocate))
{
. = ALIGN(4);
_spostrelocate = .;
*(.vectors)
*(.ramfunc)
. = ALIGN(4);

_epostrelocate = .;
} > sram

.bss (NOLOAD) :
{
_szero = .;
*(.bss)
_ezero = .;
} > sdram

.nocache (NOLOAD) :
{
*(.nocache)
} > sdram_nocache

_sstack = 0x22000000;
}
end = .;


Область 0x22000000 - 0x24000000 отведена под буферы и не кэшируется.
sergeeff
Обычно места под стеки резервируются в startup'e. Посмотрите там внимательно.
Атмег
Стартап я в первом посте привел, уже много раз все пересмотрел - не пойму что не так.

Объясните, как может получиться такая ситуация
Цитата
backtrace
#0 0x0000 0004
#1 0x2000 20A4 at main.c....
#2 0xE24E E004


zltigo
QUOTE
Но под стек места полно и непонятно

Вопрос на засыпку, сколько стеков у Вашего ARM? В каком режиме работаете? Из какого режима вылетели в Аборт? А "полно", это достаточно для работы?

QUOTE (Атмег @ Aug 11 2010, 18:36) *
Объясните, как может получиться такая ситуация

Без понятия, что значат всякие приведенные Вами цифири и как Вы их получали, посему ответа не будет.
Вот, например, распечатка вылета на Data Abort, по которой видно текущее состояние:
CODE
Abort:[D] PC:00016AF0 Op:E5D00020 CPSR:6000001F
   LR:00014BF4 SP:400059C0
SP[0]:00000022->00014BF4->00000016->0001381C->
SP[4]:40000EBC->40000E70->00000004->40002D4C
R0:00430001 R1:00000000 R2:00027190 R3:00000000  R4:40002D4C  R5:00026D40
R6:00000000 R7:40001698 R8:00000001 R9:00000004 R10:00000FFF R11:400034D4
R12:00000000

И можно о чем-то рассуждать.
sergeeff
Проверьте, правильно ли заполнена таблица векторов прерываний с адреса 0х00000000.
defunct
Цитата(zltigo @ Aug 11 2010, 19:12) *
Вот, например, распечатка вылета на Data Abort, по которой видно текущее состояние:

Data Abort это наиболее простая проблема, но по вашей распечатке не ясно содержание какого SP выведено. Тот что "DAbt SP" - смотреть бессмыслено, надо смотреть SP и стек контекст предыдущего режима, из которого ввалились в Abort. Prefetch Abort тоже относительно прост, LR SYS/SVSR режима будет содержать то место откуда прыгнули в недоступную область памяти.

В случае же Undef / Swi найти тот LR, что нужно очень не просто т.к. проц выполняет уже совсем не код программы, а просто какой-то мусор со случайного адреса.
если вдобавок еще и SYS / SVSR SP подпорчен, то практически нереально будет найти то место из которого осуществлен прыжек... Здесь нужен более глубойкий анализ дампа нежели только значения регистров.

как причина вышеописанного поведения из наиболее часто встечающихся в порядке убывания такие:

1. Перетирание стека упомянутое выше, по причине нехватки стека - решение: не жлобитесь, на железках с 32/64MB памяти отведите 1-2MB под стек (напр 64KB под задачу) и забудьте что такое проблемы со стеком навсегда.
2. Перетирание стека по причине выхода за границу массива, если есть массивы объявленные в стеке самое время посмотреть а все ли с ними в порядке.
3. NULL pointer в результате которого перетирается таблица векторов, тут имеет смысл анализировать дампы только с Data/Prefetch Abort'ами - их анализ будет самым эффективным.
4. Непроинициализированные поля / переменные. - очень сложная ситуация...
5. сбоит SDRAM - портится значение бита ячейки содержащей какой-нить callback. или что еще хуже - corruption непосредственно в секции кода. Здесь главное убедиться что в некой ячейке изменяется строго один бит, ну а дальше выявить регулярность и найти соотв. проблемную линию / попробовать изменить параметры SDRAM контроллера, если не поможет, - фиксить аппартный баг, вплоть до замены м/c памяти.
zltigo
QUOTE (defunct @ Aug 12 2010, 04:16) *
но по вашей распечатке не ясно содержание какого SP выведено.

Поскольку SP, Abort режима, как Вы правильно заметили, бессмысленен с точки зрения локализации проблемы, то выводить его мне было-бы ОЧЕНЬ странно. Посему совершено очевидно какой стек распечатан. Это точно так-же очевидно по содержимому CPSR, он ведь не Exception Mode показывает, а вполне себе System Mode не правда-ли smile.gif? Кстати, по нему-же видно, что вывалились не из обработчика прерывания или секции с закрытыми прерываниями - тоже информация.
И для именно для того, что-бы понять куда (чего как-раз не видно по распечатке) попали, и есть специальный индикатор Abort:[D] - значение которого я специально в посте и расшифровал - "Data Abort". Так-что никаких непоняток в распечатке нет.
QUOTE
В случае же Undef / Swi найти тот LR, что нужно очень не просто т.к. проц выполняет уже совсем не код программы, а просто какой-то мусор со случайного адреса.

Тем не менее, он далеко не обязательно попал туда через МНОЖЕСТВЕНЫЕ call. Ну в моем случае, распечатка состояния производится уже в отладочной консоли загрузчика - гипотетически можно и мусор по которому бежали порасшифровывать, благо PC есть (замечу, что тоже "тот" smile.gif ). В свое время для некоторых процессоров в консоли у меня и дизассемблер был. Ну в случае НЕ мусора, несколько вызовов обычно уже видны в стеке и вычисляются по листингу.
P.S.
Приведенная распечатка вылета, кстати, была прислана из-за границы за несколько часов до этого заказчиком ведущими проверку софта с добавленной функциональностью на железе которого у меня вообще нет smile.gif. Проблема с различием структур данных была по этой распечатке решена минут за 20. Случай был практически (в структурах было совсем не то) такой:
QUOTE
4. Непроинициализированные поля / переменные. - очень сложная ситуация...
Атмег
Цитата
Вопрос на засыпку, сколько стеков у Вашего ARM? В каком режиме работаете? Из какого режима вылетели в Аборт? А "полно", это достаточно для работы?


Стеки организованы так: по 0х2200 0000 лежит стек FIQ, ниже стек IRQ, ниже стек Supervisor. "Полно" - это неск Мб, судя по мэпу. Программа все время сидит в SVC, обработчик прерываний организован так: сохраняем в стек IRQ, потом переключаемся в SVC и выполняем прерывание в нем, по завершении обратно в IRQ, подтверждаем и выходим в SVC. Соответственно стек IRQ небольшой, а стека SVC большой, его должно хватить.
Нормально ли, что стек у меня в середине памяти, а над ним и до конца памяти еще отдельная секция под буферы? Просто мне показалось так удобней сделать для некэшируемых буферов.

Цитата
что значат всякие приведенные Вами цифири


Это результат выданный мне командой backtrace. В нормальном состоянии программы я по этим строчкам вижу цепочку вызовов, то есть это вроде как значения LR? Когда возникает глюк, backtrace выдает не знаю что, может он как то неправильно разбивает стек на фреймы и не может понять откуда был вызов? Но в любом случае видно что 0xe24ee004 - адрес из которого код не мог быть исполнен и не мог оттуда вызов быть.
Как от gdb получить подробную распечатку, как у Вас приведено? Не пинайте, я с gdb знаком недавно smile.gif

Цитата
Проверьте, правильно ли заполнена таблица векторов прерываний с адреса 0х00000000.


Правильно.

Вот типичный случай как выглядит:

"$cpsr" = 0x2000009b - Undefined instruction
sp 0x00000000 - sp для Undef не инициализирован, вместо обработчика беск цикл
"$lr" = 0x200020f8
"$pc" = 0x00000004


backtrace дает вот что:

#0 0x00000004 in ?? ()
#1 0x200020f8 in ISR_SPI1 () at main.c:1069
#2 0xe24ee004 in ?? ()
Backtrace stopped: frame did not save the PC

То есть из main.c:1069 как то попали в exceiption...
Как непонятно..
Dump of assembler code from 0x200020f0 to 0x20002100:
0x200020f0 <ISR_SPI1+272>: add lr, r12, #1 ; 0x1
0x200020f4 <ISR_SPI1+276>: add r2, lr, #1 ; 0x1
0x200020f8 <ISR_SPI1+280>: ldr r3, [pc, #1424] ; 0x20002690 <ISR_SPI1+1712>
0x200020fc <ISR_SPI1+284>: str r2, [r6]
End of assembler dump.

Глюк происходит редко, поэтому поставил в main.c:1069 брейкпоинт и посмотрел как оно в норме, вот так:
bt
#0 ISR_SPI1 () at main.c:1069
#1 0x00000088 in ?? ()
#2 0x20003b24 in AIC_ConfigureIT (source=<value optimized out>, mode=8, handler=0xffff) at at91lib/peripherals/aic/aic.c:61
#3 0x000007fe in ?? ()
#4 0xcc33cc32 in ?? ()
Backtrace stopped: frame did not save the PC

Тут похоже backtrace путается из-за обработчика прерываний, поэтому строчки #1-4 какие то бессмысленные. AIC_ConfigureIT из второй строки здесь вообще не вызывается, проверял, брейкпойнт на ней ставил.

Это наиболее частый случай я тут привел, а вообще то глюки возникают иногда еще до разрешения прерываний.

Цитата
1. Перетирание стека...


Смотрю по мар-файлу, неск Мб от последней переменной до начала стека

Цитата
2. Перетирание стека по причине выхода за границу массива, если есть массивы объявленные в стеке самое время посмотреть а все ли с ними в порядке.


Структуры объявлены, но обращаюсь к полям стандартным образом, без особых хитростей...

Цитата
3. NULL pointer в результате которого перетирается таблица векторов, тут имеет смысл анализировать дампы только с Data/Prefetch Abort'ами - их анализ будет самым эффективным.


malloc/calloc не использую, вроде не должно...

Цитата
4. Непроинициализированные поля / переменные. - очень сложная ситуация...


Можете подробнее, что имеется в виду? Кроме обращения по указателю который равен 0.

Цитата
5. сбоит SDRAM


Ситуация слабоповторяемая, то сбоит, то не сбоит. То есть запускаю определенную функцию в программе, может на 3-й раз посыпаться, может на 10-й... Плата - отладка Атмеловская. Могут на такой плате быть проблемы из-за плохой разводки? Или это больше относится к своим платам?
zltigo
QUOTE (Атмег @ Aug 12 2010, 16:37) *
backtrace выдает не знаю что..

Я тоже не знаю sad.gif smile.gif
QUOTE
Как от gdb получить подробную распечатку, как у Вас приведено? Не пинайте, я с gdb знаком недавно smile.gif

Не знаю, эта моя собственная распечатка при вылете, как уже писал, в аварийную консоль. Отладчиками пользуюсь крайне редко, ибо самое интересное случается за тысячи километров на объектах, а там никаких подключенных JTAG адаптеров, отладчиков, компиляторов и т.д. просто нет не было и не будет.
QUOTE (Атмег @ Aug 12 2010, 16:37) *
Стеки организованы так: по 0х2200 0000 лежит стек FIQ, ниже стек IRQ, ниже стек Supervisor. "Полно" - это неск Мб, судя по мэпу.

Какие такие "Mб", если стеки FIQ и IRQ черным по белому записаны у Вас по 24 слова!!! Да и инициализированы только три стека.
sergeeff
Вы бы взяли и прислали свой проект, если он не сов.секретный? Дистанционно вас пытать, что к чему, не очень продуктивно.
Атмег
Цитата(zltigo @ Aug 12 2010, 17:58) *
Какие такие "Mб", если стеки FIQ и IRQ черным по белому записаны у Вас по 24 слова! Да и инициализированы только три стека.


Ну я же описал, как работает обработчик прерывания. Сам код прерывания выполняется в SVC. Посему и стеки по 24 слова, а Мб - это стек SVC. Инициализированы только три стека, потому что обработчики остальных исключений отсутствуют

Цитата
backtrace выдает не знаю что..


Неправда, я привел то, что выдает backtrace. Проанализировать не могу.
zltigo
QUOTE (Атмег @ Aug 12 2010, 17:19) *
Посему и стеки по 24 слова, а Мб - это стек SVC. Инициализированы только три стека, потому что обработчики остальных исключений отсутствуют

По этой причине будем парить мозги и себе, и людям, и отладчику, но не проинициализируем все (вылетать в них будем, но инициализировать ни за что) стеки и не сделаем при наличии мегабайтов тот-же IRQ/FIQ в десяток-другой раз больше.
DpInRock
Если начинаются неожиданные вещи, первым делом пририсовываем нолик к размеру стеков - всех подряд, а уж потом смотрим в программу.

На втором месте по частоте стоит выход за границы массива. Чтоб не лазить по программе - меняем местоположение массива или добавляем массив большого размера вслед за тестируемым. Ну, либо что тоже самое - увеличиваем размер исследуемого массива.
И смотрим результат.

defunct
Цитата(zltigo @ Aug 12 2010, 08:33) *
Это точно так-же очевидно по содержимому CPSR, он ведь не Exception Mode показывает, а вполне себе System Mode не правда-ли smile.gif?

CPSR проглядел когда смотрел. Таки да, показывает Sys.
Правда тогда такой вывод для DAbt тоже не совсем понятный. Для DABT - SYS LR - неактуален, там нужен Abort LR т.к именно он указывает точное место где произошел краш. Только не говорите, что оно у Вас само собой так и есть и это ясно из распечатки smile.gif
(то что там PC нарисован я вижу, только мне было бы намного понятней если бы его там не было, а вместо него был Abort LR)

Цитата(Атмег @ Aug 12 2010, 16:37) *
Смотрю по мар-файлу, неск Мб от последней переменной до начала стека

ОК.

Цитата
Структуры объявлены, но обращаюсь к полям стандартным образом, без особых хитростей...

Стуктуры могут быть с массивами в конце.
Например:

Код
{
    U8 Id;
    U8 Type;
    ...
    U32 Payload[ 64 ];
}


И в каком-нибудь обработчике может делаться совсем без хитростей:

Код
U32 *p = pCmd->Payload;

*p++ = xxx;
*p++ = xxx;
...
*p++ = xxx;


Без проверки на размер.


Цитата
malloc/calloc не использую, вроде не должно...

А партишины? Хоть какой-то намек на динамическую память в программе есть? Если используется сетевой стек неповерю, что нет динамического пула пакетов ;>

Цитата
Можете подробнее, что имеется в виду? Кроме обращения по указателю который равен 0.

Имеется в виду что некоторые поля структур не проинициализированы до того как начинают использоваться.
Например, есть тип пакета:

Код
typedef struct tagPACKET
{
     struct tagPACKET *pNext;
     ....
} TPACKET, *PPACKET;



Скажем вы создали пакет, а pNext не проинициализировали в NULL, и там будет какой-то мусор.
Затем вы этот пакет пропускаете через функцию которая обслуживает список пакетов связанный по pNext и получаете краш, т.к. pNext созданного пакета указывает черт знает куда...

Цитата
Ситуация слабоповторяемая, то сбоит, то не сбоит. То есть запускаю определенную функцию в программе, может на 3-й раз посыпаться, может на 10-й... Плата - отладка Атмеловская. Могут на такой плате быть проблемы из-за плохой разводки? Или это больше относится к своим платам?

Могут быть на любой плате (made in USA еще не гарантирует что с железом все ОК).
И даже если в железом все ОК, могут возникнуть проблемы из-за настроек SDRAM контроллера, несовместимых с реально впаянными чипами памяти в конкртеной ситуации.
zltigo
QUOTE (defunct @ Aug 16 2010, 04:34) *
Правда тогда такой вывод для DAbt тоже не совсем понятный. Для DABT - SYS LR - неактуален, там нужен Abort LR т.к именно он указывает точное место где произошел краш.

Точное место указывает PC (вычисляется из Abort LR, ибо несколько отличаются). Посему распечатка самого Abort LR, совсем без надобности, в отличии от Sys LR (прерванного режима), который есть хвостик для раскрутки того, как докатились до этого.
QUOTE
Только не говорите, что оно у Вас само собой так и есть и это ясно из распечатки smile.gif

Именно так и скажу, ибо много разных "идей" можно высказать, только начните, пожалуйста с мысли, что эта распечатка делалась для реальной работы по локализации, а не как набор цифирек smile.gif.
defunct
Цитата(zltigo @ Aug 16 2010, 09:49) *
Именно так и скажу, ибо много разных "идей" можно высказать, только начните, пожалуйста с мысли, что эта распечатка делалась для реальной работы по локализации, а не как набор цифирек smile.gif.

Вот одна из идей - выводить регистры двух режимов - Abort и Fault, без дублежа естессно. Это удобно читать, и практически нет оверхеда т.к. для всех исключений нужно сохранить всего лишь 1 регистр.
zltigo
QUOTE (defunct @ Aug 16 2010, 13:45) *
Удобно.

Абсолютно бесполезно. Зачем мне знать регисты обработчика Abort - это четкая и однозначная точка входа. Состояние его собственного банка регистров будет соответствовать тому, что осталось после предыдущего вылета в этот обработчик или мусору при первом входе. Что "удобно"?
defunct
Цитата(zltigo @ Aug 16 2010, 14:50) *
Что "удобно"?

Может быть я уже так привык, - мне удобно смотреть первым делом на Abort LR.
zltigo
QUOTE (defunct @ Aug 16 2010, 13:55) *
смотреть первым делом на Abort LR.

Для этого есть PC - он уже получен из Abort LR в соответствии с видом аборта. Вот это действительно удобно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.