Looking for help using MP in Windows with QT

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Looking for help using MP in Windows with QT

Post by cduran » Mon Sep 25, 2017 2:40 pm

First I think I should give some background. I started by using the minimal build to run on Atmel SAM MCU. I started with minimal because I was embedding micropython into my existing firmware. I should also add that I am not using the current builds of MP, my project started somewhere around April 2016 and I haven't pulled any updates from the repo just to make sure I wasn't introducing any new issues into my firmware. My firmware handles all hardware, Python code is delivered over the air to my firmware and executed. Which brings me to the second component of my project.

Using QT I developed a sort of debugger for python code running on my firmware. For this I used the same build of micropython just so that I have a dublicate of mp that will behave just like the one on my firmware.

Now is when the fun begins, I'm having issues when running a script. MP is hanging within the nlr_push() call before compiling and executing the python.

The following coded handles my python execution. I haven't made any meaningful modifications to the "minimal" build of MP other than adding a few printf's:

Code: Select all

    
nlr_buf_t nlr;
unsigned int nlr_push_result = nlr_push(&nlr);
if (nlr_push_result == 0)
{
	qstr source_name = lex->source_name;
	mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
	mp_obj_t module_fun = mp_compile(&parse_tree, source_name, MP_EMIT_OPT_NONE, true);
	mp_call_function_0(module_fun);
        nlr_pop();
}
else
{
	// uncaught exception
        mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val);
}
Any insight as to what could be causing the hand will be welcome. I'm not very familiar with what the nlr is supposed to be doing or why does it have to be assemble, which I believe is part of the problem, if not all of it.

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Looking for help using MP in Windows with QT

Post by stijn » Mon Sep 25, 2017 3:34 pm

Just an idea, but whenever nlr_push is used in the uPy code it's result is never assigned to a variable and instead it's put directly in the if condition. Not sure if this matters, but if your nlr_push implementation is the one using setjmp and setjmp fiddles with the stack etc, it just might. So try with

Code: Select all

if(nlr_push(&nlr)) {...
.

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Looking for help using MP in Windows with QT

Post by cduran » Mon Sep 25, 2017 6:43 pm

stijn wrote:Just an idea, but whenever nlr_push is used in the uPy code it's result is never assigned to a variable and instead it's put directly in the if condition. Not sure if this matters, but if your nlr_push implementation is the one using setjmp and setjmp fiddles with the stack etc, it just might. So try with

Code: Select all

if(nlr_push(&nlr)) {...
.
Originally I had this:

Code: Select all

if (nlr_push(&nlr) == 0)
Still had the same hanging.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Looking for help using MP in Windows with QT

Post by dhylands » Mon Sep 25, 2017 7:35 pm

Just to clarify:

Code: Select all

if (nlr_push(&nlr)) {
is equivalent to

Code: Select all

if (nlr_push(&nlr) != 0) {
You had written == 0 which might also be fine if you swapped your if and else stuff around.

nlr_push returns 0 when it's first called, and returns non-zero when an exception is thrown.

Since nlr_push/pop is essentially setjmp/longjmp, I believe that its incompatible with C++ exception handling, and trying to mix the two will most likely be problematic. I've not used QT before, so I'm not sure if its C++ or just plain C.

There are some defines you can set that will actually make nlr_push/pop use setjmp/longjmp instead of the assembler versions. I'm not sure why a call to nlr_push would hang, It basically just saves some registers into a structure.

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Looking for help using MP in Windows with QT

Post by cduran » Mon Sep 25, 2017 8:18 pm

Well, I've been digging some more and the hang is definitely coming from here:

Code: Select all

if (type->call != NULL)
{
	return type->call(fun_in, n_args, n_kw, args);
}
Which is inside mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args)

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Looking for help using MP in Windows with QT

Post by cduran » Mon Sep 25, 2017 8:22 pm

By the way QT is both C++ and C, I just have to use:

Code: Select all

#ifdef __cplusplus
extern "C" {
#endif
 [...]
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
to call the C code from QT/C++ code.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Looking for help using MP in Windows with QT

Post by dhylands » Mon Sep 25, 2017 11:26 pm

Using extern C just satisfies the linker.

You need to make sure that once you're in MicroPython land, if you call ANY C++ code that it does not throw an exception, or it will totally mess up the MicroPython exception stack. As long as MicroPython doesn't call any C++ functions which may throw an exception you'll be fine.

As to your hang, then it sounds like perhaps your Python to C bindings are not quite setup properly.

Did you try something that's known to work, like the c_sample from here:
viewtopic.php?f=16&t=2861&p=19206#p19206

stijn
Posts: 735
Joined: Thu Apr 24, 2014 9:13 am

Re: Looking for help using MP in Windows with QT

Post by stijn » Tue Sep 26, 2017 8:32 am

Can't you just run this under the debugger and see what's goiing on? In particular, inspect the values of type and call in the code shown.

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Looking for help using MP in Windows with QT

Post by cduran » Tue Sep 26, 2017 2:38 pm

dhylands wrote:Using extern C just satisfies the linker.

You need to make sure that once you're in MicroPython land, if you call ANY C++ code that it does not throw an exception, or it will totally mess up the MicroPython exception stack. As long as MicroPython doesn't call any C++ functions which may throw an exception you'll be fine.

As to your hang, then it sounds like perhaps your Python to C bindings are not quite setup properly.

Did you try something that's known to work, like the c_sample from here:
viewtopic.php?f=16&t=2861&p=19206#p19206
MP never makes any C++ calls, I make sure everything stays in C while mp is executing.

As for the c_sample, that is what I'm using. I didn't change anything in mp going from my firmware to windows. But I'll check, might be something that QT doesn't like, but works in my firmware.

cduran
Posts: 80
Joined: Thu Mar 17, 2016 4:52 pm

Re: Looking for help using MP in Windows with QT

Post by cduran » Tue Sep 26, 2017 2:39 pm

stijn wrote:Can't you just run this under the debugger and see what's goiing on? In particular, inspect the values of type and call in the code shown.
The debugger isn't working inside the C code.

Post Reply