|
Применение буферов больше 256 байт глючит sprintf, Камень stm32L476 |
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 37)
|
Aug 22 2017, 21:06
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Димон Безпарольный @ Aug 22 2017, 23:44)  Как это узнать? Традиционный способ такой: 1. Заполняем выделенную под стек память каким-нибудь паттерном (хоть бы и однобайтовым) 2. Вызываем интересующую процедуру 3. Смотрим, сколько памяти было "затерто"
|
|
|
|
|
Aug 22 2017, 21:18
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Димон Безпарольный @ Aug 22 2017, 23:44)  Как это узнать? Это надо не узнавать. А задавать. У себя в исходниках. Если конечно писали их Вы.... Цитата(aaarrr @ Aug 23 2017, 00:06)  3. Смотрим, сколько памяти было "затерто" В некоторых случаях наблюдал как ..printf из IAR-овской библиотеки использовал до немного больше 256 байт стека. Но это не при каждом вызове. Обычно - намного меньше. Так что "просто вызвать и посмотреть сколько потрёт" - тут не всегда сработает как надо.
|
|
|
|
|
Aug 22 2017, 21:20
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(aaarrr @ Aug 23 2017, 01:06)  Традиционный способ такой: 1. Заполняем выделенную под стек память каким-нибудь паттерном (хоть бы и однобайтовым) 2. Вызываем интересующую процедуру 3. Смотрим, сколько памяти было "затерто" Слишком сложно. Даже если смогу, как изменить размер?
|
|
|
|
|
Aug 22 2017, 21:29
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(jcxz @ Aug 23 2017, 00:18)  В некоторых случаях наблюдал как ..printf из IAR-овской библиотеки использовал до немного больше 256 байт стека. Но это не при каждом вызове. Обычно - намного меньше. Так что "просто вызвать и посмотреть сколько потрёт" - тут не всегда сработает как надо. Да форматированный ввод-вывод очень прожорлив. Смотреть, естественно, наиболее навороченные вызовы. Цитата(Димон Безпарольный @ Aug 23 2017, 00:20)  Слишком сложно. Несколько строк кода. Цитата(Димон Безпарольный @ Aug 23 2017, 00:20)  Даже если смогу, как изменить размер? Этот момент лучше выяснять задолго до введения нескольких буферов по 400 байт. Кстати, Цитата(Димон Безпарольный @ Aug 22 2017, 23:03)  Буфер char buf[400]; и подаю я туда байты. buf - не локальный часом?
|
|
|
|
|
Aug 22 2017, 22:02
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Димон Безпарольный @ Aug 23 2017, 00:43)  Похоже. У меня в sprintf строка в 290байт. Как это ограничение обойти? 1. Увеличить размер стека И еще постараться: 2. Не держать локальные буферы по полкилобайта 3. Не формировать sprintf'ом строки по 290 байт Это весьма расточительно, если всей памяти десятки килобайт.
|
|
|
|
|
Aug 22 2017, 22:11
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
1. Буду благодарен если намекнете как. 2,3 Что делать если надо сформировать строку: Цитата { "d" : {"deviceid":"<deviceid>","param5":"<dw>","param6":"<fullw> ",”param7”:”<kk>”,”param8”:”<diff>”,”param9”:”<maxt>” ,”param11”:”<mint>”,”param12”:”<msisdn>”,”param13”:”<imei>”,”param14”:”<mac>”,”param15”:”<ccid>”,”param16”:”<rmod>”,”param17”:”<ssid>”,”param18”:”<lin>”,,”param19”:”<uptime>”}} Бред конечно - но не я диктую моду...
|
|
|
|
|
Aug 22 2017, 22:53
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Димон Безпарольный @ Aug 23 2017, 01:11)  1. Буду благодарен если намекнете как. Даже намекнуть не могу, так как это зависит от используемого инструментария, структуры проекта и т.п., и по-хорошему должно быть известно только вам. Посмотрите документацию на компилятор, там наверняка описан некий традиционный способ установки размера стека. Сравните с тем, что имеете в своем проекте и внесите коррективы. Димон, складывается впечатление, что вы пытаетесь собрать что-то монструозное, но при этом стараетесь обходить стороной фундаментальные основы. Не получится так  Цитата(Димон Безпарольный @ Aug 23 2017, 01:11)  2,3 Что делать если надо сформировать строку: Разделить её на кучу мелких по числу param.
|
|
|
|
|
Aug 23 2017, 05:29
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(jcxz @ Aug 23 2017, 03:00)  Надо начать с вопроса: "А зачем её формировать в этом буфере"? И можно ли без этого обойтись? Я вот тоже сейчас например в текущем проекте распарсиваю и формирую "модные" JSON-сообщения в несколько кБ (а возможно вырастут до сотен кБ), обходясь буферами в десятки-сотни байт. Без каких-либо проблем. Парсить можно разбивая строку. Но это отправляемая строка. Она целиком должна быть запихнута в сериализатор и далее на отправку. Представить не могу как частями это сделать. Заказчик очень хочет чтобы эта кишка не разбивалась.
|
|
|
|
|
Aug 23 2017, 07:24
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Димон Безпарольный @ Aug 23 2017, 08:29)  Парсить можно разбивая строку. Но это отправляемая строка. Она целиком должна быть запихнута в сериализатор и далее на отправку. Представить не могу как частями это сделать. Вот точно так же можно и отправляемую строку по частям напечатать. Я именно так и делаю. Писал выше. У меня строки размером до десятка кБ (а будут много больше). И печатают они в Ethernet-кадры, размер которых 576 байт Цитата(Димон Безпарольный @ Aug 23 2017, 09:04)  Согласен. Но буфер должен быть единым. Т.е. больше 256 байт. Нет. Если включить голову, то печатать можно окнами через тот же ..printf. И кучу тоже не использую - печать сразу в Ethernet-кадры.
|
|
|
|
|
Aug 23 2017, 07:39
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(scifi @ Aug 23 2017, 11:27)  Я правильно понял, что ТС не выяснил, сколько у него стека, и сколько его расходуется? И не планирует этим заниматься? Если так, помочь тут нечем, сушите вёсла. Ковырялся. Пока не получилось. Методику ищу, изучаю. Не факт что осилю. й Цитата(jcxz @ Aug 23 2017, 11:24)  И кучу тоже не использую - печать сразу в Ethernet-кадры. Она сериализатором по частям не обрабатывается. Т.е. можно и свой сериализатор написать. Но боюсь времени не хватит.
|
|
|
|
|
Aug 23 2017, 13:12
|
Частый гость
 
