Wink Saville’s Blog

March 14, 2008

git - workflow with remote svn repositories

Filed under: programming, scm — wink @ 11:11 am

I’m going to try a new git-svn workflow. Previously I did a git svn clone and also created a backup on my backup server as a remote. So pictorially something like this:

    local-git-svn-clone
           /       \
          /         \
         /           \
remote-svn            backup-server

This worked OK but I’ve made mistakes in the local-git-svn-clone and have had to start all over because things got out of sync. Most often this would happen if I merged into the master branch pushed to the backup-server than then did a “git svn rebase”. I would end up not being able to do any more pushes to the backup-server.

To try to reduce the possibility of mistakes I’m going to try separate repos. So I first. cloned the svn repo as normal:

<local>$ git svn clone -s svn+ssh://wink@<remote-svn-rep>/<path to repo> <local-git-svn-clone>

Then I made a local clone of local-git-svn-clone:

<local>$ git clone local-git-svn-clone local-clone

Next ssh into my backup-server and create a bare shared repo.

<local>$ ssh wink@<backup-server>
<backup-server>$ cd <git-repos>
<backup-server>$ mkdir <backup-repo>
<backup-server>$ cd <backup-repo>
<backup-server>$ git --bare init --shared
<backup-server>$ exit
<local>$

Now back on my local machine I push the local-git-svn-clone repo to the backup repository.

<local>$ cd <local-clone>
<local>$ git remote add backup git://<backup-server>/<backup-repo>
<local>$ git push --repo=backup --all

So at this point <local-clone> points at <local-git-svn-clone> and <backup-repo> which I don’t want. What I want is <local-clone> to just point at <backup-repo>. There may be a simpler way to do this, but I choose to actually delete <local-clone> and create it anew from <backup-repo>.

<local>$ cd ..
<local>$ rm <local-clone>
<local>$ git clone git://<backup-server>/<backup-repo> <local-clone>

So now I have two separate repos on local. <local-clone> connected to <backup-server>/<backup-repo> and <local-git-svn-clone> connected to the <remote-svn-repo>/<path to repo>.

    local-clone    << git pull >>    local-git-svn-clone
           /                                      \
          /                                        \
         /                                          \
back-repo                                          backup-server

Without the direct connection between , but since they are both based on the svn repo I can easily pull local-clone from local-git-svn-clone.

With this configuration you work on branches in local-clone, don’t work on master, the goal is to keep local-clone master exactly the same as local-git-svn-clone. If you don’t do this it will you’ll see trapezoidal commits and things get confusing.

So the work flow becomes:

local-clone$ git checkout -b x
local-clone$ hack
local-clone$ git commit (or git gui)
local-clone$ test
local-clone$ repeat more hack/commit/test
local-clone$ git push --all

So you’ve been working a while and periodically pushing to your back-repo to backup local-clone. Eventually you’ll want to commit the work you’ve done. To do this you’ll pull the changes from local-clone x branch to local-git-svn-clone, svn rebase, test and svn dcommit.

local-git-svn-clone$ git pull <local-clone> x:master
local-git-svn-clone$ git svn rebase
local-git-svn-clone$ test
local-git-svn-clone$ git svn dcommit

If the git svn rebase pulled in a lot of changes you may want to pull these over to local-clone if there and hack/test/commit then back to the above. Eventually you’ll do the svn dcommit.

The last step is to get the changes in local-git-svn-clone into local-clone and push them to backup-repo.

local-clone$ git pull <local-git-svn-clone>
local-clone$ git branch -D x
local-clone$ git push

Of course you don’t need to delete the branch x but all of those changes are now in the local-clone master so they aren’t needed.

March 10, 2008

Linking - How to link 32bit and 64bit x86 code into one image

Filed under: linux, programming — wink @ 11:05 pm

Learned something new from TJ over at Codegen today, he solved a problem where we needed to have 32bit code linked with 64bit code but the linker wouldn’t do it. Apparently this use to work without doing anything, but with the latest linker (ld) code it doesn’t. TJ figured out all that needed to be done was use objcopy to convert the 32bit format to 64bit format:

objcopy -O elf64-x86_64 32bit.o 64bit.o

One other noteworthy element to determine the output formats that objcopy supports use objcopy –info or objcopy –help

wink@ic2d1:$ objcopy --info
BFD header file version (GNU Binutils for Ubuntu) 2.18
elf64-x86-64
 (header little endian, data little endian)
  i386
elf32-i386
 (header little endian, data little endian)
  i386
