segmentation fault while using ctypes

S

sanket

Hello All,

I am dealing with this weird bug.
I have a function in C and I have written python bindings for it using
ctypes.

I can call this function for couple of times and then suddenly it
gives me seg fault.
But I can call same function from a C code for any number of times.

I cannot get what's going on.

here is my code.

/**********************************************/
/* C Function I am calling */
int get_hash(char *filename,int rate,int ch,unsigned char* hash,
unsigned int* hash_size,short* avg_f,short* avg_d){

/* some variable declarations here */
fp = fopen(filename,"rb");

data = (signed short *)malloc(sizeof(signed short) * N_BLOCKS);

whereami = WAVE_HEADER_SIZE;
while((!feof(fp)) && (fp_more == 1) && !ferror(fp)){
fp_data_size = fread(data,sizeof(signed short),N_BLOCKS,fp);
whereami += fp_data_size;
fp_more = fp_feed_short(fooid,data,fp_data_size); // call to some
library funtion
} //end while

/* some arithmetic calculations here */

n = my_fp_calculate(fooid,audio_length,fp_fingerprint,&fit,&dom);

if (data != NULL)
free(data)
fclose(fp)
return n;
}

/************************* END OF C FUNCTION
*********************************/
--------------------------------------------------------------------
Python code
---------------------------------------------------------------------
from ctypes import *
lib = cdll.LoadLibrary("/usr/lib/libclient.so")


def my_func(filename,rate,ch):
hash = (c_ubyte * 424)()
hash_size = c_uint()
avg_f = c_short(0)
avg_d = c_short(0)
n = lib.get_hash(filename,rate,ch,hash,byref(hash_size),byref
(avg_f),byref(avg_d))
hash = None

def main():
for filename in os.listdir(MY_DIR):
print filename
my_func(filename,100,10)
print
"----------------------------------------------------"

if __name__ == "__main__":
main()

============== END OF PYTHON CODE ==========================



Thank you in advance,
sanket
 
D

Diez B. Roggisch

sanket said:
Hello All,

I am dealing with this weird bug.
I have a function in C and I have written python bindings for it using
ctypes.

I can call this function for couple of times and then suddenly it
gives me seg fault.
But I can call same function from a C code for any number of times.

I cannot get what's going on.

Try debugging it. While a python debug-build might help, I have been
getting good results with a simple

# gdb python
$ set args testscript.py
$ run


then when the segfaults hit, get a backtrace. You can also of course set
a berakpoint to the function in question.

Diez
 
M

MRAB

sanket said:
Hello All,

I am dealing with this weird bug.
I have a function in C and I have written python bindings for it using
ctypes.

I can call this function for couple of times and then suddenly it
gives me seg fault.
But I can call same function from a C code for any number of times.

I cannot get what's going on.

here is my code.