Группа: Участник
Сообщений: 161
Регистрация: 29-09-10
Пользователь №: 59 816

|
Есть полезная штука по крайней мере у Кейла: При компиляции опасные функции обрамляются ватермарком и при его повреждении - вызывается специальная функция. http://www.keil.com/support/man/docs/armcc...59124940593.htm
|
|
|
|
|
Aug 23 2017, 15:04
|
Частый гость
 
Группа: Участник
Сообщений: 169
Регистрация: 31-08-05
Из: New York
Пользователь №: 8 118

|
Если компилятор - IAR, то там есть встроенная функция контроля переполнения стека.
--------------------
ASB
|
|
|
|
|
Aug 23 2017, 17:44
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Пытаюсь работать с ключом --protect_stack Вставил функцию: Код void *__stack_chk_guard;
void __stack_chk_fail(void) { } Но виснет при обращении к массивам.
Сообщение отредактировал Димон Безпарольный - Aug 23 2017, 17:45
|
|
|
|
|
Aug 24 2017, 02:16
|
Частый гость
 
Группа: Участник
Сообщений: 161
Регистрация: 29-09-10
Пользователь №: 59 816

|
Цитата(jcxz @ Aug 24 2017, 01:27)  Малоэффективно. Вот пример перед глазами - случай автора топика: выставили ватермарк на 200 ниже SP перед входом в функцию, а автор взял и выделил в функции 400, (т.е. - начало этого массива оказалось на 200 байт ниже ватермарка) и напечатал в этот буфер скажем 150 байт - ватермарк остался нетронутым, а стек переполнился и затёр соседние данные (или они его). Эффективно как раз. У автора действительно тяжелый случай, но он явно выпаливается по внешним признакам. А --protect_stack как раз хорошо помогает, когда выделили для разных задач много маленьких буферов и потом в результате ошибки (не хватило пару байт потому что пролюбили пробел например) при печати в буфер портится соседнее значение, причем не каждый раз. И вот тут такое исключение чрезвычайно полезно. У меня раз такая ошибка в релизное ПО ушла. Одного чара в буфере не хватило.
|
|
|
|
|
Aug 24 2017, 05:57
|
Частый гость
 
Группа: Участник
Сообщений: 161
Регистрация: 29-09-10
Пользователь №: 59 816

|
Цитата(Димон Безпарольный @ Aug 24 2017, 00:44)  Пытаюсь работать с ключом --protect_stack Вставил функцию: Код void *__stack_chk_guard;
void __stack_chk_fail(void) { } Но виснет при обращении к массивам. Применяю так: Цитата void * __stack_chk_guard = (void *)(0xDEADBEEF);
void __stack_chk_fail(void) { bitset(global_error, 10); } http://infocenter.arm.com/help/index.jsp?t...qs/ka16747.html
Сообщение отредактировал Михась - Aug 24 2017, 05:59
|
|
|
|
|
Aug 24 2017, 08:35
|
Частый гость
 
Группа: Участник
Сообщений: 130
Регистрация: 26-06-06
Из: Березовский
Пользователь №: 18 355

|
Цитата(Димон Безпарольный @ Aug 23 2017, 03:11)  1. Буду благодарен если намекнете как. startup_stm32l476xx.s Цитата Stack_Size EQU 0x400;
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|