tfussell / xlnt

:bar_chart: Cross-platform user-friendly xlsx library for C++11+
Other
1.5k stars 423 forks source link

Sample error #72

Closed sukoi26 closed 8 years ago

sukoi26 commented 8 years ago

Hello, After compiling the library under Linux, with no errors, i try the sample : ~/dvp/xlnt/samples$ g++ -std=c++14 -Ixlnt/include -Lxlnt/lib -lxlnt sample.cpp -o sample

I received this error:

GNU gdb (Debian 7.11.1-2) 7.11.1 Reading symbols from ./sample...done. (gdb) r Starting program: ~/dvp/xlnt/samples/sample terminate called after throwing an instance of 'std::out_of_range' what(): _Map_base::at

Program received signal SIGABRT, Aborted. 0x00007ffff6960fdf in raise () from /lib/x86_64-linux-gnu/libc.so.6 (gdb) bt

0 0x00007ffff6960fdf in raise () from /lib/x86_64-linux-gnu/libc.so.6

1 0x00007ffff696240a in abort () from /lib/x86_64-linux-gnu/libc.so.6

2 0x00007ffff727804d in __gnu_cxx::__verbose_terminate_handler() ()

from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

3 0x00007ffff7276016 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

4 0x00007ffff7276061 in std::terminate() ()

from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

5 0x00007ffff7276279 in __cxa_throw ()

from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

6 0x00007ffff729e50f in std::__throw_out_of_range(char const*) ()

from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

7 0x00007ffff789f843 in std::detail::_Map_base<xlnt::column_t, std::pair<xlnt::column_t const, xlnt::detail::cell_impl>, std::allocator<std::pair<xlnt::column_t const, xlnt::detail::cell_impl> >, std::detail::_Select1st, std::equal_toxlnt::column_t, std::hashxlnt::column_t, std::detail::_Mod_range_hashing, std::detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::at(xlnt::column_t const&)

() from /usr/local/lib/libxlnt.so.0.9

8 0x00007ffff789d3a3 in std::unordered_map<xlnt::column_t, xlnt::detail::cell_impl, std::hash, std::equal_toxlnt::column_t, std::allocator<std::pair<xlnt::column_t const, xlnt::detail::cell_impl> > >::at(xlnt::column_t const&) () from /usr/local/lib/libxlnt.so.0.9

9 0x00007ffff7894515 in xlnt::worksheet::get_cell(xlnt::cell_reference const&)`

` const () from /usr/local/lib/libxlnt.so.0.9

10 0x00007ffff7889d7b in xlnt::const_cell_iterator::operator*() const ()

from /usr/local/lib/libxlnt.so.0.9

11 0x00007ffff7938268 in xlnt::detail::xlsx_producer::write_shared_string_table(xlnt::relationship const&) () from /usr/local/lib/libxlnt.so.0.9

12 0x00007ffff7933c5a in xlnt::detail::xlsx_producer::write_workbook(xlnt::relationship const&) () from /usr/local/lib/libxlnt.so.0.9

13 0x00007ffff792544e in xlnt::detail::xlsx_producer::populate_archive() ()

from /usr/local/lib/libxlnt.so.0.9

14 0x00007ffff7924d24 in xlnt::detail::xlsx_producer::write(xlnt::path const&)

() from /usr/local/lib/libxlnt.so.0.9

15 0x00007ffff784e68e in xlnt::workbook::save(xlnt::path const&) const ()

from /usr/local/lib/libxlnt.so.0.9

16 0x00007ffff784e5a5 in xlnt::workbook::save(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&) const ()

from /usr/local/lib/libxlnt.so.0.9

17 0x00000000004010cd in main ()

at ~dvp/xlnt/samples/data/sample/main.cpp:12
yekm commented 8 years ago

Same here. Some nice example:

#include <xlnt/xlnt.hpp>

int main(int argc, const char *argv[])
{
    xlnt::workbook wb;
    auto ws1 = wb.get_active_sheet();
    ws1[xlnt::cell_reference(1, 1)].set_value("abc"); // (2,1), for example, works fine
    ws1[xlnt::cell_reference(2, 2)].set_value("def");
    wb.save("test_crash.xlsx");
    return 0;
}
(gdb) catch throw
Catchpoint 1 (throw)
(gdb) r
Starting program: /home/yekm/src/odesk/csv2xslx_regex/src/a.out

Catchpoint 1 (exception thrown), __cxxabiv1::__cxa_throw (obj=obj@entry=0x7cb190, tinfo=0x7ffff7dcca98 <typeinfo for std::out_of_range>, dest=0x7ffff7af6df0 <std::out_of_range::~out_of_range()>)
    at /build/gcc-multilib/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc:62
62      /build/gcc-multilib/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc: No such file or directory.
(gdb) bt
#0  __cxxabiv1::__cxa_throw (obj=obj@entry=0x7cb190, tinfo=0x7ffff7dcca98 <typeinfo for std::out_of_range>, dest=0x7ffff7af6df0 <std::out_of_range::~out_of_range()>)
    at /build/gcc-multilib/src/gcc/libstdc++-v3/libsupc++/eh_throw.cc:62
