Menu

#2629 int64 vs int confusion in the plugin header

None
closed-fixed
nobody
None
2023-09-04
2023-06-21
L L
No

When writing a gnuplot plugin i ran into a weird bug.

I ran the following commands in gnuplot:

import f(x) from "test.so:test"
print f(1.6)
print f(1)

As you should be able to verify, the result of RVAL is incorrect, because RVAL does not explicitly cast to int and rather converts the int64_t to a double. The int64_t however still contains data from the previous invocation (at least on my machine, in general the data is probably undefined), leading to confusingly wrong numbers.

This should be easily fixed by using

return (double)(int) v.v.int_val;

instead of

return (double) v.v.int_val;

More precisely the actual size of int that is used should be provided, i guess.

Here is a transcript of the results on my machine, including the version of gnuplot. I'm running on Debian.

    G N U P L O T
    Version 5.2 patchlevel 6    last modified 2019-01-01 

    Copyright (C) 1986-1993, 1998, 2004, 2007-2018
    Thomas Williams, Colin Kelley and many others
    [...]

gnuplot> import f(x) from "test.so:test"
gnuplot> print f(1.6)
1
type: 2
as int64: 4609884578576439706
as int:   -1717986918
as cmplx: 1.600000 + 0.000000i
via RVAL: 1.600000
via IVAL: 1
<undefined>
gnuplot> print f(1)
1
type: 1
as int64: 4609884575999459329
as int:   1
as cmplx: 1.599999 + 0.000000i
via RVAL: 4609884575999459328.000000
via IVAL: 1
<undefined>

The source test.c is included as attachement.

I'm sorry that I couldn't chekc, whether this bug is maybe already resolved somewhere, but i couldn't find a bug repot relating to plugins in general.

Please tell me if anything is unclear. Thanks a lot for your work.

1 Attachments

