Python C/API simple debugging

K

k3xji

Hi all,

I am new to Python C API and finding it difficult to debug C
extensions. So, basically I want to see the value of an integer value
during the C API. Here is the code:

#define LAST_MIX_VAL 0xDEADBEEF

static PyObject *
chash(PyObject *self, PyObject *args)
{
unsigned int key,result; //treat key like an usinged int.
unsigned char a,b,c,d;

key = result = 0;
if (!PyArg_ParseTuple(args, "i", &key))
return NULL;

printf("Key:%i\n",Py_BuildValue("i", key));
.
..

So, I just want to see the contents of local variable key. If I call
printf(..) without Py_BuildValue(), the interpreter shuts down, because
(I am assuming) printf is allocating some value in heap that is not in
the interpreter's heap itself which is causing the corruption.

This way it works, but this time I cannot see correct key content.

So, questions are:
- What I am doing wrong here?
- What is the preffered approach for these kind simple-debugging
issue? I searched C/API ref but cannot see any help on that?

Thanks,
 
S

Stefan Behnel

k3xji said:
I am new to Python C API and finding it difficult to debug C
extensions. So, basically I want to see the value of an integer value
during the C API. Here is the code:

#define LAST_MIX_VAL 0xDEADBEEF

static PyObject *
chash(PyObject *self, PyObject *args)
{
unsigned int key,result; //treat key like an usinged int.
unsigned char a,b,c,d;

key = result = 0;
if (!PyArg_ParseTuple(args, "i", &key))
return NULL;

printf("Key:%i\n",Py_BuildValue("i", key));
.
.
[...]
- What is the preffered approach for these kind simple-debugging
issue?

If you want to simplify this kind of debugging as well as the general code
writing itself, consider using Cython.

http://cython.org/

Apart from that, I'd use gdb for debugging these things. It does have a
learning curve, but in change gives you a lot more than just "print-debugging".

Stefan
 
K

k3xji

k3xji said:
I am new to Python C API and finding it difficult to debug C
extensions. So, basically I want to see the value of an integer value
during the C API. Here is the code:
#define LAST_MIX_VAL 0xDEADBEEF
static PyObject *
chash(PyObject *self, PyObject *args)
{
    unsigned int key,result; //treat key like an usinged int.
   unsigned char a,b,c,d;
   key = result = 0;
    if (!PyArg_ParseTuple(args, "i", &key))
        return NULL;
   printf("Key:%i\n",Py_BuildValue("i", key));
   .
.
[...]
- What is the preffered approach for these kind simple-debugging
issue?

If you want to simplify this kind of debugging as well as the general code
writing itself, consider using Cython.

http://cython.org/

Apart from that, I'd use gdb for debugging these things. It does have a
learning curve, but in change gives you a lot more than just "print-debugging".

Stefan

OK.

How to use gdb? I am compiling the extension to a "pyd" file and
importing it right now. So, I assume we need to, somehow load the
extension dynamically for debugging? But how?

Thanks
 
D

Diez B. Roggisch

k3xji said:
k3xji said:
I am new to Python C API and finding it difficult to debug C
extensions. So, basically I want to see the value of an integer value
during the C API. Here is the code:
#define LAST_MIX_VAL 0xDEADBEEF
static PyObject *
chash(PyObject *self, PyObject *args)
{
unsigned int key,result; //treat key like an usinged int.
unsigned char a,b,c,d;
key = result = 0;
if (!PyArg_ParseTuple(args, "i", &key))
return NULL;
printf("Key:%i\n",Py_BuildValue("i", key));
.
.
[...]
- What is the preffered approach for these kind simple-debugging
issue?

If you want to simplify this kind of debugging as well as the general
code writing itself, consider using Cython.

http://cython.org/

Apart from that, I'd use gdb for debugging these things. It does have a
learning curve, but in change gives you a lot more than just
"print-debugging".

Stefan

OK.

How to use gdb? I am compiling the extension to a "pyd" file and
importing it right now. So, I assume we need to, somehow load the
extension dynamically for debugging? But how?

You write a testscript that exposes the error you want to observe in the
C-layer.

Then you do

$ gdb python
# set args testscript.py
# break <some breakpoint, see how to enter that in gdb-docs>
# run

That pretty much is it. You can't single-step python code this way, but you
can walk through C/C++-code.

Diez
 
K

k3xji

k3xji said:
k3xji wrote:
I am new to Python C API and finding it difficult to debug C
extensions. So, basically I want to see the value of an integer value
during the C API. Here is the code:
#define LAST_MIX_VAL 0xDEADBEEF
static PyObject *
chash(PyObject *self, PyObject *args)
{
unsigned int key,result; //treat key like an usinged int.
unsigned char a,b,c,d;
key = result = 0;
if (!PyArg_ParseTuple(args, "i", &key))
return NULL;
printf("Key:%i\n",Py_BuildValue("i", key));
.
.
[...]
- What is the preffered approach for these kind simple-debugging
issue?
If you want to simplify this kind of debugging as well as the general
code writing itself, consider using Cython.
http://cython.org/
Apart from that, I'd use gdb for debugging these things. It does have a
learning curve, but in change gives you a lot more than just
"print-debugging".
Stefan

How to use gdb? I am compiling the extension to a "pyd" file and
importing it right now. So, I assume we need to, somehow load the
extension dynamically for debugging? But how?

You write a testscript that exposes the error you want to observe in the
C-layer.

Then you do

$ gdb python
# set args testscript.py
# break <some breakpoint, see how to enter that in gdb-docs>
# run

That pretty much is it. You can't single-step python code this way, but you
can walk through C/C++-code.

Diez

OK I see your point, I just expected an another way to do that from
distutils itself. Thanks for the answer.

By the way for simple print-debugging, below works right now, I forgot
to try that
fprintf(stderr,"%d", key);

Thanks all again
 
P

Philip Semanchuk

to try that
fprintf(stderr,"%d", key);


As a new extension developer myself, I'll pass along the following
handy macro that I swiped from another extension (psycopg I think):

#ifdef DEBUG_ON
#define DPRINTF(fmt, args...) fprintf(stderr, "+++ " fmt, ## args)
#else
#define DPRINTF(fmt, args...)
#endif

You can use it in code like so:

DPRINTF("key == %d\n", key);


And then turn all of your debug statements on/off by recompiling with/
without the DEBUG_ON flag.


HTH
Philip
 
A

Aaron Brady

Hi all,

I am new to Python C API and finding it difficult to debug C
extensions. So, basically I want to see the value of an integer value
during the C API. Here is the code:

#define LAST_MIX_VAL 0xDEADBEEF

static PyObject *
chash(PyObject *self, PyObject *args)
{
    unsigned int key,result; //treat key like an usinged int.
        unsigned char a,b,c,d;

        key = result = 0;
    if (!PyArg_ParseTuple(args, "i", &key))
        return NULL;

        printf("Key:%i\n",Py_BuildValue("i", key));
        .
.

So, I just want to see the contents of local variable key. If I call
printf(..) without Py_BuildValue(), the interpreter shuts down, because
(I am assuming) printf is allocating some value in heap that is not in
the interpreter's heap itself which is causing the corruption.

This way it works, but this time I cannot see correct key content.

So, questions are:
- What I am doing wrong here?
- What is the preffered approach for these kind simple-debugging
issue? I searched C/API ref but cannot see any help on that?

Thanks,

This works fine for me:

static PyObject *
methA(PyObject *self, PyObject *args) {
int a;

PyArg_ParseTuple( args, "i", &a );
printf( "%i\n", a );

Py_INCREF(Py_None);

return Py_None;
}

Did you want capital-I for 'unsigned int'?
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,061
Latest member
KetonaraKeto

Latest Threads

Top