#1  0x00007ffff7b0adef in std::__throw_out_of_range (__s=0x52177c "_Map_base::at") at /build/gcc-multilib/src/gcc/libstdc++-v3/src/c++11/functexcept.cc:90
#2  0x000000000045ab27 in std::__detail::_Map_base<xlnt::column_t, std::pair<xlnt::column_t const, xlnt::detail::cell_impl>, std::allocator<std::pair<xlnt::column_t const, xlnt::detail::cell_impl> >, std::__detail::_Select1st, std::equal_to<xlnt::column_t>, std::hash<xlnt::column_t>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>::at (this=0x7afd20, __k=...) at /usr/include/c++/6.2.1/bits/hashtable_policy.h:644
#3  0x00000000004594fb in std::unordered_map<xlnt::column_t, xlnt::detail::cell_impl, std::hash<xlnt::column_t>, std::equal_to<xlnt::column_t>, std::allocator<std::pair<xlnt::column_t const, xlnt::detail::cell_impl> > >::at (this=0x7afd20, __k=...) at /usr/include/c++/6.2.1/bits/unordered_map.h:921
#4  0x0000000000455563 in xlnt::worksheet::get_cell (this=0x7fffffffb750, reference=...) at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/worksheet/worksheet.cpp:363
#5  0x0000000000451569 in xlnt::const_cell_iterator::operator* (this=0x7fffffffb750) at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/worksheet/const_cell_iterator.cpp:94
#6  0x000000000049fcb6 in xlnt::detail::xlsx_producer::write_shared_string_table (this=0x7fffffffe4a0, rel=...) at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/detail/xlsx_producer.cpp:616
#7  0x000000000049e0fc in xlnt::detail::xlsx_producer::write_workbook (this=0x7fffffffe4a0, rel=...) at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/detail/xlsx_producer.cpp:528
#8  0x0000000000497b3a in xlnt::detail::xlsx_producer::populate_archive (this=0x7fffffffe4a0) at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/detail/xlsx_producer.cpp:113
#9  0x00000000004977bc in xlnt::detail::xlsx_producer::write (this=0x7fffffffe4a0, destination=...) at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/detail/xlsx_producer.cpp:65
#10 0x000000000042fd3c in xlnt::workbook::save (this=0x7fffffffe730, filename=...) at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/workbook/workbook.cpp:675
#11 0x000000000042fcc1 in xlnt::workbook::save (this=0x7fffffffe730, filename="test_crash.xlsx") at /home/yekm/src/odesk/csv2xslx_regex/xlnt/source/workbook/workbook.cpp:669
#12 0x00000000004063a2 in main ()
tfussell commented 8 years ago

I guess it's time that I update the outdated samples since they seem to be misguiding potential users. I'll have some commits in the next few days to fix this.

yekm commented 8 years ago

Some usage guides would be nice.

Also, there is another crash, somewhat unrelated, I guess. It can't read files with xlnt::datetime-s, that was previously created by xlnt iteslf.

#include <xlnt/xlnt.hpp>

int main(int argc, const char *argv[])
{
    xlnt::workbook wb;
    auto ws1 = wb.get_active_sheet();
    ws1[xlnt::cell_reference(2, 1)].set_value("abc");
    ws1[xlnt::cell_reference(2, 2)].set_value("def");
    ws1[xlnt::cell_reference(2, 3)].set_value(xlnt::datetime(2016, 1, 1, 11, 11, 11));
    wb.save("test_crash.xlsx");
    xlnt::workbook wb2;
    wb2.load("test_crash.xlsx");
    return 0;
}
$ ./a.out 
terminate called after throwing an instance of 'xml::parsing'
  what():  styles.xml:3:4: error: start element 'numFmt' expected
Aborted (core dumped)
sukoi26 commented 8 years ago

on sample.cpp, the crash is on this line , if i comment is OK? ws.get_cell("B2").set_value("string data");

very strange, test OK ~/dvp/xlnt/build$ bin/xlnt.test Running cxxtest tests (278 tests)........................................................................................................................................................................................s.............................................................................................OK!

tfussell commented 8 years ago

There are a few separate issues here. As @yekm discovered (nice detective work!), iterating over the rows and columns in a workbook is sort of broken at the moment. This doesn't normally show up because iterating over a non-const workbook adds the cells to the internal cell map as it looks them up (see http://en.cppreference.com/w/cpp/container/unordered_map/operator_at). During writing, the workbook is const and the loop to count the number of strings to write to the shared string table was looking up non-existent cells. This particular problem during writing is fixed with commit b83cf64 and the code in the comment now works as expected. More work needs to be done to fix cell iteration.

The crash in sample.cpp mentioned by @sukoi26 was caused by bad XML writing/reading for the shared strings file. This is fixed with a commit I will make tonight. This commit will include significant improvements to the build system and supporting files. samples/sample.cpp will be updated and I will begin compiling samples in Travis/AppVeyor to ensure they are always in a working state. After "git pull", it will be necessary to "git submodule init && git submodule update" to get botan which is the new encryption library used for reading password-protected workbooks. Certain builds may fail during this commit but they will be resolved in short time.