funny Code behaviour - c++

I am trying to connect to a mysql database with the following code in my main() function.
MYSQL *connect = mysql_init(NULL);
which works fine and I get a pointer value returned.
I have created another c++ file with a function in it as below
int Newl_connection(FileHandler& pProcLog)
{
MYSQL *connect = mysql_init(NULL);
return 0;
}
compiling and Linking fine, I have made several calls to the same line of code in the main function (as a test) and all ok but when I run the code it fails at the line in the Newl_connection() function.
I have stripped the Newl_connection to as basic as possible, and included all the headers from the file containing Main() into the file containing Newl_connection() function.
THe compiler error I recieve is
Program received signal SIGABRT, Aborted.
0x00007ffff6bc6428 in __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Attempt to use a type name as an expression.
Attempt to use a type name as an expression
Attempt to use a type name as an expression. appears for all instance calls, but the call in the Newl_connection() function is terminal.
I have tried removing all other instances in main() and still get the same problem.
Why should code work in one place but behave differently in another?
Help would be appreciated I am at my witts end on this one.

According to your function header:
int Newl_connection(FileHandler& pProcLog)
you should call it with a valid object of type FileHandler.
Setting the variable name as pProcLog makes me think you want to use it as a pointer to an object. Then the declaration should be:
int Newl_connection(FileHandler* pProcLog)
This way you could call the function safe with a null value as argument.

Related

netcdf fortran how to retrieve the total number of global attributes

