Hello,
not being the maintainer I tried to reproduce the issue.

The message originates to freeing the std::string sSpecial in 
SpecClass::~SpecClass.

I could follow in debugger to the constructor and set a watch point.
That lead to a suspicious call to qsort.
For this reason the content of StarArray gets copied to temparray, sorted and
copied back to StarArray.

Replacing the c-like qstort with a c++-like std::sort avoids the crash.
(Patch should replicate old sort behaviour, but was just tested really short.)


Kind regards,
Bernhard



# coredumpctl gdb
Core was generated by `starplot'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51      ../sysdeps/unix/sysv/linux/raise.c: Datei oder Verzeichnis nicht 
gefunden.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007f5a67efd3fa in __GI_abort () at abort.c:89
#2  0x00007f5a67f39bd0 in __libc_message (do_abort=do_abort@entry=2, 
fmt=fmt@entry=0x7f5a6802ebd0 "*** Error in `%s': %s: 0x%s ***\n") at 
../sysdeps/posix/libc_fatal.c:175
#3  0x00007f5a67f3ff96 in malloc_printerr (action=3, str=0x7f5a6802b76d 
"free(): invalid pointer", ptr=<optimized out>, ar_ptr=<optimized out>) at 
malloc.c:5046
#4  0x00007f5a67f4078e in _int_free (av=0x7f5a68261b00 <main_arena>, 
p=0x5628d20d0260, have_lock=0) at malloc.c:3902
#5  0x00005628cfdb7601 in __gnu_cxx::new_allocator<char>::deallocate 
(this=0x5628d20d05c0, __p=<optimized out>) at 
/usr/include/c++/6/ext/new_allocator.h:110
#6  std::allocator_traits<std::allocator<char> >::deallocate (__a=..., 
__n=<optimized out>, __p=<optimized out>) at 
/usr/include/c++/6/bits/alloc_traits.h:442
#7  std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >::_M_destroy (__size=<optimized out>, 
this=0x5628d20d05c0) at /usr/include/c++/6/bits/basic_string.h:186
#8  std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >::_M_dispose (this=0x5628d20d05c0) at 
/usr/include/c++/6/bits/basic_string.h:181
#9  std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >::~basic_string (this=0x5628d20d05c0, 
__in_chrg=<optimized out>) at /usr/include/c++/6/bits/basic_string.h:558
#10 SpecClass::~SpecClass (this=0x5628d20d0588, __in_chrg=<optimized out>) at 
classes/specclass.h:29
#11 Star::~Star (this=0x5628d20d04e0, __in_chrg=<optimized out>) at 
classes/star.h:182
#12 sortable::~sortable (this=0x5628d20d04d8, __in_chrg=<optimized out>) at 
classes/stararray.cc:166
#13 StarArray::Sort (this=this@entry=0x5628d2086920) at classes/stararray.cc:205
#14 0x00005628cfdb8e59 in StarArray::SetRules (this=0x5628d2086920, rules=..., 
ruleschange=<optimized out>) at classes/stararray.cc:463
#15 0x00005628cfdaacf3 in redraw_all (changetype=<optimized out>) at 
gui/starplot.cc:105
#16 0x00005628cfd8d31d in main (argc=<optimized out>, argv=<optimized out>) at 
gui/starplot.cc:299




$ gdb -q --args starplot
...
(gdb) next
SpecClass::SpecClass (this=0x5555558e1528, s="") at classes/specclass.cc:57
57      SpecClass::SpecClass(const string &s)
(gdb) step
59        sSpecial("")
(gdb) next
61        if (! starstrings::isempty(sSpecstring))
(gdb) print &sSpecial
$7 = (std::__cxx11::string *) 0x5555558e1560
(gdb) print sSpecial._M_dataplus._M_p
$10 = (std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >::pointer) 0x5555558e1570 ""


Hardware watchpoint 11: ((std::__cxx11::string *) 
0x5555558e1560)->_M_dataplus._M_p

