Outside address error while reading xml

I get weird segfault when using libxml to parse a file. This code worked earlier when I compiled it as a 32-bit application. I changed it to a 64-bit application and stopped working.

The seg error appears in "if (xmlStrcmp (cur-> name, (const xmlChar *)" servers "))"

cur-> name is const xmlChar *, and it points to the address where its limits are indicated. But when I debug and move to this memory location, this data is correct.

int XmlGetServers() { xmlDocPtr doc; xmlNodePtr cur; doc = xmlParseFile("Pin.xml"); if (doc == NULL) { std::cout << "\n Pin.xml not parsed successfully." << std::endl; return -1; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { std::cout << "\n Pin.xml is empty document." << std::endl; xmlFreeDoc(doc); return -1; } if (xmlStrcmp(cur->name, (const xmlChar *) "servers")) { std::cout << "\n ERROR: Pin.xml of the wrong type, root node != servers." << std::endl; xmlFreeDoc(doc); return -1; } } 

Before initializing cur, the name parameter

 Name : name Details:0xed11f72000007fff <Address 0xed11f72000007fff out of bounds> 

After cur is initialized, the name parameter

 Name : name Details:0x64c43000000000 <Address 0x64c43000000000 out of bounds> 

XML file reference

 <?xml version="1.0"?> <servers> <server_info> <server_name>Server1</server_name> <server_ip>127.0.0.1</server_ip> <server_data_port>9000</server_data_port> </server_info> <server_info> <server_name>Server2</server_name> <server_ip>127.0.0.1</server_ip> <server_data_port>9001</server_data_port> </server_info> </servers> 

System:

OS: Redhat Enterprise Linux 6.4 64-bit

GCC: 4.4.7-3

: libxml2-2.7.6-8.el6_3.4.x86_64

+5
source share
2 answers

The problem was that we used #pragma pack (1) in our code, which means that bools in DOMParser are packed up to 1 byte, while Xerces are not #pragma pack and get standard 4 byte packing.

0
source

I took your code as is and added:

 #include <libxml/parser.h> #include <iostream> 

then renamed the function to main () and compiled it on x86-64 Fedora 22 with libxml2 2.9.2

The resulting code worked successfully using a sample file, without segfaults. Even valgrind did not detect a memory access violation. As evidence, the resulting shortened strace log looks like this:

 stat("Pin.xml", {st_mode=S_IFREG|0644, st_size=362, ...}) = 0 stat("Pin.xml", {st_mode=S_IFREG|0644, st_size=362, ...}) = 0 stat("Pin.xml", {st_mode=S_IFREG|0644, st_size=362, ...}) = 0 open("Pin.xml", O_RDONLY) = 3 lseek(3, 0, SEEK_CUR) = 0 read(3, "<?xml version=\"1.0\"?>\n\n<servers>\n\n<server_info>\n\n <server_name>Server1</server_name>\n\n <server_ip>127.0.0.1</server_ip> \n\n <server_data_port>9000</server_data_port> \n\n</server_info>\n\n<server_info>\n\n <server_name>Server2</server_name> \n\n <ser"..., 8192) = 362 read(3, "", 7830) = 0 getcwd("/tmp", 1024) = 5 close(3) = 0 exit_group(0) = ? +++ exited with 0 +++ 

Although this is Fedora with slightly new libxml2 and gcc, this difference does not matter. The answer here is that there is nothing wrong with the code shown here. I see nothing wrong with that.

But this is obviously part of a much larger application, and your memory corruption occurs in some other part of your application, and it only appears when the execution of your application reaches that part.

The thing about C ++ is that just because of a code malfunction at a certain point does this not mean that this particular line of code is a problem. It’s not easy to come up with a simple example:

 #include <iostream> #include <cstring> int main() { char foo[3]; strcpy(foo, "FoobarbazXXXXXXXXXXXXXXXXXXXXXX"); for (int i=0; i<100; i++) std::cout << i << std::endl; return 0; } 

Here the error is explicitly found on the strcpy line. But the code will work very well and print 100 numbers from 0 to 99 and crash when main () returns. But obviously, "return 0" is not where the error is.

This is similar to what happens with your application. At some point, incorrect memory corruption occurs that does not significantly affect code execution until your code tries to parse your XML file.

Welcome to C ++.

+17
source

Source: https://habr.com/ru/post/1234139/


All Articles