a.out-i386-linux
 (header little endian, data little endian)
  i386
efi-app-ia32
 (header little endian, data little endian)
  i386
efi-app-x86_64
 (header little endian, data little endian)
  i386
elf64-little
 (header little endian, data little endian)
  i386
elf64-big
 (header big endian, data big endian)
  i386
elf32-little
 (header little endian, data little endian)
  i386
elf32-big
 (header big endian, data big endian)
  i386
srec
 (header endianness unknown, data endianness unknown)
  i386
symbolsrec
 (header endianness unknown, data endianness unknown)
  i386
tekhex
 (header endianness unknown, data endianness unknown)
  i386
binary
 (header endianness unknown, data endianness unknown)
  i386
ihex
 (header endianness unknown, data endianness unknown)
  i386

               elf64-x86-64 elf32-i386 a.out-i386-linux efi-app-ia32
          i386 elf64-x86-64 elf32-i386 a.out-i386-linux efi-app-ia32
               efi-app-x86_64 elf64-little elf64-big elf32-little elf32-big
          i386 efi-app-x86_64 elf64-little elf64-big elf32-little elf32-big
               srec symbolsrec tekhex binary ihex
          i386 srec symbolsrec tekhex binary ihex

March 7, 2008

make - need VPATH for non-local files if implicit rules are used

Filed under: linux, programming — wink @ 5:31 pm

Ran into a strange problem today, for some reason if a file isn’t in the current directory I need to have VPATH defined so that it points to the directory that contains the file(s) if the rule is implicit. For example, with the following structure where the Makefile is in a subdirectory below the location of the source file:

wink.c
x/Makefile

and the Makefile file is:cat x/Makefile is:

wink@ic2d1:$ cat x/Makefile
#VPATH=../
wink.o: ../wink.c
clean:
      rm *.o

If I now go into x and do a make –debug the we see the following:

wink@ic2d1:$ make --debug
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
Reading makefiles...
Updating goal targets....
 File `wink.o' does not exist.
Must remake target `wink.o'.
Successfully remade target file `wink.o'.
make: Nothing to be done for `wink.o'.

So it knows it needs to”remake target ‘wink.o’” but then says “Successfully remade …” but it didn’t, wink.o isn’t built. If I now enable VPATH and Makefile is:

wink@ic2d1:$ cat x/Makefile
VPATH=../
wink.o: ../wink.c
clean:
      rm *.o

Now make –debug does build wink.o and the output is:

wink@ic2d1:$ make --debug
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
Reading makefiles...
Updating goal targets....
 File `wink.o' does not exist.
Must remake target `wink.o'.
cc    -c -o wink.o ../wink.c
Successfully remade target file `wink.o'.

If you have an explicit rule everything works as expected as well:

wink@ic2d1:$ cat Makefile
#VPATH=../
wink.o: ../wink.c
	$(CC) $(CFLAGS) -c -o $@ $<
clean:
      rm *.o

Now make –debug also builds wink.o and the output is:

wink@ic2d1:$ make --debug
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
Reading makefiles...
Updating goal targets....
 File `wink.o' does not exist.
Must remake target `wink.o'.
cc    -c -o wink.o ../wink.c
Successfully remade target file `wink.o'.

Another solution is don’t use Gnu Make but use pmake. Of course if the makefile isn’t compatible with pmake then this won’t work. On Ubuntu install the bin86 package via synaptic or “apt-get install pmake”.

March 3, 2008

PXE - Booting via network cards

Filed under: linux, programming, pxe — wink @ 2:08 pm

To get PXE there are several resources on the web, here and here. The sources for pxelinux.0 is in syslinux. Anyway, here’s what I did; First, to use PXE you need to have a more capable DHCP server, so I switched to dhcpd3-server on my linux:

wink@saville-server:/etc/dhcp3$ cat my-dhcpd.conf
ddns-update-style interim;
option domain-name "saville.com";
option domain-name-servers 68.87.76.178, 66.240.49.9;
default-lease-time 600;max-lease-time 7200;

log-facility local7;
subnet 192.168.0.0 netmask 255.255.255.0 {
   range 192.168.0.100 192.168.0.149;
   option routers 192.168.0.2;
}

host test1 {
   hardware ethernet 00:1D:7D:00:A3:0B;
   fixed-address 192.168.0.148;
   option host-name "test1";
   filename "pxelinux.0";
   next-server 192.168.0.99;
}

The “host” section is the important part for PXE and in particular “hardware” identifies the card via its ethernet id, “filename” defines the file that will be requested and “next-server” defines the IP address of the server that will server the file to the “test1″ client via tftp.

