I seem to have fallen within the bounds of my Pointer-Fu and am seeking help (or some kind of head medicine).
Rough outline of the project: an integrated ARM video encoder board running Linux using a poorly documented poorly supported SDK. Among his extensive code sprawl is the huge heap that gSoap generates from some WSDL, and this causes a headache.
In terms of the huge data structure automatically created by gSoap, we have a place to write some data (or a place to write a pointer to the place where we wrote some data):
struct tt__IPAddress { enum tt__IPType Type; char *IPv4Address; char *IPv6Address; };
Then we have this code, which, in short, should write a string to the IPv4Address address:
DNSInformation->DNSManual = ((struct tt__IPAddress *)soap_malloc(soap, sizeof(struct tt__IPAddress))); DNSInformation->DNSManual->IPv4Address = (char **)soap_malloc(soap, sizeof(char *)); DNSInformation->DNSManual->IPv4Address[0] = (char *)soap_malloc(soap, sizeof(char) * LARGE_INFO_LENGTH);
dns_string is what you expect - something like "192.168.2.254". It correctly completes zero, the value of LARGE_INFO_LENGTH is something big (for example, 1024), so it has enough space for the string. I switched from strcpy () to strncpy () for security.
My background is a little embedded material (without OS, without using malloc ()), so I have a bit of persuasion problem. I understand what this code does. The code is automatically generated / part of the SDK, so this is not my creation, and it is not documented / commented out.
Here is what I think he is doing:
DNSInformation->DNSManual = ((struct tt__IPAddress *)soap_malloc(soap, sizeof(struct tt__IPAddress)));
Allocates a piece of RAM pointed to by DNSManual where the tt__IPAddress structure will exist.
DNSInformation->DNSManual->IPv4Address = (char **)soap_malloc(soap, sizeof(char *));
Allocates a piece of RAM pointed to by IPv4Address, where a pointer to a string containing the address will be written.
DNSInformation->DNSManual->IPv4Address[0] = (char *)soap_malloc(soap, sizeof(char) * LARGE_INFO_LENGTH);
Now it throws me a little, it looks like he is trying to allocate RAM to store the string that IPv4Address [0] will point to, except that it seems to me that they are trying to write a (32-bit) pointer to char, perhaps.
This code worked previously, however after some changes elsewhere it is now segfaults, always on or during strncpy ().
My questions are twofold:
- Can someone help me understand what is happening with mallocs / pointer-fu correctly?
- Any recommendations on how to track / debug this?
We do not have the ability to GDB with this setting, unfortunately - yes, I'm sure it is possible to configure, but for now let's assume that it is not practical for many lame and tiring reasons.
Currently, I have printf debugging scattered throughout the code, on virtually every line of this small fragment, and it always stops with SIGSEGV in the strncpy () line.
Edit to close how WhozCraig hit the answer:
For the most well-known reasons, gSoap changed the structure of tt__IPAddress, it may have run out of asterisks, but what it was in previous versions, and what it should be is:
struct tt__IPAddress { enum tt__IPType Type; char **IPv4Address; char **IPv6Address; };