pleydell at supagro.inra.fr
2009-Sep-23 11:44 UTC
[Rd] Strange behaviour with global variable in C
I understand global variables can be a bad idea, but even so I would like to understand what is going on here... ### DESCRIPTION OF PROGRAM ### ...I have a strange bug on a global variable in some C code which I am compiling using $ MAKEFLAGS="CFLAGS=-g -O0" R CMD SHLIB myProgram.c the global variable in question is the log likelihood. In an old version of the program I initialized this as double loglik = -999999999999999 and in current versions I initialize this as double loglik = 0.0 and long sequences of 9s do not appear anywhere in the program now (I confirmed this using the grep command in bash) A function called update_loglik() exists in the file loglik.c and so myProgram.c includes the line #include "loglik.c" prior to the main() function. The first line in the function update_loglik() is loglik = 0.0; and then later in the function there is a loop containing the line loglik += some_value_corresponding_to_one_observation ### DESCRIPTION OF BUG ### If I add printf("%f",loglik) at the second line of update_loglik() it prints "0.0", BUT if I set a breakpoint here and execute (gdb) p loglik in gdb it prints -999999999999999 worse, the value being added to in the loop of update_loglik() is neither that being printed by printf nor that being printed by gdb. Moreover, if I put update_loglik() into a loop and printf the values I get itter 0 loglik -1242105.108051 itter 1 loglik -602880.293985 itter 2 loglik -590470.733006 itter 3 loglik -578061.172026 itter 4 loglik -565651.611046 itter 5 loglik -553242.050066 itter 6 loglik -540832.489086 itter 7 loglik -528422.928106 ### A CLUE ### This is clearly a pointer problem, in fact I believe gdb gives us a good clue (gdb) b loglik.c:100 Breakpoint 3 at 0xb7a2eba4: file loglik.c, line 100. (2 locations) (gdb) i b Num Type Disp Enb Address What 3 breakpoint keep y <MULTIPLE> 0xb7a2eba4 3.1 y 0xb7a2eba4 in update_loglik at loglik.c:100 3.2 y 0xb7a2895a in update_loglik at loglik.c:100 for some reason gdb associates this breakpoint with two addresses (line 100 by the way is where I try to set loglik to 0.0, described above) I should perhaps also add that my project is subject to bzr (bazaar) version control, so I wonder if this almost ghost-like resurrection of the -999999999999 is due to either gcc or gdb confusing information from current bzr versions with previous bzr versions. This resurrection occurs even after turning off the computer and rebooting so it shouldn't be to do with memory leaks. So why is gdb giving multiple addresses for a single line breakpoint and why gdb's ghostly resurrection of a long line of 9s even after a reboot? thanks David
pleydell at supagro.inra.fr
2009-Sep-23 12:06 UTC
[Rd] Strange behaviour with global variable in C
To answer my own question... I have two copies of my program 1) a working copy stored in $PROJECT/analysis/c 2) a packaged copy stored in $PROJECT/analysis/myPackage_1.0.2.tar.gz I have been running a script which does the following library(myPackage) load(myData) detach("package:myPackge") dyn.load("$PROJECT/analysis/c/myProgram.so") .C("main", ...) The "resurrection" comes from values of loglik set in the packaged version and not used in the working version. I had assumed detach would remove all traces of the package but this is clearly wrong. I wonder what over developers do when they want to switch from working with a packaged version to a working version without restarting R and without generating conflicts between the two? (Perhaps I can find that in documentation somewhere...) David