std::string error
-
wrote on 21 Dec 2018, 18:43 last edited by
Not a Qt-specific problem, but...
void Message::buildSilenceAck() { string s; s.clear(); s.append(m_params->nvs->getIpAddr(IP_ADDRESS)); ... } string Nvs::getIpAddr(IpIdentifier addr) { string s; char *pAddr; s.clear(); if (addr == IP_ADDRESS) { pAddr = m_workingCopy->ipAddr; } ... s.append(pAddr); return s; }
gives me an exception at the s.append of the calling routine. The routine getIpAddr() is called by the same object, in seemingly the identical way, at several other points and they all work. Can someone see something I'm doing wrong with this one?
Thanks.
-
Not a Qt-specific problem, but...
void Message::buildSilenceAck() { string s; s.clear(); s.append(m_params->nvs->getIpAddr(IP_ADDRESS)); ... } string Nvs::getIpAddr(IpIdentifier addr) { string s; char *pAddr; s.clear(); if (addr == IP_ADDRESS) { pAddr = m_workingCopy->ipAddr; } ... s.append(pAddr); return s; }
gives me an exception at the s.append of the calling routine. The routine getIpAddr() is called by the same object, in seemingly the identical way, at several other points and they all work. Can someone see something I'm doing wrong with this one?
Thanks.
wrote on 21 Dec 2018, 19:09 last edited by JonBgives me an exception at the s.append of the calling routine.
I don't know the answer. But I also don't know whether it's when returning the result of
getIpAddr()
or passing it tos.append()
. While you wait for an expert, wouldn't it help to split that line into two separate statements so that we know which? -
wrote on 21 Dec 2018, 19:35 last edited by
Hi Jon - not sure how I'd split this out further. I tried an assign() instead of an append() as well as the assignment operator; they all fail. I'm fairly sure the called routine is good, as it's used extensively elsewhere in the program.
-
Hi Jon - not sure how I'd split this out further. I tried an assign() instead of an append() as well as the assignment operator; they all fail. I'm fairly sure the called routine is good, as it's used extensively elsewhere in the program.
Please provide information on the types involved, we are flying blind here. For example what is
IpIdentifier
and why are you assigning it to achar *
? -
wrote on 21 Dec 2018, 20:41 last edited by
Sure:
struct Tasks { EventGroupHandle_t tasksInitEventGroup; Nvs *nvs; Wifi *wifi; Worker *worker; ... }; Tasks *m_params; enum IpIdentifier { IP_ADDRESS, IP_GATEWAY, IP_NETMASK };
There's much more in Tasks, but I don't think that matters here.
-
Sure:
struct Tasks { EventGroupHandle_t tasksInitEventGroup; Nvs *nvs; Wifi *wifi; Worker *worker; ... }; Tasks *m_params; enum IpIdentifier { IP_ADDRESS, IP_GATEWAY, IP_NETMASK };
There's much more in Tasks, but I don't think that matters here.
And
m_workingCopy->ipAddr
is? I'm asking because that assignment looks really suspicious ... -
wrote on 21 Dec 2018, 20:51 last edited by
Oh: it's a pointer into flash memory, managed by the Nvs object.
struct DeviceDetails { uint8_t macAddr[6]; char serialNbr[NBR_CHARS_SER_NBR]; char devName[25]; uint8_t version[4]; char ssid[32]; char psk[64]; uint32_t ipConfig; char ipAddr[16]; char gateway[16]; char subnet[16]; char ntpServer[256]; char timeZone[32]; uint32_t ledDutyBattery; uint32_t ledDutyLine; uint32_t buzzerDuty; char label[NBR_CHARS_LABEL]; // will be checked at startup to verify NVS is programmed. }; DeviceDetails *m_workingCopy;
Again, I stress that the routine Nvs::getIpAddr() is called several times, with the same argument, and works fine everywhere but on this call.
-
Oh: it's a pointer into flash memory, managed by the Nvs object.
struct DeviceDetails { uint8_t macAddr[6]; char serialNbr[NBR_CHARS_SER_NBR]; char devName[25]; uint8_t version[4]; char ssid[32]; char psk[64]; uint32_t ipConfig; char ipAddr[16]; char gateway[16]; char subnet[16]; char ntpServer[256]; char timeZone[32]; uint32_t ledDutyBattery; uint32_t ledDutyLine; uint32_t buzzerDuty; char label[NBR_CHARS_LABEL]; // will be checked at startup to verify NVS is programmed. }; DeviceDetails *m_workingCopy;
Again, I stress that the routine Nvs::getIpAddr() is called several times, with the same argument, and works fine everywhere but on this call.
Okay, humor me for a second. Add
*pAddr = '\0'
before the append inNvs::getIpAddr
and see if that passes through.
Also a stack trace would be helpful and the exact exception you get (albeit I'm pretty sure it is not an exception per se). -
Hi Jon - not sure how I'd split this out further. I tried an assign() instead of an append() as well as the assignment operator; they all fail. I'm fairly sure the called routine is good, as it's used extensively elsewhere in the program.
wrote on 21 Dec 2018, 21:08 last edited by JonB@mzimmers
All I meant was splits.append(m_params->nvs->getIpAddr(IP_ADDRESS));
intostring s2(m_params->nvs->getIpAddr(IP_ADDRESS)); s.append(s2);
and tell us which of two lines raises the seg fault. Or a stack trace would have told us.
-
wrote on 21 Dec 2018, 22:02 last edited by mzimmers
Sorry for the delay; kshegunov's change was invalidating my addresses, and it took me a minute to realize what was happening. I changed the use of a pointer to a char array.
The error still occurs, and it happens at the assignment of string s2. This is running on an embedded system (running FreeRTOS) so there isn't much more information available.
EDIT: the error still occurs with kshegunov's change as well.
-
Sorry for the delay; kshegunov's change was invalidating my addresses, and it took me a minute to realize what was happening. I changed the use of a pointer to a char array.
The error still occurs, and it happens at the assignment of string s2. This is running on an embedded system (running FreeRTOS) so there isn't much more information available.
EDIT: the error still occurs with kshegunov's change as well.
wrote on 21 Dec 2018, 22:14 last edited by JonB@mzimmers
I know nothing about embedded & debugging (you can't give us a stack trace, can you?), but ingetIpAddr()
can you check the value ofs
immediately beforereturn s;
? I guess you're going to say it's OK then, but not as it gets returned to thestring s2(m_params->nvs->getIpAddr(IP_ADDRESS));
line? -
wrote on 21 Dec 2018, 22:27 last edited by
Yeah it looks fine in the Nvs routine:
ESP_LOGI(TAG, "getIpAddr(): returning \"%s\".", s.c_str()); vTaskDelay(10); return s;
Produces: I (26142) Nvs: getIpAddr(): returning "10.10.0.157".
-
Yeah it looks fine in the Nvs routine:
ESP_LOGI(TAG, "getIpAddr(): returning \"%s\".", s.c_str()); vTaskDelay(10); return s;
Produces: I (26142) Nvs: getIpAddr(): returning "10.10.0.157".
wrote on 21 Dec 2018, 22:30 last edited by JonB@mzimmers
So if you have debug like that, try to debug out the result fromm_params->nvs->getIpAddr(IP_ADDRESS));
in the caller? You're saying doing that raises exception? (BTW, do we get any details about the exception, I don't think you've said?) -
wrote on 21 Dec 2018, 22:36 last edited by
I can't output the result -- the error occurs as I'm trying to execute that line.
The error is known in the ESP32 world as a "Guru Meditation Error," and about all I get with my current debugging resources is this:
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled. Core 0 register dump: PC : 0x400e1bae PS : 0x00060230 A0 : 0x800dd03d A1 : 0x3ffebf80 A2 : 0x3fff17c4 A3 : 0x3fff0ef0 A4 : 0x3fff17c4 A5 : 0x3fff17c8 A6 : 0x00000000 A7 : 0x3fff0ef4 A8 : 0x00000000 A9 : 0x3ffebf30 A10 : 0x73d2d9f0 A11 : 0x73d2d9f0 A12 : 0x00000000 A13 : 0x0000001f A14 : 0x00000001 A15 : 0x00000005 SAR : 0x00000004 EXCCAUSE: 0x0000001c EXCVADDR: 0x00000010 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffffd Backtrace: 0x400e1bae:0x3ffebf80 0x400dd03a:0x3ffec040 0x400dd48d:0x3ffec290 0x400de12b:0x3ffec730 0x400de197:0x3ffec780
This is very likely what the Linux world refers to as a segmentation fault. Sorry I can't give better information; the debugging tools are the weak point of ESP32 development (IMO).
-
wrote on 22 Dec 2018, 00:06 last edited by
Hi, if you change to a static s, does it crash in the same way?
I.e change to:... string Nvs::getIpAddr(IpIdentifier addr) { static string s; char *pAddr; ...
-
Hi, if you change to a static s, does it crash in the same way?
I.e change to:... string Nvs::getIpAddr(IpIdentifier addr) { static string s; char *pAddr; ...
wrote on 22 Dec 2018, 00:26 last edited by@hskoglund yes it does. I eliminated the pointer in favor of a static char array, too; same result.
-
wrote on 22 Dec 2018, 01:50 last edited by hskoglund
Hmm maybe some of the pointers when calling are bad, if you log them, say something like:
void Message::buildSilenceAck() { string s; s.clear(); ESP_LOGI(TAG, "params = %d",(int) m_params); ESP_LOGI(TAG, "m_params->nvs = %d",(int) m_params->nvs); s.append(m_params->nvs->getIpAddr(IP_ADDRESS));
-
Hmm maybe some of the pointers when calling are bad, if you log them, say something like:
void Message::buildSilenceAck() { string s; s.clear(); ESP_LOGI(TAG, "params = %d",(int) m_params); ESP_LOGI(TAG, "m_params->nvs = %d",(int) m_params->nvs); s.append(m_params->nvs->getIpAddr(IP_ADDRESS));
wrote on 22 Dec 2018, 14:49 last edited by@hskoglund I've done that. The pointers seem fine, and the getIpAddr() routine executes successfully.
Weird problem, I know.
-
I can't output the result -- the error occurs as I'm trying to execute that line.
The error is known in the ESP32 world as a "Guru Meditation Error," and about all I get with my current debugging resources is this:
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled. Core 0 register dump: PC : 0x400e1bae PS : 0x00060230 A0 : 0x800dd03d A1 : 0x3ffebf80 A2 : 0x3fff17c4 A3 : 0x3fff0ef0 A4 : 0x3fff17c4 A5 : 0x3fff17c8 A6 : 0x00000000 A7 : 0x3fff0ef4 A8 : 0x00000000 A9 : 0x3ffebf30 A10 : 0x73d2d9f0 A11 : 0x73d2d9f0 A12 : 0x00000000 A13 : 0x0000001f A14 : 0x00000001 A15 : 0x00000005 SAR : 0x00000004 EXCCAUSE: 0x0000001c EXCVADDR: 0x00000010 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffffd Backtrace: 0x400e1bae:0x3ffebf80 0x400dd03a:0x3ffec040 0x400dd48d:0x3ffec290 0x400de12b:0x3ffec730 0x400de197:0x3ffec780
This is very likely what the Linux world refers to as a segmentation fault. Sorry I can't give better information; the debugging tools are the weak point of ESP32 development (IMO).
@mzimmers said in std::string error:
This is very likely what the Linux world refers to as a segmentation fault.
More like kernel panic, looking at the dump. Ordinary segfaults are handled by the kernel and don't usually dump the CPU registers. Are you sure you have enough memory on that device? One'd observe a similar thing on desktop if swapping is disabled and there's a syscall that can't free up memory (or the memory is corrupt at the point of the system call). Funnily I currently get similar dumps, but that's because my CPU is buggy.
-
@mzimmers said in std::string error:
This is very likely what the Linux world refers to as a segmentation fault.
More like kernel panic, looking at the dump. Ordinary segfaults are handled by the kernel and don't usually dump the CPU registers. Are you sure you have enough memory on that device? One'd observe a similar thing on desktop if swapping is disabled and there's a syscall that can't free up memory (or the memory is corrupt at the point of the system call). Funnily I currently get similar dumps, but that's because my CPU is buggy.
PS.
A quick look here (see error code 28) leads me to believe you have dereferencing of an invalid pointer (or a call to a function through an invalid address) due toEXCVADDR
holding nonsense; so I'm back to my original assumption. It's going to be hard without debug info to trace this down, but could you try to build this application in debug mode so at least you can get a more human(e) backtrace?
1/27