Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bug in stplugin.h? (Stata Plugin Interface v3)

    On at least some systems, the Stata Plugin Interface uses 32-bit signed integers in places where it should use 64-bit integers. For instance, stplugin.h (see https://www.stata.com/plugins/#sect8) defines ST_int as int. Given that Stata observations can range from 0 to 20 billion (though c(max_N_theory) shows north of a trillion?) it seems the plugin interface should explicitly use 64-bit integers. Otherwise you get overflow errors on some systems:

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdarg.h>
    #include <stdint.h>
    #include "stplugin.h"
    
    #define BUF_MAX 4096
    void sf_printf (const char *fmt, ...);
    
    STDLL stata_call(int argc, char *argv[])
    {
        ST_retcode rc;
    
        rc = SF_vstore(1, SF_in2(), (ST_double) 1.0);
        sf_printf("status 1 = %d \n", rc);
    
        if ( rc ) {
            rc = SF_vstore(1, INT32_MAX, (ST_double) 2.0);
            sf_printf("status 2 = %d \n", rc);
    
            rc = SF_vstore(1, 2165097182, (ST_double) 3.0);
            sf_printf("status 3 = %d \n", rc);
    
            sf_printf("sizeof(ST_int) = %d\n", sizeof(ST_int));
            sf_printf("SF_in2()       = %d \n", SF_in2());
        }
    
        return (rc);
    }
    
    void sf_printf (const char *fmt, ...)
    {
        va_list args;
        va_start (args, fmt);
        char buf[BUF_MAX];
        vsprintf (buf, fmt, args);
        SF_display (buf);
        va_end (args);
    }
    And then (on Stata 15/MP for unix):
    Code:
    . !gcc -Wall -shared -DSYSTEM=OPUNIX -fPIC stplugin.c test.c -o test.plugin
    
    
    . program test, plugin using("test.plugin")
    
    . set obs 3
    number of observations (_N) was 0, now 3
    
    . gen x = .
    (3 missing values generated)
    
    . plugin call test x
    status 1 = 0  
    
    . l
    
        +---+
        | x |
        |---|
     1. | . |
     2. | . |
     3. | 1 |
        +---+
    
    .  
    . set obs 2165097182
    number of observations (_N) was 3, now 2,165,097,182
    
    . plugin call test x
    status 1 = 498  
    status 2 = 0  
    status 3 = 498  
    sizeof(ST_int) = 4
    SF_in2()       = -2129870114  
    r(498);
    
    . l in `=2^31 - 1'
    
               +---+
               | x |
               |---|
    2147483647. | 2 |
               +---+
    
    . l in `=_N'
    
               +---+
               | x |
               |---|
    2165097182. | . |
               +---+
    The second run gives an error not just because SF_in2() overflowed, but because ST_vstore does not seem to accept values past 2^31-1 (we can see that the last value of x is left unchanged, but not the value where obs = largest signed integer). I've tried changing every "int" in stplugin.h to "int64_t" but it hasn't helped, so I think the issue might not just be with stplugin.h, but with the underlying types as well.
Working...
X