/**********************************************/
/* C Function I am calling */
int get_hash(char *filename,int rate,int ch,unsigned char* hash,
unsigned int* hash_size,short* avg_f,short* avg_d){

/* some variable declarations here */
fp = fopen(filename,"rb");
You should check the value of 'fp' here.
data = (signed short *)malloc(sizeof(signed short) * N_BLOCKS);

You should check the value of 'data' here.
whereami = WAVE_HEADER_SIZE;

What is 'whereami'?
while((!feof(fp)) && (fp_more == 1) && !ferror(fp)){
fp_data_size = fread(data,sizeof(signed short),N_BLOCKS,fp);

'fp_data_size' will be the number of signed shorts read, not the number
of bytes. Is this OK?
whereami += fp_data_size;

The final value of 'whereami' will be WAVE_HEADER_SIZE + the total
number of signed shorts read.
fp_more = fp_feed_short(fooid,data,fp_data_size); // call to some
library funtion
} //end while

/* some arithmetic calculations here */

n = my_fp_calculate(fooid,audio_length,fp_fingerprint,&fit,&dom);

if (data != NULL)
free(data)

I don't that 'free()' will complain if 'data' happens to be NULL,
although you should've already checked whether 'data' is NULL when you
malloc'ed! :)
 
S

sanket

You should check the value of 'fp' here.


You should check the value of 'data' here.


What is 'whereami'?


'fp_data_size' will be the number of signed shorts read, not the number
of bytes. Is this OK?


The final value of 'whereami' will be WAVE_HEADER_SIZE + the total
number of signed shorts read.





I don't that 'free()' will complain if 'data' happens to be NULL,
although you should've already checked whether 'data' is NULL when you
malloc'ed! :)

Thank you for your reply.

I will make check for fp and data pointers.
But my point is this function runs fine while calling it from a C
code.
it only breaks while calling from python. So I wonder if there can be
anything wrong with ctypes module.

Thanks,
sanket
 
S

sanket

Try debugging it. While a python debug-build might help, I have been
getting good results with a simple

# gdb python
$ set args testscript.py
$ run

then when the segfaults hit, get a backtrace. You can also of course set
a berakpoint to the function in question.

Diez

Thanks Diez,

I used the gdb but it just crashed and kicked my out of gdb prompt.
how can I get a stack trace?

Thanks,
sanket
 
M

MRAB

sanket said:
Thank you for your reply.

I will make check for fp and data pointers.
But my point is this function runs fine while calling it from a C
code.
it only breaks while calling from python. So I wonder if there can be
anything wrong with ctypes module.
It's more likely that it's a bug in your code.
 
A

Aaron Brady

snip
Thank you for your reply.

I will make check for fp and data pointers.
But my point is this function runs fine while calling it from a C
code.
it only breaks while calling from python. So I wonder if there can be
anything wrong with ctypes module.

Thanks,
sanket

If you have console output available, you should printf the parameters
as soon as you get into the function. You can also return immediately
for debugging purposes, to see if it's the call or the function body.
You can also assign the 'argtypes' and 'returntype' members of a
ctypes function call, which you didn't do, and may or may not help.
 
M

MRAB

Aaron said:
If you have console output available, you should printf the parameters
as soon as you get into the function. You can also return immediately
for debugging purposes, to see if it's the call or the function body.
You can also assign the 'argtypes' and 'returntype' members of a
ctypes function call, which you didn't do, and may or may not help.
Instead of printf you could open a log file and use fprintf. I'd also
probably recommend setbuf(log_file, NULL) to disable buffering just
after opening the log file so that the logging is written immediately to
disk because otherwise you won't might not get all the logging if it
crashes!
 
A

Aaron Brady

If you have console output available, you should printf the parameters
as soon as you get into the function.  You can also return immediately
for debugging purposes, to see if it's the call or the function body.
You can also assign the 'argtypes' and 'returntype' members of a
ctypes function call, which you didn't do, and may or may not help.

This just in, I was able to successfully print the 'filename'
parameter in C, write to the 'hash' parameter in C, and print the
resulting 'hash' parameter in Python. I didn't need 'argtypes' or
'returntype'. FYI.
 
B

bieffe62

Hello All,

I am dealing with this weird bug.
I have a function in C and I have written python bindings for it using
ctypes.

I can call this function for couple of times and then suddenly it
gives me seg fault.
But I can call same function from a C code for any number of times.

I cannot get what's going on.

here is my code.

/**********************************************/
/* C Function I am calling */
int get_hash(char *filename,int rate,int ch,unsigned char* hash,
unsigned int* hash_size,short* avg_f,short* avg_d){

/* some variable declarations here */
fp = fopen(filename,"rb");

data = (signed short *)malloc(sizeof(signed short) * N_BLOCKS);

whereami = WAVE_HEADER_SIZE;
while((!feof(fp)) && (fp_more == 1) && !ferror(fp)){
     fp_data_size = fread(data,sizeof(signed short),N_BLOCKS,fp);
     whereami += fp_data_size;
     fp_more = fp_feed_short(fooid,data,fp_data_size); // call to some
library funtion
 } //end while

/* some arithmetic calculations here */

  n = my_fp_calculate(fooid,audio_length,fp_fingerprint,&fit,&dom);

  if (data != NULL)
      free(data)
  fclose(fp)
  return n;

}

/************************* END OF C FUNCTION
*********************************/
--------------------------------------------------------------------
Python code
---------------------------------------------------------------------
from ctypes import *
lib = cdll.LoadLibrary("/usr/lib/libclient.so")

def my_func(filename,rate,ch):
    hash = (c_ubyte * 424)()
    hash_size = c_uint()
    avg_f = c_short(0)
    avg_d = c_short(0)
    n = lib.get_hash(filename,rate,ch,hash,byref(hash_size),byref
(avg_f),byref(avg_d))
    hash = None

def main():
    for filename in os.listdir(MY_DIR):
            print filename
            my_func(filename,100,10)
            print
"----------------------------------------------------"

if __name__ == "__main__":
    main()

============== END OF PYTHON CODE ==========================

Thank you in advance,
sanket


You don't show how the C function make use of parameters hash,
hash_size, avg_f, avg_d. Since you pass them by address,
I guess that are output parameters, but how do they get written? In
particular,make sure you don't write into hash more
than the 424 bytes you allocated for it in the calling python
code ...

Ciao
 
D

Diez B. Roggisch

Thanks Diez,

I used the gdb but it just crashed and kicked my out of gdb prompt.
how can I get a stack trace?

That's odd, has never happened for me before. Can you show us what you do
exactly, and what gdb & co say?

Diez
 
S

sanket

You don't show how the C function make use of parameters hash,
hash_size, avg_f, avg_d. Since you pass them by address,
I guess that are output parameters, but how do they get written? In
particular,make sure you don't write into hash more
than the  424 bytes you allocated for it in the calling python
code ...

Ciao

Yes, I am making sure that hash wouldn't be written more that 424
bytes in to it.
This is something really weird. I can call this function from C as
many times as I want but not from python

I tracked down the problem and came to know that call to
my_fp_calculate causes the seg fault.
I will debug it and let you guys know.

Thank you all so much for the help. I appreciate it.
sanket
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top