Stewori / JyNI

Enables Jython to load native CPython extensions.
https://jyni.12hp.de
Other
151 stars 17 forks source link

How to setup a development environment? #10

Open whilo opened 8 years ago

whilo commented 8 years ago

I have found out when I was trying to debug numpy that building all stuff JyNI related can be hairy. Could you provide a guide (and maybe a short screencast)?

Stewori commented 8 years ago

Sure. However, I can explain my setup, which might actually not be optimal, so I'm open for improvements!

First of all, I am using Eclipse as IDE. Historically this wasn't actually my first choice. I used to program in Netbeans once, until they dropped Python support somewhen after version 5 or so. What bothers me most with Eclipse is it's inhomogenity in L&F when using it with different languages; and it's stubbornness whith appearance configuration. Also cdt refuse to perform code-navigation as soon as a c-file exceeds 7k lines or so, which frequently happens in CPython (e.g. typeobject.c), ctypes or NumPy codebase. Still, eclipse so far was the most sufficient solution for cross-language and cross-platform support. AFAIK @peanut256 uses an XCode setup on OSX, maybe he will share some instructions on this front here too.

For JyNI I use up to 6 parallel projects, because mixing languages in one project is impossible (or at least impossibly painful). These are:

Each of these projects has a direct correspondence as a folder in JyNI's repo. For language select Java, C, or Python (take the obvious fit for each ;) ) I will give more details on project configuration next time.

Then. I gave up to use Eclipse's own build-process for any of the JyNI-projects. Working on JyNI I always hava a console window open to enter "make" from time to time. It is crucial to turn off automatic building in Eclipse, especially for JyNI-Java!

Some notes on using JyNI's makefile:

JYTHON = ./jython.jar PY_INCLUDE = /usr/include/python2.7 JAVA_HOME = /usr/lib/jvm/default-java

are adjusted for your system. JyNI builds fine with Java 7 or 8. I usually leave the Jython-line as it is and place a symlink to Jython-standalone in my JyNI-folder and rename it to jython.jar. Be sure to use Jython-standalone.jar of Jython 2.7.1 b3 or newer. JyOpenGL requires newest repository version, because it calls posixmodule.uname, which is not included in Jython 2.7.1b3.

In that case you should of course adjust JYTHON, PY_INCLUDE and JAVA_HOME in your corresponding makefile.

I close with some notes on debugging, will maybe specify in more detail later.

So much for now. I will supplement this info as it occurs to me or on demand.

Stewori commented 8 years ago

One more thing. You might have noticed that in JyNI-code I use tabs all the way. tabs vs spaces is a historic debate https://www.youtube.com/watch?v=SsoOG6ZeyUI In contradiction to Jython- and CPython styleguide I am actually on the tabs-front. Note that I only use tabs for indentation, not for alignment of comments next to code (frequently used in type-definitions in CPython codebase). Let me make my point on tabs:

So please stick to this as JyNI-styleguide, hope it doesn't bother you too much! For people who are uncomfortable regarding tabs vs spaces, the following post might be helpful: https://stackoverflow.com/questions/2316677/can-git-automatically-switch-between-spaces-and-tabs

Stewori commented 8 years ago

As of https://github.com/Stewori/JyNI/commit/1937112ff1763746d2d0eeeed35e9b09e45d55d0 makefile obtains JAVA_HOME from java-command if necessary and also respects if JAVA_HOME was previously given as environment variable. So this step can be skipped now in build-setup. However JYTHON must still be hand-configured (or provided e.g. as symlink).

CalumFreeman commented 6 years ago

Hi,

I have managed to get a C debugger(gdb) to attach to a running jython process. Here is a rough guide as to how I did it (suggestions for improvements in both content and delivery are very welcome).

Compiling/make-ing JyNI:

