--with-blas/lapack being ignored

John W. Eaton jwe at bevo.che.wisc.edu
Thu Dec 6 12:35:43 CST 2007


On  6-Dec-2007, Ben Abbott wrote:

| However, regarding the strptime function ...
| 
| ---------------------------
| checking for strptime... yes
| [...]
| checking whether strptime is broken... no
| ---------------------------
| 
| I do not know if Apple has fixed this in Leopard or not. Configure  
| thinks so, but calls to strptime from octave produces a crash.
| 
| Running from gdb, I obtained the following.
| 
| ---------------------------
| octave:1> strptime ('09/13', '%m/%d')
| . done
| 
| Program received signal EXC_BAD_ACCESS, Could not access memory.
| Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
| 0x9110f590 in strlen ()
| (gdb) where
| #0  0x9110f590 in strlen ()
| #1  0x019b9661 in octave_base_tm::init (this=0xbfffed50, p=0x0) at oct- 
| time.cc:307
| #2  0x019b97dd in octave_strptime::init (this=0xbfffed24,  
| str=@0xffffffff, fmt=@0xffffffff) at oct-time.cc:379

Are str and fmt really @0xffffffff?  That looks strange.

The octave_strptime::init function is

  void
  octave_strptime::init (const std::string& str, const std::string& fmt)
  {
    struct tm t;

    t.tm_sec = 0;
    t.tm_min = 0;
    t.tm_hour = 0;
    t.tm_mday = 0;
    t.tm_mon = -1;
    t.tm_year = INT_MIN;
    t.tm_wday = 0;
    t.tm_yday = 0;
    t.tm_isdst = 0;

  #if defined (HAVE_STRUCT_TM_TM_ZONE)
    char *ps = strsave ("");
    t.tm_zone = ps;
  #endif

    char *p = strsave (str.c_str ());

    char *q = oct_strptime (p, fmt.c_str (), &t);

    // Fill in wday and yday, but only if mday is valid and the mon and year
    // are filled in, avoiding issues with mktime and invalid dates.
    if (t.tm_mday != 0 && t.tm_mon >= 0 && t.tm_year != INT_MIN)
      {
	t.tm_isdst = -1;
	mktime (&t);
      }

    if (t.tm_mon < 0)
      t.tm_mon = 0;

    if (t.tm_year == INT_MIN)
      t.tm_year = 0;

    if (q)
      nchars = q - p + 1;
    else
      nchars = 0;

    delete [] p;

    octave_base_tm::init (&t);

  #if defined (HAVE_STRUCT_TM_TM_ZONE)
    delete [] ps;
  #endif
  }

and the octave_base_tm::init function is

  void
  octave_base_tm::init (void *p)
  {
    struct tm *t = static_cast<struct tm*> (p);

    tm_sec = t->tm_sec;
    tm_min = t->tm_min;
    tm_hour = t->tm_hour;
    tm_mday = t->tm_mday;
    tm_mon = t->tm_mon;
    tm_year = t->tm_year;
    tm_wday = t->tm_wday;
    tm_yday = t->tm_yday;
    tm_isdst = t->tm_isdst;

  #if defined (HAVE_STRUCT_TM_TM_ZONE)
    tm_zone = t->tm_zone;
  #elif defined (HAVE_TZNAME)
    if (t->tm_isdst == 0 || t->tm_isdst == 1)
      tm_zone = tzname[t->tm_isdst];
  #endif
  }

As I recall, the argument is void* instead of struct tm* to avoid
exposing that in the octave_base_tm interface.

Line 307 is

    tm_zone = t->tm_zone;

There is no call to strlen here, so I don't see how that happens.
Does struct tm on your system actually have a tm_zone field?  If not,
then why is HAVE_STRUCT_TM_TM_ZONE defined?  The check for this is
performed by the autoconf macro AC_STRUCT_TIMEZONE.

jwe


More information about the Bug-octave mailing list