So the next step was to get tftp working, I did the following but obviously synaptic works also:

apt-get install tftpd-hpa

I the config file for tftpd needs a little doctoring. The defaults is not running as a daemon and the directory is /var/log/tftpboot. You need it to run as a daemon and you may want to change the directory, here is what I have:

#Defaults for tftpd-hpa
RUN_DAEMON="yes"
OPTIONS="-l -s /tftpboot"

To start/test manually run “sudo /etc/init.d/tftpd-hpa start”. You should be able to see tftp using netstat:

wink@ic2d1:$ netstat netstat -apu
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
udp        0      0 *:32769                 *:*                                -
udp        0      0 *:32772                 *:*                                -
udp        0      0 ic2d1.local:netbios-ns  *:*                                -
udp        0      0 *:netbios-ns            *:*                                -
udp        0      0 ic2d1.local:netbios-dgm *:*                                -
udp        0      0 *:netbios-dgm           *:*                                -
udp        0      0 *:946                   *:*                                -
udp        0      0 *:tftp                  *:*                                -       
udp        0      0 *:mdns                  *:*                                -
udp        0      0 *:sunrpc                *:*                                -
udp        0      0 ic2d1.local:ntp         *:*                                -
udp        0      0 localhost:ntp           *:*                                -
udp        0      0 *:ntp                   *:*                                -
udp6       0      0 fe80::217:31ff:fee1:ntp *:*                                -
udp6       0      0 ip6-localhost:ntp       *:*                                -
udp6       0      0 *:ntp                   *:*                                -

You should now be able to add files to the directory /tftpboot such as pxelinux.0.

January 18, 2008

Android - Bug: Thread hangs writing to outer class variable

Filed under: Android, programming — wink @ 12:07 pm

Below is an bug I reported to android-developers and android-bug, it is quite strange, while executing an assignment statement the code just hangs. No errors, exceptions nothing.

Hello,

A possible bug that seems to be associated with accessing
variables of an outer class from an inner class that is a Runnable.
Maybe its a bug in my code, but I don’t see it and if it is
I wouldn’t have expected Java code to just hang on an
“assignment” statement.

In this file:
http://async-msgcomp.googlecode.com/svn/trunk/android/mc/src/com/saville/android/mc/McMgr.java
If lines 216 or 218 are commented out:

214             /** ******************************************************************************** */
215             /* FIXME: Next statement required to see “… run() 2″ below */
216             mSecondaryPort.get();
217             /* FIXME: Next statement required to see “… run() 3″ below */
218             mServerRunning = 0;
219             /** ******************************************************************************** */

Then the Thread started will stop execution with no error at line 241 or 244:

238             /** ******************************************************************************** */
239             Log.v(df, “%s: McServer; run() 1″, mName);
240             /* FIXME: We’ll die if mSecondary.get() isn’t in McServer() */
241             mSecondaryPort.set(mPort + 1);
242             Log.v(df, “%s: McServer; run() 2″, mName);
243             /* FIXME: We’ll die if mServerRunnging=0 isn’t in McServer() */
244             mServerRunning = 1;
245             Log.v(df, “%s: McServer; run() 3″, mName);
246             /** ******************************************************************************** */

The entire code base is from Revision 13 of this repository for http://async-msgcomp.googlecode.com
There are several applicatons in this repository the one in question is “android/mc”.
I tried to make a simpler test but as would be expected it didn’t fail.

I’m running m37a on Linux:

wink@ic2d1:$ uname -a
Linux ic2d1 2.6.22-14-generic #1 SMP Tue Dec 18 05:28:27 UTC 2007 x86_64 GNU/Linux

Feel free to contact me  <first name>@<last name>.com if any
additional information is needed.

Regards,

Wink Saville

January 14, 2008

Eclipse - settings and moving workspaces

Filed under: Eclipse, programming — wink @ 11:08 am

I checkout ws-msgcomp onto my laptop and wanted to move the settings from my main machine to the laptop. I found that Eclipse really doesn’t like to do that and when you do things still need tweaking.

Here was a link on what someone did for moving the settings so I created a tar script to save the settings:

tar -cjvf $1.tbz .metadata/.plugins/org.eclipse.core.runtime .metadata/.plugins/org.eclipse.ui.workbench

I saved this as backup-eclipse-settings.sh in my local bin file and executed:

backup-eclipse-setting.sh settings