Discussion

  • Ethan Merritt

    Ethan Merritt - 2023-06-22

    I cannot reproduce your result with running gnuplot 5.2.6 and building your test case in the demo/plugin source directory for the 5.2.6 distribution. My test machine is x86, gcc version 12.3.0. I get the following output, which looks correct to me, and valgrind does not report any access to uninitialized memory.

    [gnuplot-5.2.6/demo/plugin] gnuplot_5.2.6 2629.bug
    1
    type: 2
    as int64: 2576980378
    as int:   -1717986918
    as cmplx: 1.600000 + 0.000000i
    via RVAL: 1.600000
    via IVAL: 1
    <undefined>
    1
    type: 1
    as int64: 1
    as int:   1
    as cmplx: 1.599999 + 0.000000i
    via RVAL: 1.000000
    via IVAL: 1
    <undefined>
    

    However I can reproduce your result in other versions of gnuplot starting with 5.4.0
    if the  enum DATA_TYPES as defined in gnuplot_plugin.h get out of sync with the
    corresponding enum DATA_TYPES in the main source directory .../src/gp_types.h
    This mis-match causes the print statement to chase down the wrong code path. Or, depending on how bad the mis-match is, it may segfault.

    So I wonder if it is possible that you are building your plugin from more recent source than the gnuplot 5.2.6 executable you are loading it from?   Clearly there should be some version check done by the plugin loading code, but sadly there is not. I will definitely file that as a "must fix" item for the next gnuplot release.

    And it is embarrassing that just such a mismatch exists throughout the 5.4 code base and persists in the development branch. So repairing the mis-match also becomes an immediate "must fix".

    Work-around
    You can hit this mis-match in source files if you are using the plugin demo source distributed with gnuplot versions 5.4.0 throuth 5.4.8. You can repair it by applying the patch below and rebuilding your plugin. You do not need to rebuild gnuplot itself.

    diff --git a/demo/plugin/gnuplot_plugin.h b/demo/plugin/gnuplot_plugin.h
    index 805a0a262..3dc04e50e 100644
    --- a/demo/plugin/gnuplot_plugin.h
    +++ b/demo/plugin/gnuplot_plugin.h
    @@ -9,6 +9,7 @@ enum DATA_TYPES {
         STRING,
         DATABLOCK,
         ARRAY,
    +    VOXELGRID,
         NOTDEFINED, /* exists, but value is currently undefined */
         INVALID_VALUE,  /* used only for error return by external functions */
    

    Summary:
    * I can't reproduce the problem in 5.2.6 .   I think the cast from int64_t->double is correct as written.
    * The problem as reported definitely does affect version 5.4 because the types in the source file gnuplot_plugin.h provided as an example do not match those in the executable built from 5.4 source. Oops.
    * The attached patch will repair the header file provided for the demo plugin in version 5.4
    * I will leave this bug open at least until a fix appears in the next gnuplot release.  

     

    Last edit: Ethan Merritt 2023-06-22
  • L L

    L L - 2023-06-22

    Thanks a lot for the quick response @sfeam. You are actually right, I did forget that my gnuplot_plugin.h was not actually coming from my version of gnuplot but I instead downloaded it from the github-repo (commit 109ab067724012d20b31663bc71664ad462a8eb4). However, gnuplot_plugin.h did actually not change since 5 years according to commit history, so that alone should not cause the issue.

    Also, applying your patch does change the printing of the returned value from <undefined> to NaN, but this wasn't my issue. This kind of makes sense though, since the problem is only dealing with the INTGR and CMPLX types, of which the values don't change (they are still 1 and 2 respectively).

    Another thought: I'm running on x86_64, so maybe the size of int is different on my machine compared to yours? Then it would make sense why you can't reproduce the bug, if for you the sizes "accidentally" coincides and for some reason it doesn't for me.

    Just for fun, I did explicitly check using sizeof and I did get:

    sizeof(int):    4
    sizeof(int64_t):    8
    

    My gcc version is gcc (Debian 8.3.0-6) 8.3.0 btw. Let me know if there are any more questions and how I can help you reproduce the bug.

    Finally, in case it helps anybody, I actually don't observe the bug anymore if I apply the attached patch (which is what I described in my OP). For me this implies that there is something weird going on there with the data types, else it wouldn't apparently solve the issue, right?

     

    Last edit: L L 2023-06-22
    • Ethan Merritt

      Ethan Merritt - 2023-06-22

      Gnuplot started using 64-bit integer variables in version 5.4. Your gnuplot executable for 5.2.6 almost certainly uses only 32-bit integers unless someone customized it to match 5.4 (possible, but why do that rather than just switching to 5.4?)

      So yeah, part of the header mismatch

      • version 5.2: src/gp_types.h and demo/plugin/gnuplot_plugin.h both define struct value to use 32-bit ints. (Actually the later simply #includes the former).
      • version 5.4: src/gp_types.h defines struct value to use type intgr_t, which is either 32- or 64- bit as detected at program build time by the content of the system header <inttypes.h>. demo/plugin/gnuplot_plugin.h explicitly uses int64_t, which is potentially a mis-match with a gnuplot executable built to use 32-bit ints.
      • version 6 (development version; not yet released): Currently the same state as 5.4 but I will fix this right away.

      So the version mismatch problem is actually worse than I thought, at least if you are mixing 32- and 64- bit header definitions for value.v.int_val.

      None of that really explains why you and I see different output when running your test case on 5.2.6 built with the 5.2.6 source. If you built the plugin with a plugin header from 5.4 that might explain it.

      By the way "github repo"?? The gnuplot source lives on SourceForge. If you found a repo on github I don't know who put it there or what exactly its provenance is. In the canonical gnuplot git repository there is no commit with the hash you quote.

       
  • Ethan Merritt

    Ethan Merritt - 2023-07-09
    • status: open --> pending-fixed
    • Group: -->
    • Priority: -->
     
  • Ethan Merritt

    Ethan Merritt - 2023-09-04
    • Status: pending-fixed --> closed-fixed
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.