As was mentioned earlier, to include debug symbols in the compiled files you need to adjust the makefile. Fortunately this is a fairly simple fix: simply add -g to the CFLAGS variable (I put it between -c and -O0 but I don't think that matters). Then you must run "make clean" before running "make" again or else it may not actually recompile the files and you won't get the debug symbols.

Before starting gdb:

To attach gdb to a java application that uses the Java native interface to run C code, I have been told you should include the following commands in the gdb init file (~/gdbinit). If you are only using the command line you could just run these every time you start gdb, but that gets annoying very quickly. I think these commands basically just stop the debugger from throwing lots of extra errors which are thrown by the JVM in normal operation, but I'm not entirely sure.

handle SIGXCPU nostop noprint pass
handle SIGPWR nostop noprint pass
handle SIGSEGV nostop noprint pass

Command line only:

If you just want to debug from the command line then gdb is now setup, all you need to do is get the process id for the JyNI run and type the command gdb attach <pid>. This will open the gdb environment, you can set breakpoints in one of two ways:

break /Path/To/File.c:lineNumber
break Function_Name

Note that gdb halts the process it attaches to so you need to run the command c to continue so that the code you want to debug can actually run. Then once the breakpoint has triggered you can use gdb to debug using it's commands, full documentation is available(https://sourceware.org/gdb/download/onlinedocs/gdb/index.html#Top) but here's a shorter list of commands:

s = step (into) n = next (step over) f = finish function c = continue print var = print the variable called var return/enter repeats the last command

Eclipse:

To setup gdb in eclipse is slightly more involved. First you must go to the menu Run→Debug configurations. This will open a window, on the left bar select C/C++ Attach to application, then click the icon on the top left of the bar to create a New launch configuration. On the first tab(Main) select the project containing the .c files(in our case JyNI-C). The second tab(debugger) shouldn't need changing for most people, where I work the default version of gdb doesn't work very well so the path needs to be changed to point to the correct version (version 8.1.0 seems to work). Then on the third tab (source) you need to add all the folders containing all the .so files you want to be able to see the source code for while debugging. Then remember to click apply!

At this point you can set some other process running, ideally in debug mode with a breakpoint before the C code you're interested in so that you have time to attach gdb before the C code executes. Then go to the debug configuration screen, select C/C++ Attach to application again and click the debug button. You will then be asked to pick a process to attach to, you can type jps in a terminal to get a list of java processes and their process id's, if you only have one jython process running then that is the one to pick. Once attached, gdb will halt the JVM so you need to tell the C/C++ debugger to continue before you can make anything happen in your java process(press F8). You can then select the java process and start it again. You may have to take care in remembering which debugger you are in before stepping but other than that you can set breakpoints and use this like any other debugger in eclipse.

CalumFreeman commented 6 years ago

I've started to build a wiki page to answer this question, although it isn't done yet.

There is some extra information on the wiki so I'll repost it here until the wiki page is done:

It's helpful to enable non-stop mode in the C debugger as this avoids needing to press F8 as soon as the proccess attaches, it also allows java's threads to behave properly.

Also, there is a bug that will show up in debug mode only, this appears to be a known jython issue which is difficult to fix 2517. It's something to do with timing which get's thrown off in debug mode, I don't think it's worth pursuing a fix but we should warn developers about it.

Stewori commented 6 years ago

That's perfect. Moving to the wiki is the right choice at this stage. @CalumFreeman In section https://github.com/Stewori/JyNI/wiki/How-to-set-up-a-development-environment#build-the-projects I can readily fill in the build commands for numpy and CPython. However, I did not yet figure out debug mode. Given we're moving this to the wiki, I think this issue can be closed soon. Before closing I'd like to find time to hint to the wiki from the readme...

Stewori commented 6 years ago

We should add a build target for debug mode. Don't spend too much effort on documenting how to change the makefile to obtain a debug version manually. I sourced this out into #30.

Stewori commented 6 years ago

Also worth noting: Now that we are moving this to the wiki I noticed that it is not obvious how to get notified about wiki changes in github. A helpful stack overflow entry suggests to subscribe the atom feed for this. I figured out the atom feed for JyNI wiki is https://github.com/stewori/jyni/wiki.atom

Stewori commented 6 years ago

Building NumPy with debug symbols seems not to be so obvious. This page gives some hints but as far as I can see assumes that one simply installs debug extensions of numpy. This page gave some more interesting hints. The following might work: CFLAGS="-O0 -g" python setup.py build_ext --inplace At some places I also encountered -g or --debug flags applied to setup.py so that's eventually also worth a try, e.g.python setup.py build_ext --inplace --debug or python setup.py build_ext --inplace -g I did not actually try these yet, just had some time so search a bit...