I am trying to figure out how to discover how many global attributes a netcdf file has. By doing so, I am using the call:
status = nf90_Inquire_Variable(ncid, NF90_GLOBAL, nAtts=natts)
In order to test it I created a simple example. First, it creates a file with global attributes and then it tries to read it:
...
! create the file
call check( nf90_create("test.nc", NF90_NETCDF4, ncid) )
call check( nf90_put_att(ncid, NF90_GLOBAL, "date", "01/01/2021") )
call check( nf90_put_att(ncid, NF90_GLOBAL, "time", "00:00:00") )
call check( nf90_put_att(ncid, NF90_GLOBAL, "seconds", 1000) )
call check( nf90_close(ncid) )
! Read the file.
status = nf90_open("test.nc", NF90_NOWRITE, ncid)
call check(status)
! how many global attributes?
status = nf90_Inquire_Variable(ncid, NF90_GLOBAL, nAtts=natts)
call check(status)
! bye
status = nf90_close(ncid)
call check(status)
The netcdf file is properly created
netcdf simpletest {
// global attributes:
:date = "01/01/2021" ;
:time = "00:00:00" ;
:seconds = 1000 ;
}
But the following error shows up:
Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0x7f34c7156d01 in ???
#1 0x7f34c7155ed5 in ???
#2 0x7f34c6e2020f in ???
#3 0x7f34c749304e in nf_inq_var_
at /to/some/path/netcdf-fortran-4.5.1/fortran/nf_genvar.f90:181
#4 0x7f34c74ebedf in __netcdf_MOD_nf90_inquire_variable
at /to/some/path/netcdf-fortran-4.5.1/fortran/netcdf4_variables.f90:293
Violació de segment (s'ha bolcat la memòria)
GDB stops at:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7f5e04e in nf_inq_var (ncid=1, varid=0, name=..., xtype=1077936128, ndims=1073741824, dimids=..., natts=3, _name=256)
at nf_genvar.f90:181
warning: Source file is more recent than executable.
181 dimids(1:ndims) = cdimids(ndims:1:-1)+1
So it seems to me I am doing something wrong. Am I using the original call in a way it is meant to?
If not, how could it be done? By reading the netcdf fortran documentation I am not able to find it.
I am using the following versions of:
gfortran 9.3
zlib 1.2.11
hdf5 1.10.5
netcdf-c 4.7.1
netcdf-fortran 4.5.1
Edit:
As suggested in one of the comments below, I did a couple of minimum reproducible examples with different choices as I am a bit confused regarding the options.
I also created a new fortran bindings to the nc_inq_natts call but renamed to nf90_inq_natts.
a fortran file which creates and read a netcdf file
a c file which creates a netcdf file with 1 global attribute
a fortran file which only read the file from point 2
All files are compiled in debug mode when running.
The following outputs came up:
Create a new file (C):
*** SUCCESS writing example file simple_xy.nc!
Only read netcdf file (fortran):
nf90_inquire_variable ...
NetCDF: Variable not found
nf90_inq_natts ...
NetCDF: Not a valid ID
Global attributes (inquire_variable(GLOBAL)): 1788528357 <-- not working
Global attributes (inq_natts): 260315136 <-- not working
Create and read file (fortran):
nf90_inquire_variable ...
nf90_inq_natts ...
NetCDF: Not a valid ID
Global attributes (inquire_variable(GLOBAL)): 3 <-- it works
Global attributes (inq_natts): 1256308480 <-- not working
The results:
I cannot reproduce the error I first mentioned. :-/
nc_inq_natts does not seems to work when mixed with Fortran (NetCDF: Not a valid ID)
nf90_inquire_variables seems to work when the netcdf file is created in the same file (?). Regarding documention it is not supposed to happen.
C example taken from github works as expected
From a thread on the netcdfgroup mail list found by googling:
A variable ID of NF90_GLOBAL is explicitly allowed with
nf90_inquire_attribute, but not with nf90_inquire_variable. The intended
functions for discovering global attributes are nf90_inquire and
nf90_inquire_attribute. With a bit of study, the F90 documentation on this
topic seems rather clear to me.
Attempting to use nf90_inquire_variable for global attributes is a
mis-application of that function. Furthermore, that function is probably
returning the appropriate error code in this case, as documented: "The
variable ID is invalid for the specified netCDF dataset."
i.e., change the function you call to nf90_inquire_attribute.

LLVM how to get callsite file name and line number

I am very very new to LLVM, and it's my first time to write C++
I need to find several function info related to LLVM CallSite, however, I have checked the source code here: LLVM CallSite Source Code
Still don't know where to get call site file name (eg. CallSite is in example.c file), call site line number (eg. at line 18 in the whole program)
Do you know how can I get call site file name and line number?
You can get this information by retrieving debug information from the called function. The algorithm is the following:
You need to get underlying called value, which is a function.
Then you need to get debug information attached to that function.
The debug information should contain everything you need.
Here is a code that should do the job (I didn't run it though):
CallSite cs = ...;
if (!cs.isCall() && !cs.isInvoke()) {
break;
}
Function *calledFunction = dyn_cast<Function>(cs.getCalledValue());
if (!calledFunction) {
break;
}
MDNode *metadata = calledFunction->getMetadata(0);
if (!metadata) {
break;
}
DILocation *debugLocation = dyn_cast<DILocation>(metadata);
if (debugLocation) {
debugLocation->getFilename();
debugLocation->getLine();
}
Please note the breaks. They are here to show that every step may not succeed, so you should be ready to handle all such cases.

Invoke another exe and get value

How to invoke another .exe and then get the returned value?
Here's the code that I tried and failed:
int main() {
int ret = (int) system("Test.exe");
}
In this code ret holds Zero value but it's should be able to container Test.exe's value.
system returns OS return code, not the console output. There is no portable way to get the output of the program you run (#Rapptz correction, system calls are implementation-defined).
Much easier (at least for some basic usage) would be to redirect output of said .exe to a file, and then read that file.

Sporadic segfault in c++ python extension

I have a python object which accesses and downloads some text via HTTP.
I'm running this python object, and processing that text, using a c++ code.
I.e.
/* CPPCode.cxx */
int main(...) {
for(int i = 0; i < numURLs; i++) {
// Python method returns a string
PyObject *pyValue = PyObject_CallMethod(pyObjectInstance, pyFunctionName, par1, par2....);
string valString = PyString_AsString(pHistValue);
// ... process string ...
}
}
/* PyObject.py */
class PyClass:
def PyFunction(...):
try: urlSock = urllib.urlopen(urlName)
except ...
while(...) :
dataStr = urlSock.readline()
# do some basic string processing....
return dataStr
Most URLs work fine---the c++ code gets the proper string, I can process it, all is happy and well. A few particular URLs which look (basically) the same as the others on a browser, lead to a segfault in the PyString_AsString() method:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00000000000000b2
0x000000010007716d in PyString_AsString ()
If I print out the string that should be returned by the python method ('dataStr' in the pseudo-code above), it looks fine! I have no idea what could be causing this problem---any tips on how to procede would be appreciated!
Thanks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SOLUTION:
The template code I was using had a call to
Py_DECREF(pyValue)
before I called
PyString_AsString(pyValue)
Why it was being deallocated for certain particular function calls, I have no idea. As 'Gecco' says in the comments below,
'PyString_AsString documentation says: "The pointer refers to the internal buffer of string, not a copy. The data must not be modified in any way, unless the string was just created using PyString_FromStringAndSize(NULL, size). It must not be deallocated." '
PyString_AsString documentation says: "The pointer refers to the internal buffer of string, not a copy. The data must not be modified in any way, unless the string was just created using PyString_FromStringAndSize(NULL, size). It must not be deallocated."
Please ensure you do not deallocate this buffer
If you compile your C code with the -g debug flag (in GCC at least) then you can run your python code using the gnu debugger gdb:
$ gdb /path/to/python/compiled/against
... blah ...
(gdb) run PyObject.py
and you should catch your segfault.
My guess is the Py_DECREF is somehow getting a NULL value.

qsettings different results

I am using QSettings to try and figure out if an INI is valid.(using status() to check) I made a purposefully invalid INI file and loaded it in. The first time the code is called, it returns invalid, but every time after that, it returns valid. Is this a bug in my code?
It's a Qt bug caused by some global state. Note that the difference in results happens whether or not you call delete on your QSettings object, which you should. Here's a brief summary of what happens on the first run:
The result code is set to NoError.
A global cache is checked to see if your file is present
Your file isn't present the first time, so it's parsed on qsettings.cpp line 1530 (Qt-4.6.2)
Parsing results in an error and the result code is set (see qsettings.cpp line 1552).
The error result code is returned.
And the second run is different:
The result code is set to NoError.
A global cache is checked, your file is present.
The file size and timestamp are checked to see if the file has changed (see qsettings.cpp line 1424).
The result code is returned, which happens to be NoError -- the file was assumed to have been parsed correctly.
Checked your code, you need to delete the file object before returning.
Apart from that, your code uses the QSettings::QSettings(fileName, format) c'tor to open an ini-file. That call ends in the function QConfFile::fromName (implemented in qsettings.cpp). As I read it (there are a few macros and such that I decided not to follow), the file is not re-opened if the file already is open (i.e. you have not deleted the object since the last time). Thus the status will be ok the second time around.