Opened 9 years ago

Closed 8 years ago

Last modified 8 years ago

#9224 closed Bugs (worksforme)

rapidxml, memory corruption in class memory_pool, private member m_static_memory; not threadsafe in multi-threaded process

Reported by: spacecabooie@… Owned by: Sebastian Redl
Milestone: To Be Determined Component: property_tree
Version: Boost 1.54.0 Severity: Showstopper
Keywords: rapidxml, memory_pool, allocate_node, m_static_memory, multi-threaded Cc:

Description

Symptom: Executing on a mips under VxWorks 6.8 (though not when executing on a PC under Windows 7, compiled under VSC++), a simple three-four branch deep XML <string, string> file of more than 10-12 lines in length causes a call to property_tree/read_xml(istream, pt) to fail with Signal 11 (Segmentation Fault).

Cause: Debugging analysis shows that the failure occurs due to memory_pool::allocate_node() returning an invalid node_type to its parser caller. The returned value should be identical to the value provided in the call, but instead of being 0, 1, 2, 4 (doc, data, etc.) as passed in at construction (placement new), the returned value may be 681123, or some other value invalid as a node type.

Debugging further, within allocate_node(), by repeatedly printing in succession (up to 6-7 times) the local value of node_type, one will observe that the value becomes invalid on the 3rd or 4th print. (There are no other instructions within this thread being executed between the printf statements.) Debugging even further, by repeatedly printing an an entire region of the m_static_memory array, from m_begin to m_ptr, one will observe significant portions of this entire region changing in value.

Thus, another thread is writing into this area. The threads within the process all share the memory reserved/partitioned to this process. However, should one not expect that the m_static_memory array will be declared on the stack, or that otherwise the m_static_memory array address space will be resolved by the linker to be occupied exclusively by memory_pool ?

Apparently not. Perhaps this design is only for single threaded applications.

Possible (non-optimal) solution: To resolve the memory overlap and resulting susceptibility to corruption, I moved the declaration of the private data member m_static_array outside of the memory_pool class, and in fact outside of all namespace encapsulation present in rapidxml.hpp; it is now a global variable.

This does not crash. But neither is it boost conforming.

Change History (3)

comment:1 by Sebastian Redl, 9 years ago

Status: newassigned

Can you show a minimal compilable example that, at least on your machine, exhibits this issue? Simple inspection of the code shows that read_xml_internal allocates the xml_document on the stack. xml_document inherits from (and thus embeds) the memory_pool, and the m_static_memory array is a normal member of that class. In other words, the pool *is* in fact on the stack, and no sharing should occur.

I'm inclined to say that this is a problem of your larger application, and not of PropertyTree.

However, there is another option: you're saying MIPS, so I assume that you're talking about a machine with very limited memory, and also very little protection. This static array, by default, occupies 64k of stack space. Is it possible that you're simply observing a stack overflow that isn't properly diagnosed, and the static buffer overlays the stack of another thread?

Please try redefining BOOST_PROPERTY_TREE_RAPIDXML_STATIC_POOL_SIZE to a smaller value in your project and see if that fixes the problem.

comment:2 by Sebastian Redl, 8 years ago

Resolution: worksforme
Status: assignedclosed

comment:3 by anonymous, 8 years ago

I think you may want to look at this again - I'm running into some kind of memory issue and will try to get a valgrind log attached.

Note: See TracTickets for help on using tickets.