Solaris/SPARC: SIGBUS in unittests/array_out.c

"Peter C. Norton" <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
Group, 

I'm no good at alignment issues, so I'm looking for help here.  I've
got a 64-bit build of freetds-0.83.dev.20100902:

nortonp@ssqa1 11:54 /tmp/freetds/src/odbc/unittests $ ./array_out
odbctest
--------

connection parameters:
server:   'SYBQA1'
user:     'sa'
password: '????'
database: 'tempdb'
use tempdb
CREATE TABLE #odbc_test(i INT, t TEXT)
INSERT INTO #odbc_test(i, t) VALUES(1, 'arow number 0')
INSERT INTO #odbc_test(i, t) VALUES(2, 'brow number 13')
INSERT INTO #odbc_test(i, t) VALUES(3, 'crow number 26')
INSERT INTO #odbc_test(i, t) VALUES(4, 'drow number 39')
INSERT INTO #odbc_test(i, t) VALUES(5, 'erow number 52')
INSERT INTO #odbc_test(i, t) VALUES(6, 'frow number 65')
INSERT INTO #odbc_test(i, t) VALUES(7, 'grow number 78')
INSERT INTO #odbc_test(i, t) VALUES(8, 'hrow number 91')
INSERT INTO #odbc_test(i, t) VALUES(9, 'irow number 104')
INSERT INTO #odbc_test(i, t) VALUES(10, 'jrow number 117')
test line 149
test line 153
test line 159
Bus Error (core dumped)

freetds/src/odbc/unittests $ /proj/lang/SunOS.5.sparc/studio-12.1/bin/dbx array_out core
For information about new features see `help changes'
To remove this message, put `dbxenv suppress_startup_message 7.8' in your .dbxrc
Reading array_out
core file header read successfully
[etc...]
t@1 (l@1) program terminated by signal BUS (invalid address alignment)
Current function is query_test
   69                   ID_LENS(i) = 0;
(dbx) where
current thread: t@1
=>[1] query_test(expected = 0x100004fd8 "S", expected_status = 0x100005140 "VVVVVVVVVV"), line 69 in "array_out.c"
  [2] main(argc = 1, argv = 0xffffffff7ffff758), line 160 in "array_out.c"

array_out.c looks like this:
     58 #define REC(f,n) (((char*)f)+rec_size*(n))
     59 #define DESCS(n) (rec ? (SQLCHAR*)REC(descs,n): (descs+(n)*desc_len))
     60 #define IDS(n) *(rec ? (SQLUINTEGER*)REC(ids,n) : &ids[n])
     61 #define ID_LENS(n) *(rec ? (SQLLEN*)REC(id_lens,n) : &id_lens[n])
     62 #define DESC_LENS(n) *(rec ? (SQLLEN*)REC(desc_lens,n) : &desc_lens[n])
     63
     64         processed = ARRAY_SIZE + 1;
     65         for (i = 0; i < ARRAY_SIZE; i++) {
     66                 statuses[i] = SQL_ROW_UPDATED;
     67                 IDS(i) = i * 132;
     68                 sprintf((char *) DESCS(i), "aaa");
>>>  69                 ID_LENS(i) = 0;
     70                 DESC_LENS(i) = -i;
     71         }
     72

The test has changed a bunch since 0.82, such that it doesn't compile
in 0.83 anymore, and I can't exactly reproduce our old 0.82 build
anymore (lots of other moving parts have moved on)...  I guess that
id_lens, being declared as follows:

        SQLLEN *id_lens, *desc_lens;

decomposes into:

typedef int             SQLINTEGER;

If I understand correctly, on 64-bit platforms the word size is 8
bytes, and empirically an int is 4 bytes and so is a (char *), so this
test is bound to cause an unaligned access on the second access, where
it's trying to access (id_lens[i] << 16) (unless I've got the
endianness backwards, please forgive me if so).

What's the right fix on this test?  Is there a macro to check for
alignment and cleverly return the desired byte, something fancier than
the code here: http://forums.sun.com/thread.jspa?threadID=5341322 ?

Thanks,

-Peter
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.