[Ovmsdev] Stack sizes

Mark Webb-Johnson mark at webb-johnson.net
Wed Dec 6 11:11:30 HKT 2017


Very strange.

Changing the way Transmit() is called in OvmsServerV2::ProcessCommand(), by making it one call rather than each time in the switch/case statements, reduces stack to 672 bytes (was 1,900++) for that function.

The issue seems to be all those temporary std::string objects created by things like this:

if (vehicle->CommandHomelink(atoi(payload.substr(sep+1).c_str())) == OvmsVehicle::Success) k = 0;

Getting rid of all those, and changing payload to char*, brings OvmsServerV2::ProcessCommand() down to 336 bytes. Much better. But, still looking for those remaining bytes...

It seems that we have to be very careful with switch/case statements and local variables.

Regards, Mark.

> On 6 Dec 2017, at 9:05 AM, Mark Webb-Johnson <mark at webb-johnson.net> wrote:
> 
> It seems that we are continuously having to increase stack sizes. So, I went on a hunt to try to find out why…
> 
> I put a abort() in the metrics_list() function. Spun up a wifi connection, an ovms_server_v2 connection, and then 'cmd.pl 7 'metric list’. Here are the stack frame details:
> 
> (gdb) bt
> #0  0x40088dac in invoke_abort () at /Users/mark/esp/esp-idf/components/esp32/./panic.c:125
> #1  0x40088e7a in abort () at /Users/mark/esp/esp-idf/components/esp32/./panic.c:134
> #2  0x40123765 in metrics_list (verbosity=1024, writer=0x3fff6b94, cmd=0x3ffb6584, argc=0, argv=0x0)
>     at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_metrics.cpp:49
> #3  0x4011e1a9 in OvmsCommand::Execute (this=0x3ffb6584, verbosity=1024, writer=0x3fff6b94, argc=0, argv=0x0)
>     at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:257
> #4  0x4011e29d in OvmsCommand::Execute (this=0x3ffb64f0, verbosity=1024, writer=0x3fff6b94, argc=1, argv=0x3fff54d4)
>     at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:302
> #5  0x4011e290 in OvmsCommand::Execute (this=0x3ffc3cc4 <MyCommandApp+4>, verbosity=1024, writer=0x3fff6b94, argc=2, argv=0x3fff54d4)
>     at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:298
> #6  0x4011e2c4 in OvmsCommandApp::Execute (this=0x3ffc3cc0 <MyCommandApp>, verbosity=1024, writer=0x3fff6b94, argc=2, argv=0x3fff54d0)
>     at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:507
> #7  0x401292a8 in Execute (rl=0x3fff6b9c, argc=2, argv=0x3fff54d0) at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_shell.cpp:47
> #8  0x400db2cd in new_line_handler (pThis=0x3fff6b9c) at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/microrl/./microrl.c:626
> #9  0x400db333 in microrl_insert_char (pThis=0x3fff6b9c, ch=10) at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/microrl/./microrl.c:674
> #10 0x401292f7 in OvmsShell::ProcessChar (this=0x3fff6b94, c=10 '\n') at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_shell.cpp:62
> #11 0x400f57d8 in OvmsServerV2::ProcessCommand (this=0x3fff433c, payload=<optimized out>)
>     at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:411
> #12 0x400f9b54 in OvmsServerV2::ProcessServerMsg (this=0x3fff433c) at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:336
> #13 0x400fa263 in OvmsServerV2::ServerTask (this=0x3fff433c) at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:244
> #14 0x400f4325 in OvmsServer_task (pvParameters=0x3fff433c) at /Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server/./ovms_server.cpp:43
> 
> Stack level 0, frame at 0x3fff53f0:
>  pc = 0x40088dac in invoke_abort (/Users/mark/esp/esp-idf/components/esp32/./panic.c:125); saved pc = 0x40088e7a
>  called by frame at 0x3fff5410
>  source language c.
>  Arglist at 0x3fff53d0, args:
>  Locals at 0x3fff53d0, Previous frame's sp is 0x3fff53f0
>  Saved registers:
>   ar56 at 0x3fff53c0, ar57 at 0x3fff53c4, ar58 at 0x3fff53c8, ar59 at 0x3fff53cc, ar60 at 0x3fff53f0, ar61 at 0x3fff53f4, ar62 at 0x3fff53f8, ar63 at 0x3fff53fc, a0 at 0x3fff53c0, a2 at 0x3fff53c8,
>   a3 at 0x3fff53cc, a4 at 0x3fff53f0, a5 at 0x3fff53f4, a6 at 0x3fff53f8, a7 at 0x3fff53fc
> 
> Stack level 1, frame at 0x3fff5410:
>  pc = 0x40088e7a in abort (/Users/mark/esp/esp-idf/components/esp32/./panic.c:134); saved pc = 0x40123765
>  called by frame at 0x3fff5430, caller of frame at 0x3fff53f0
>  source language c.
>  Arglist at 0x3fff53f0, args:
>  Locals at 0x3fff53f0, Previous frame's sp is 0x3fff5410
>  Saved registers:
>   ar48 at 0x3fff53e0, ar49 at 0x3fff53e4, ar50 at 0x3fff53e8, ar51 at 0x3fff53ec, ar52 at 0x3fff5410, ar53 at 0x3fff5414, ar54 at 0x3fff5418, ar55 at 0x3fff541c, a0 at 0x3fff53e0, a2 at 0x3fff53e8,
>   a3 at 0x3fff53ec, a4 at 0x3fff5410, a5 at 0x3fff5414, a6 at 0x3fff5418, a7 at 0x3fff541c
> 
> Stack level 2, frame at 0x3fff5430:
>  pc = 0x40123765 in metrics_list (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_metrics.cpp:49); saved pc = 0x4011e1a9
>  called by frame at 0x3fff5450, caller of frame at 0x3fff5410
>  source language c++.
>  Arglist at 0x3fff5410, args: verbosity=1024, writer=0x3fff6b94, cmd=0x3ffb6584, argc=0, argv=0x0
>  Locals at 0x3fff5410, Previous frame's sp is 0x3fff5430
>  Saved registers:
>   ar40 at 0x3fff5400, ar41 at 0x3fff5404, ar42 at 0x3fff5408, ar43 at 0x3fff540c, ar44 at 0x3fff5430, ar45 at 0x3fff5434, ar46 at 0x3fff5438, ar47 at 0x3fff543c, a0 at 0x3fff5400, a2 at 0x3fff5408,
>   a3 at 0x3fff540c, a4 at 0x3fff5430, a5 at 0x3fff5434, a6 at 0x3fff5438, a7 at 0x3fff543c
> 
> Stack level 3, frame at 0x3fff5450:
>  pc = 0x4011e1a9 in OvmsCommand::Execute (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:257); saved pc = 0x4011e29d
>  called by frame at 0x3fff5470, caller of frame at 0x3fff5430
>  source language c++.
>  Arglist at 0x3fff5430, args: this=0x3ffb6584, verbosity=1024, writer=0x3fff6b94, argc=0, argv=0x0
>  Locals at 0x3fff5430, Previous frame's sp is 0x3fff5450
>  Saved registers:
>   ar32 at 0x3fff5420, ar33 at 0x3fff5424, ar34 at 0x3fff5428, ar35 at 0x3fff542c, ar36 at 0x3fff5450, ar37 at 0x3fff5454, ar38 at 0x3fff5458, ar39 at 0x3fff545c, a0 at 0x3fff5420, a2 at 0x3fff5428,
>   a3 at 0x3fff542c, a4 at 0x3fff5450, a5 at 0x3fff5454, a6 at 0x3fff5458, a7 at 0x3fff545c
> 
> Stack level 4, frame at 0x3fff5470:
>  pc = 0x4011e29d in OvmsCommand::Execute (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:302); saved pc = 0x4011e290
>  called by frame at 0x3fff5490, caller of frame at 0x3fff5450
>  source language c++.
>  Arglist at 0x3fff5450, args: this=0x3ffb64f0, verbosity=1024, writer=0x3fff6b94, argc=1, argv=0x3fff54d4
>  Locals at 0x3fff5450, Previous frame's sp is 0x3fff5470
>  Saved registers:
>   ar24 at 0x3fff5440, ar25 at 0x3fff5444, ar26 at 0x3fff5448, ar27 at 0x3fff544c, ar28 at 0x3fff5470, ar29 at 0x3fff5474, ar30 at 0x3fff5478, ar31 at 0x3fff547c, a0 at 0x3fff5440, a2 at 0x3fff5448,
>   a3 at 0x3fff544c, a4 at 0x3fff5470, a5 at 0x3fff5474, a6 at 0x3fff5478, a7 at 0x3fff547c
> 
> Stack level 5, frame at 0x3fff5490:
>  pc = 0x4011e290 in OvmsCommand::Execute (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:298); saved pc = 0x4011e2c4
>  called by frame at 0x3fff54b0, caller of frame at 0x3fff5470
>  source language c++.
>  Arglist at 0x3fff5470, args: this=0x3ffc3cc4 <MyCommandApp+4>, verbosity=1024, writer=0x3fff6b94, argc=2, argv=0x3fff54d4
>  Locals at 0x3fff5470, Previous frame's sp is 0x3fff5490
>  Saved registers:
>   ar16 at 0x3fff5460, ar17 at 0x3fff5464, ar18 at 0x3fff5468, ar19 at 0x3fff546c, ar20 at 0x3fff5490, ar21 at 0x3fff5494, ar22 at 0x3fff5498, ar23 at 0x3fff549c, a0 at 0x3fff5460, a2 at 0x3fff5468,
>   a3 at 0x3fff546c, a4 at 0x3fff5490, a5 at 0x3fff5494, a6 at 0x3fff5498, a7 at 0x3fff549c
> 
> Stack level 6, frame at 0x3fff54b0:
>  pc = 0x4011e2c4 in OvmsCommandApp::Execute (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_command.cpp:507); saved pc = 0x401292a8
>  called by frame at 0x3fff54d0, caller of frame at 0x3fff5490
>  source language c++.
>  Arglist at 0x3fff5490, args: this=0x3ffc3cc0 <MyCommandApp>, verbosity=1024, writer=0x3fff6b94, argc=2, argv=0x3fff54d0
>  Locals at 0x3fff5490, Previous frame's sp is 0x3fff54b0
>  Saved registers:
>   ar8 at 0x3fff5480, ar9 at 0x3fff5484, ar10 at 0x3fff5488, ar11 at 0x3fff548c, ar12 at 0x3fff54b0, ar13 at 0x3fff54b4, ar14 at 0x3fff54b8, ar15 at 0x3fff54bc, a0 at 0x3fff5480, a2 at 0x3fff5488,
>   a3 at 0x3fff548c, a4 at 0x3fff54b0, a5 at 0x3fff54b4, a6 at 0x3fff54b8, a7 at 0x3fff54bc
> 
> Stack level 7, frame at 0x3fff54d0:
>  pc = 0x401292a8 in Execute (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_shell.cpp:47); saved pc = 0x400db2cd
>  called by frame at 0x3fff5530, caller of frame at 0x3fff54b0
>  source language c++.
>  Arglist at 0x3fff54b0, args: rl=0x3fff6b9c, argc=2, argv=0x3fff54d0
>  Locals at 0x3fff54b0, Previous frame's sp is 0x3fff54d0
>  Saved registers:
>   ar0 at 0x3fff54a0, ar1 at 0x3fff54a4, ar2 at 0x3fff54a8, ar3 at 0x3fff54ac, ar4 at 0x3fff5510, ar5 at 0x3fff5514, ar6 at 0x3fff5518, ar7 at 0x3fff551c, a0 at 0x3fff54a0, a2 at 0x3fff54a8,
>   a3 at 0x3fff54ac, a4 at 0x3fff5510, a5 at 0x3fff5514, a6 at 0x3fff5518, a7 at 0x3fff551c
> 
> Stack level 8, frame at 0x3fff5530:
>  pc = 0x400db2cd in new_line_handler (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/microrl/./microrl.c:626); saved pc = 0x400db333
>  called by frame at 0x3fff5560, caller of frame at 0x3fff54d0
>  source language c.
>  Arglist at 0x3fff54d0, args: pThis=0x3fff6b9c
>  Locals at 0x3fff54d0, Previous frame's sp is 0x3fff5530
>  Saved registers:
>   ar56 at 0x3fff54c0, ar57 at 0x3fff54c4, ar58 at 0x3fff54c8, ar59 at 0x3fff54cc, ar60 at 0x3fff5540, ar61 at 0x3fff5544, ar62 at 0x3fff5548, ar63 at 0x3fff554c, a0 at 0x3fff54c0, a2 at 0x3fff54c8,
>   a3 at 0x3fff54cc, a4 at 0x3fff5540, a5 at 0x3fff5544, a6 at 0x3fff5548, a7 at 0x3fff554c
> 
> Stack level 9, frame at 0x3fff5560:
>  pc = 0x400db333 in microrl_insert_char (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/microrl/./microrl.c:674); saved pc = 0x401292f7
>  called by frame at 0x3fff5580, caller of frame at 0x3fff5530
>  source language c.
>  Arglist at 0x3fff5530, args: pThis=0x3fff6b9c, ch=10
>  Locals at 0x3fff5530, Previous frame's sp is 0x3fff5560
>  Saved registers:
>   ar48 at 0x3fff5520, ar49 at 0x3fff5524, ar50 at 0x3fff5528, ar51 at 0x3fff552c, ar52 at 0x3fff5560, ar53 at 0x3fff5564, ar54 at 0x3fff5568, ar55 at 0x3fff556c, a0 at 0x3fff5520, a2 at 0x3fff5528,
>   a3 at 0x3fff552c, a4 at 0x3fff5560, a5 at 0x3fff5564, a6 at 0x3fff5568, a7 at 0x3fff556c
> 
> Stack level 10, frame at 0x3fff5580:
>  pc = 0x401292f7 in OvmsShell::ProcessChar (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/main/./ovms_shell.cpp:62); saved pc = 0x400f57d8
>  called by frame at 0x3fff5e20, caller of frame at 0x3fff5560
>  source language c++.
>  Arglist at 0x3fff5560, args: this=0x3fff6b94, c=10 '\n'
>  Locals at 0x3fff5560, Previous frame's sp is 0x3fff5580
>  Saved registers:
>   ar40 at 0x3fff5550, ar41 at 0x3fff5554, ar42 at 0x3fff5558, ar43 at 0x3fff555c, ar44 at 0x3fff5e00, ar45 at 0x3fff5e04, ar46 at 0x3fff5e08, ar47 at 0x3fff5e0c, a0 at 0x3fff5550, a2 at 0x3fff5558,
>   a3 at 0x3fff555c, a4 at 0x3fff5e00, a5 at 0x3fff5e04, a6 at 0x3fff5e08, a7 at 0x3fff5e0c
> 
> Stack level 11, frame at 0x3fff5e20:
>  pc = 0x400f57d8 in OvmsServerV2::ProcessCommand (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:411); saved pc = 0x400f9b54
>  called by frame at 0x3fff5ee0, caller of frame at 0x3fff5580
>  source language c++.
>  Arglist at 0x3fff5580, args: this=0x3fff433c, payload=<optimized out>
>  Locals at 0x3fff5580, Previous frame's sp is 0x3fff5e20
>  Saved registers:
>   ar32 at 0x3fff5570, ar33 at 0x3fff5574, ar34 at 0x3fff5578, ar35 at 0x3fff557c, ar36 at 0x3fff5ec0, ar37 at 0x3fff5ec4, ar38 at 0x3fff5ec8, ar39 at 0x3fff5ecc, a0 at 0x3fff5570, a2 at 0x3fff5578,
>   a3 at 0x3fff557c, a4 at 0x3fff5ec0, a5 at 0x3fff5ec4, a6 at 0x3fff5ec8, a7 at 0x3fff5ecc
> 
> Stack level 12, frame at 0x3fff5ee0:
>  pc = 0x400f9b54 in OvmsServerV2::ProcessServerMsg (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:336);
>     saved pc = 0x400fa263
>  called by frame at 0x3fff5f80, caller of frame at 0x3fff5e20
>  source language c++.
>  Arglist at 0x3fff5e40, args: this=0x3fff433c
>  Locals at 0x3fff5e40, Previous frame's sp is 0x3fff5ee0
>  Saved registers:
>   ar24 at 0x3fff5e10, ar25 at 0x3fff5e14, ar26 at 0x3fff5e18, ar27 at 0x3fff5e1c, ar28 at 0x3fff5f60, ar29 at 0x3fff5f64, ar30 at 0x3fff5f68, ar31 at 0x3fff5f6c, a0 at 0x3fff5e10, a2 at 0x3fff5e18,
>   a3 at 0x3fff5e1c, a4 at 0x3fff5f60, a5 at 0x3fff5f64, a6 at 0x3fff5f68, a7 at 0x3fff5f6c
> 
> Stack level 13, frame at 0x3fff5f80:
>  pc = 0x400fa263 in OvmsServerV2::ServerTask (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:244); saved pc = 0x400f4325
>  called by frame at 0x0, caller of frame at 0x3fff5ee0
>  source language c++.
>  Arglist at 0x3fff5ee0, args: this=0x3fff433c
>  Locals at 0x3fff5ee0, Previous frame's sp is 0x3fff5f80
>  Saved registers:
>   ar16 at 0x3fff5ed0, ar17 at 0x3fff5ed4, ar18 at 0x3fff5ed8, ar19 at 0x3fff5edc, ar20 at 0x3fff5f80, ar21 at 0x3fff5f84, ar22 at 0x3fff5f88, ar23 at 0x3fff5f8c, a0 at 0x3fff5ed0, a2 at 0x3fff5ed8,
>   a3 at 0x3fff5edc, a4 at 0x3fff5f80, a5 at 0x3fff5f84, a6 at 0x3fff5f88, a7 at 0x3fff5f8c
> 
> Stack level 14, frame at 0x0:
>  pc = 0x400f4325 in OvmsServer_task (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server/./ovms_server.cpp:43); saved pc = 0x40000000
>  Outermost frame: outermost
>  caller of frame at 0x3fff5f80
>  source language c++.
>  Arglist at 0x3fff5f80, args: pvParameters=0x3fff433c
>  Locals at 0x3fff5f80, Previous frame's sp is 0x0
>  Saved registers:
>   ar16 at 0x3fff5f70, ar17 at 0x3fff5f74, ar18 at 0x3fff5f78, ar19 at 0x3fff5f7c, a0 at 0x3fff5f70, a2 at 0x3fff5f78, a3 at 0x3fff5f7c
> 
> Here are the stack frame pointers:
> 
> OvmsServer_task Stack level 14, frame at 0x0:
> OvmsServerV2::ServerTask Stack level 13, frame at 0x3fff5f80: 160 bytes
> OvmsServerV2::ProcessServerMsg Stack level 12, frame at 0x3fff5ee0: 192 bytes
> OvmsServerV2::ProcessCommand Stack level 11, frame at 0x3fff5e20: 2208 bytes
> OvmsShell::ProcessChar Stack level 10, frame at 0x3fff5580: 32 bytes
> microrl_insert_char Stack level 9, frame at 0x3fff5560: 48 bytes
> new_line_handler Stack level 8, frame at 0x3fff5530: 92 bytes
> Execute Stack level 7, frame at 0x3fff54d0: 32 bytes
> OvmsCommandApp::ExecuteStack level 6, frame at 0x3fff54b0: 32 bytes
> OvmsCommand::Execute Stack level 5, frame at 0x3fff5490: 32 bytes
> OvmsCommand::Execute Stack level 4, frame at 0x3fff5470: 32 bytes
> OvmsCommand::Execute Stack level 3, frame at 0x3fff5450: 32 bytes
> metrics_list Stack level 2, frame at 0x3fff5430: 32 bytes
> abort Stack level 1, frame at 0x3fff5410: 32 bytes
> invoke_abort Stack level 0, frame at 0x3fff53f0
> 
> That frame #11 stands out like a sore thumb. Here are the details:
> 
> (gdb) info frame
> Stack level 11, frame at 0x3fff5e20:
>  pc = 0x400f57d8 in OvmsServerV2::ProcessCommand (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:411); saved pc = 0x400f9b54
>  called by frame at 0x3fff5ee0, caller of frame at 0x3fff5580
>  source language c++.
>  Arglist at 0x3fff5580, args: this=0x3fff433c, payload=<optimized out>
>  Locals at 0x3fff5580, Previous frame's sp is 0x3fff5e20
>  Saved registers:
>   ar32 at 0x3fff5570, ar33 at 0x3fff5574, ar34 at 0x3fff5578, ar35 at 0x3fff557c, ar36 at 0x3fff5ec0, ar37 at 0x3fff5ec4, ar38 at 0x3fff5ec8, ar39 at 0x3fff5ecc, a0 at 0x3fff5570, a2 at 0x3fff5578,
>   a3 at 0x3fff557c, a4 at 0x3fff5ec0, a5 at 0x3fff5ec4, a6 at 0x3fff5ec8, a7 at 0x3fff5ecc
> 
> (gdb) info locals
> bs = 0x3fff6b94
> val = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
>     _M_p = 0x9c85f1ef '\377' <repeats 200 times>...}, _M_string_length = 2512534878, {_M_local_buf = "\377\377\377\377\063\234\351\347W\243\303*\242\004\000\017", _M_allocated_capacity = 4294967295}}
> command = <optimized out>
> sep = 1
> vehicle = 0x0
> buffer = {<std::basic_ostream<char, std::char_traits<char> >> = {<std::basic_ios<char, std::char_traits<char> >> = {<std::ios_base> = {
>         _vptr$ios_base = 0x3f4168bc <vtable for std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >+32>, static boolalpha = std::_S_boolalpha,
>         static dec = std::_S_dec, static fixed = std::_S_fixed, static hex = std::_S_hex, static internal = std::_S_internal, static left = std::_S_left, static oct = std::_S_oct,
>         static right = std::_S_right, static scientific = std::_S_scientific, static showbase = std::_S_showbase, static showpoint = std::_S_showpoint, static showpos = std::_S_showpos,
>         static skipws = std::_S_skipws, static unitbuf = std::_S_unitbuf, static uppercase = std::_S_uppercase, static adjustfield = std::_S_adjustfield, static basefield = std::_S_basefield,
>         static floatfield = std::_S_floatfield, static badbit = std::_S_badbit, static eofbit = std::_S_eofbit, static failbit = std::_S_failbit, static goodbit = std::_S_goodbit,
>         static app = std::_S_app, static ate = std::_S_ate, static binary = std::_S_bin, static in = std::_S_in, static out = std::_S_out, static trunc = std::_S_trunc, static beg = std::_S_beg,
>         static cur = std::_S_cur, static end = std::_S_end, _M_precision = 6, _M_width = 0, _M_flags = 4098, _M_exception = std::_S_goodbit, _M_streambuf_state = std::_S_goodbit, _M_callbacks = 0x0,
>         _M_word_zero = {_M_pword = 0x0, _M_iword = 0}, _M_local_word = {{_M_pword = 0x0, _M_iword = 0}, {_M_pword = 0x0, _M_iword = 0}, {_M_pword = 0x0, _M_iword = 0}, {_M_pword = 0x0, _M_iword = 0}, {
>             _M_pword = 0x0, _M_iword = 0}, {_M_pword = 0x0, _M_iword = 0}, {_M_pword = 0x0, _M_iword = 0}, {_M_pword = 0x0, _M_iword = 0}}, _M_word_size = 8, _M_word = 0x3fff5c84, _M_ios_locale = {
>           static none = 0, static ctype = 1, static numeric = 2, static collate = 4, static time = 8, static monetary = 16, static messages = 32, static all = 63,
>           _M_impl = 0x3ffc4c2c <(anonymous namespace)::c_locale_impl>, static _S_classic = 0x3ffc4c2c <(anonymous namespace)::c_locale_impl>,
>           static _S_global = 0x3ffc4c2c <(anonymous namespace)::c_locale_impl>, static _S_categories = <optimized out>, static _S_twinned_facets = 0x3f415488 <std::locale::_S_twinned_facets>}},
>       _M_tie = 0x0, _M_fill = 0 '\000', _M_fill_init = false, _M_streambuf = 0x3fff5c24, _M_ctype = 0x3ffc4878 <(anonymous namespace)::ctype_c>, _M_num_put =
>     0x3ffc4850 <(anonymous namespace)::num_put_c>, _M_num_get = 0x3ffc4858 <(anonymous namespace)::num_get_c>},
>     _vptr$basic_ostream = 0x3f4168a8 <vtable for std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >+12>},
>   _M_stringbuf = {<std::basic_streambuf<char, std::char_traits<char> >> = {
>       _vptr$basic_streambuf = 0x3f4167cc <vtable for std::__cxx11::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >+8>, _M_in_beg = 0x0, _M_in_cur = 0x0, _M_in_end = 0x0,
>       _M_out_beg = 0x0, _M_out_cur = 0x0, _M_out_end = 0x0, _M_buf_locale = {static none = 0, static ctype = 1, static numeric = 2, static collate = 4, static time = 8, static monetary = 16,
>         static messages = 32, static all = 63, _M_impl = 0x3ffc4c2c <(anonymous namespace)::c_locale_impl>, static _S_classic = 0x3ffc4c2c <(anonymous namespace)::c_locale_impl>,
>         static _S_global = 0x3ffc4c2c <(anonymous namespace)::c_locale_impl>, static _S_categories = <optimized out>, static _S_twinned_facets = 0x3f415488 <std::locale::_S_twinned_facets>}},
>     _M_mode = std::_S_out, _M_string = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>},
>         _M_p = 0x3fff5c50 ""}, _M_string_length = 0, {_M_local_buf = "\000\377\377\377y\031\b@\000\000\000\000\250\177\b@", _M_allocated_capacity = 4294967040}}}}
> 
> (gdb) info args
> this = 0x3fff433c
> payload = <optimized out>
> 
> Also frame #12:
> 
> (gdb) info frame
> Stack level 12, frame at 0x3fff5ee0:
>  pc = 0x400f9b54 in OvmsServerV2::ProcessServerMsg (/Users/mark/Documents/ovms/Open-Vehicle-Monitoring-System-3/vehicle/OVMS.V3/components/ovms_server_v2/src/ovms_server_v2.cpp:336);
>     saved pc = 0x400fa263
>  called by frame at 0x3fff5f80, caller of frame at 0x3fff5e20
>  source language c++.
>  Arglist at 0x3fff5e40, args: this=0x3fff433c
>  Locals at 0x3fff5e40, Previous frame's sp is 0x3fff5ee0
>  Saved registers:
>   ar24 at 0x3fff5e10, ar25 at 0x3fff5e14, ar26 at 0x3fff5e18, ar27 at 0x3fff5e1c, ar28 at 0x3fff5f60, ar29 at 0x3fff5f64, ar30 at 0x3fff5f68, ar31 at 0x3fff5f6c, a0 at 0x3fff5e10, a2 at 0x3fff5e18,
>   a3 at 0x3fff5e1c, a4 at 0x3fff5f60, a5 at 0x3fff5f64, a6 at 0x3fff5f68, a7 at 0x3fff5f6c
> 
> (gdb) info locals
> line = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x3fff68a8 "MP-0 C7,metric list"},
>   _M_string_length = 19, {_M_local_buf = "\023\000\000\000\000\000\000\000\270^\377?\270^\377?", _M_allocated_capacity = 19}}
> b = 0x3fff5e20 "MP-0 C7,metric list"
> len = <optimized out>
> code = 67 'C'
> payload = {static npos = <optimized out>, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x3fff5ea8 "7,metric list"},
>   _M_string_length = 13, {_M_local_buf = "7,metric list\000\000", _M_allocated_capacity = 1701653559}}
> 
> (gdb) info args
> this = 0x3fff433c
> 
> Here is the size of that std::ostringstream:
> 
>   std::ostringstream buffer;
>   ESP_LOGI(TAG,"std::ostringstream buffer is %d bytes",sizeof(buffer));
> 
> I (41478) ovms-server-v2: std::ostringstream buffer is 200 bytes
> 
> 200 bytes, not 2,000 bytes, so something else is going on here. Anyway, changing it to a dynamically (new/delete) allocated buffer, drops stack usage of that frame to 1,824 bytes (was 2,208 so that is 384 bytes saved).
> 
> That uint8_t b[line.length()+1] in OvmsServerV2::ProcessServerMsg() is also nasty - it will grow stack usage depending on line length. So, we’ll fix that as well. 192 bytes -> 160 bytes.
> 
> Things to note:
> 
> Each stack call is a minimum of 32 bytes. Not so bad, really - we’d need to nest calls 32 deep to get 1KB stack usage.
> Local variables are scary. They can be unexpectedly large. Best to new/free them, to guarantee just 4 bytes each.
> The OvmsCommand::Execute recursion I was worried about is not so bad. Probably 100 bytes of stack, or so, for most commands. We could improve that by getting rid of the recursion (it is elegant, but not strictly necessary), but it doesn’t seem to be a big win.
> I’m still looking for 150+ bytes in OvmsServerV2::ProcessServerMsg(), and 1,900+ bytes in OvmsServerV2::ProcessCommand(). Those would be big.
> 
> Regards, Mark.
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openvehicles.com/pipermail/ovmsdev/attachments/20171206/92ca3ae2/attachment.htm>


More information about the OvmsDev mailing list