creating settings.tbz I scp that to the laptop and untared it. then executed eclipse. First problem was I had my old files but no projects were imported. I imported the projects but they wouldn’t compile because “aapt” couldn’t be found even though it was there in the path it said it expected it to be. Turns out I needed to reset the android SDK path; In the Eclipse menu “Windows -> Preferences -> Android -> SDK Location:” I used Browse to reset it, even though it was correct.

Next I had to goto each of the projects and “Browse” to each of the imported libraries by selecting the Project then using the Eclipse menu; “Project -> Properties -> Java Build Path -> Libraries” and then select each of the jar’s Editing the location browsing to the actual location.

So it seems that even though the textual path is the same that isn’t enough, its almost seems it keeps the inode. Bottom line Eclipse doen’t handle paths well.

January 2, 2008

Java - class instance variable initialization

Filed under: java, programming — wink @ 5:37 pm

Been a few days, had a nice Christmas and New Years. Did work on Android and made good steady progress and nothing real interesting to report until today.

What was interesting is that I leaned that instance variables of class are initialized twice. The first time is before the constructor gets called the variables are initialized to the expected “zero” type defaults. boolean = false, byte/char/short/int = 0, float/double = 0.0 and object references to null.

Next the constructor is called and as the first instruction of the constructors executes values are at there defaults NOT any specific initialization, so don’t assume as I did. Usually this isn’t a problem but if you have inheritance thing can be surprising. In the example below when you instantiate X (new X()) we see:

X#overrideMe(): m=0
X#X(): m=4;

I would have naively expected both to print m=4!

    class B {
B() {
overrideMe();
}

void overrideMe() {
System.out.printf(”Not called\n”);
}
}

class X extends B {
X() {
System.out.printf(”X#X(): m=%d\n”, m);
}

@Override
void overrideMe() {
System.out.printf(”X#overrideMe(): m=%d\n”, m);
}

int m = 4;
}

What happens is that X#overrideMe is called while in the B#B() and m has only its default value zero and it doesn’t acquire its initialized value until after B#B() has completed.

December 23, 2007

Android - use dx to disassemble

Filed under: Android, programming — wink @ 6:45 pm

To disassemble an entire  jar file as a disassembled dex use the following:

dx –dex –dump-to=abc –locals=full –positions=lines com.saville.android.debug.jar

Click here to see the output.

Here is an example of using dx, the android jvm-byte-code to dex converter to disassemble a method in a class. The input is a “.jar” file of my debug class and I’m dumping the print method of class Log:

wink@ic2d1:$ dx –dex –dump-method=com.saville.android.debug.Log.print com.saville.android.debug.jar
com/saville/android/debug/Log.print:(Ljava/lang/String;[Ljava/lang/Object;)V:
0000: move-object v0, v6
0001: move-object v1, v7
0002: const/4 v2, #int 4 // #4
0003: const-string v3, “” // string@0000
0005: move-object v4, v0
0006: move-object v5, v1
0007: invoke-static {v4, v5}, java/lang/String.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; // method@0014
000a: move-result-object v4
000b: invoke-static {v2, v3, v4}, android/util/Log.println:(ILjava/lang/String;Ljava/lang/String;)I // method@0000
000e: move-result v2
000f: return-void
source positions
0000: 56
000f: 57
source file: Log.java

Java - using javap

Filed under: java, programming — wink @ 12:30 pm

I wanted to disassemble a class using javap but unzipping android.jar navigating to android/os where Message.class resided and then executing:

javap -c Message.class

results in:

Couldnot find Message.class

I then searched for <javap Could not find> and found that specifying the class path and then the package name worked:

javap -c -classpath ~/android/android_sdk_linux_m3-rc37a/android.jar android.os.Message

Also, I could specify the unzipped jar, assume android.jar unzipped to android.xx and that works also:

javap -c -classpath ~/android/android_sdk_linux_m3-rc37a/android.xx android.os.Message

And the simplest was cd’ing into the directory with message and using “.” for classpath, that worked also:

cd android.xx/android/os/
javap -c -classpath . Message

Actually it turns out that if we go back to the original attempt but don’t leave off .class all is well , so assuming were still in android.xx/android/os then we just need:

javap -c Message

December 21, 2007

Eclipse - multiple/new workspace

Filed under: Android, Eclipse, programming — wink @ 11:31 am

I wanted to start eclipse using a different workspace than the default. I searched for <eclipse new workspace> and here it said to use the -data option and so that you know which workspace your in use the showlocatin option:

eclipse –data ws-android –showlocation

I then added -showlocation to the the gnome application lanuch icon.

Newer Posts »

Powered by WordPress