Old value = (std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >::pointer) 0x5555558e1570 ""
New value = (std::__cxx11::basic_string<char, std::char_traits<char>, 
std::allocator<char> >::pointer) 0x5555558e1c30 "m"
__memmove_sse2_unaligned_erms () at 
../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:399
399     ../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S: 
Datei oder Verzeichnis nicht gefunden.
(gdb) bt
#0  __memmove_sse2_unaligned_erms () at 
../sysdeps/x86_64/multiarch/../multiarch/memmove-vec-unaligned-erms.S:399
#1  0x00007ffff4b01ea0 in __GI___qsort_r (b=0x5555558e1478, n=7, s=288, 
cmp=<optimized out>, arg=<optimized out>) at msort.c:271
#2  0x000055555559636d in StarArray::Sort (this=this@entry=0x5555558979a0) at 
classes/stararray.cc:196
#3  0x0000555555597e59 in StarArray::SetRules (this=0x5555558979a0, rules=..., 
ruleschange=<optimized out>) at classes/stararray.cc:463
#4  0x0000555555589cf3 in redraw_all (changetype=<optimized out>) at 
gui/starplot.cc:105
#5  0x000055555556c31d in main (argc=<optimized out>, argv=<optimized out>) at 
gui/starplot.cc:299
From f603ddfa6a0eb6fc90bc8f14d0bb010efef975fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernha...@mailbox.org>
Date: Mon, 8 May 2017 23:05:28 +0200
Subject: Replace c-like qsort with c++-like std::sort.

https://bugs.debian.org/862065
---
 src/classes/stararray.cc | 49 +++++++++++++++++-------------------------------
 1 file changed, 17 insertions(+), 32 deletions(-)

diff --git a/src/classes/stararray.cc b/src/classes/stararray.cc
index 26cc6a0..72cc856 100644
--- a/src/classes/stararray.cc
+++ b/src/classes/stararray.cc
@@ -26,6 +26,7 @@
 
 #define NEED_FULL_NAMES
 #include "constellations.h"
+#include <algorithm>
 
 using std::string;
 using std::vector;
@@ -167,42 +168,26 @@ typedef struct {
 
 // Next, the function to compare for qsort().
 
-int compare_function(const void *p, const void *q)
-{
-  double x1 = ((const sortable *)p)->xposition;
-  double x2 = ((const sortable *)q)->xposition;
-  return (x1 - x2 >= 0.0) ? 1 : -1;
-}
+struct sort_class {
+  Rules &rules;
+  sort_class(Rules &r) : rules(r) {};
+  bool operator() (const Star &p, const Star &q)
+  {
+    SolidAngle orientation = rules.ChartOrientation;
+    Vector3 relativeLocation;
+    relativeLocation = p.GetStarXYZ() - rules.ChartLocation;
+    double x1 = relativeLocation.getX() * cos(orientation.getPhi()) + relativeLocation.getY() * sin(orientation.getPhi());
+    relativeLocation = q.GetStarXYZ() - rules.ChartLocation;
+    double x2 = relativeLocation.getX() * cos(orientation.getPhi()) + relativeLocation.getY() * sin(orientation.getPhi());
+    return (x1 - x2 >= 0.0) ? 1 : -1;
+  }
+};
 
-// Finally, the main function which calls qsort()
+// Finally, the main function which calls std::sort()
 
 void StarArray::Sort()
 {
-  size_t size = Array.size();
-  Vector3 relativeLocation;
-  SolidAngle orientation = ArrayRules.ChartOrientation;
-  sortable *temparray = new sortable[size];
-
-  // Make a temporary array for qsort(), consisting of "sortable" structs
-  //  which each contain a Star and a position in local coordinates.
-  for (size_t i = 0; i < size; i++) {
-    relativeLocation = Array[i].GetStarXYZ() - ArrayRules.ChartLocation;
-    temparray[i].xposition =
-      relativeLocation.getX() * cos(orientation.getPhi())
-      + relativeLocation.getY() * sin(orientation.getPhi());
-    temparray[i].star = Array[i];
-  }
-
-  qsort(temparray, size, sizeof(sortable), compare_function);
-
-  // Put the sorted temporary array back into the vector
-  Array.clear();
-  for (size_t i = 0; i < size; i++) {
-    temparray[i].star.SetPlace(i+1);    // label stars starting at 1
-    Array.push_back(temparray[i].star);
-  }
-
-  delete [] temparray;
+  std::sort(Array.begin(), Array.end(), sort_class(ArrayRules));
   return;
 }
 
-- 
2.11.0

Reply via email to