Backtraces in glibc and Java

  • In Gnu libc:

The following program illustrates the use of these functions. Note that
the array to contain the return addresses returned by
backtrace
is allocated on the stack. Therefore code like this can be used in
situations where the memory handling via
malloc does not work
anymore (in which case the backtrace_symbols has to be replaced
by a
backtrace_symbols_fd call as well). The number of return
addresses is normally not very large. Even complicated programs rather
seldom have a nesting level of more than, say, 50 and with 200 possible
entries probably all programs should be covered.

     #include <execinfo.h>
     #include <stdio.h>
     #include <stdlib.h>
    
     /* Obtain a backtrace and print it to stdout. */
     void
     print_trace (void)
     {
       void *array[10];
       size_t size;
       char **strings;
       size_t i;
    
       size = backtrace (array, 10);
       strings = backtrace_symbols (array, size);
    
       printf ("Obtained %zd stack frames.\n", size);
    
       for (i = 0; i < size; i++)
          printf ("%s\n", strings[i]);
    
       free (strings);
     }
    
     /* A dummy function to make the backtrace more interesting. */
     void
     dummy_function (void)
     {
       print_trace ();
     }
    
     int
     main (void)
     {
       dummy_function ();
       return 0;
     }

  • In Java:
StackTraceElement [] stack= Thread.currentThread ().getStackTrace ();

for (StackTraceElement e:stack) {

    ... ...

}

or in hotspot VM:

sun.reflect.Reflection.getCallerClass (1)

Several thoughts about im list in gimlet.

Today, in iiimf's irc, we discussed about the im list in gimlet.

(12:56:02) federic: Actually the 'Input Method List' of Input method attribute in IIIM spec refers to language available, i am afraid that IIIM protocol should be extended in order to list all IMs for langs, otherwise, all IMs have to be reimplemented as LEs to achive this goal. UNIT LE exports a lot of input method, can we leverage?
(12:59:18) federic: Hideki is right, gimlet should directly use iiimp/iiimcf to get more information, but the question is IIIMCF API should export more useful information in order to either gimlet or other IIIM*CF (client) to leverage and communicate to server.
... ...
(13:15:57) yongx40: While IIIMF server does not manage "Input Method" (the concept in CLE) in IIIM spec. Only if IM is a managed unit in server, IIIMF server could provide the information in IM level, and gimlet could tell how to organize the information. But if the IM interface is defined and officially published, we could find LE interface will be useless. So, I think LE could be consider as a IM, and with the multiple layer API (actually wrappers of LE interface), one LE could
(13:25:12) phill: Yes, if we distinguish LE and IM in the future, then there would be lot of other support thing to do, such as the creation of IM is not same as creation of LE,
(13:25:31) phill: and unload IM would be depend on LE
(13:26:00) phill: and unload LE would cause unload all its IM, etc
(13:27:50) phill: We really should make a LE a IM. Yet one package (LE) conatians multiple IM has it advantege
(13:30:08) phill: , many code could be shared. So it is reasonable to leave the LE's concept, but we could just treat it as a .so file
(13:30:50) phill: and make clear what is IM in the .so file. i.e, we have to distinguish LE and IM.
(13:32:03) phill: Currently, in LEBase class, get_langlist() and get_imdesclist() is seperated. Maybe we could try to make a langlist to every IM in the LE.
(13:35:54) yongsun: In concept, what's a IM has to do to declare itself, it should expose it's IM interface, and declare what language (or locale?) it supports, if it will use common AUX or its own custom AUX ... You could find all the stuffs are just what the LE is currently doing. I totally agree with phill, that one LE <-> one IM.
... ...
(13:39:55) juhp: as to LE vs IM I don't have a strong idea about that - I thought they were the same thing, but I see what you mean

Stand alone的Spring示例 (IoC)

Reference:

1. 60秒入门教程: http://gabriel.jarchitect.org/spring/index.html

必需的jar文件包括: spring-core.jar, common-logging.jar, 在IDEA中,
运行Java虚拟机的目录并不是classes目录, 因此它在当前目录中无法找到
"bean.xml"文件, 使用下面的代码:

  import org.springframework.core.io.*;
  /* Read the configuration file from classpath */
   Resource res = new ClassPathResource("bean.xml");
   XmlBeanFactory factory = new XmlBeanFactory(res);


Stand alone的Spring示例 (AOP)

Referneces:

1. An Introduction to Aspect-Oriented Programming with the Spring Framework, Part 1: http://www.onjava.com/lpt/a/4994

2. http://www.springframework.org/docs/wiki/Spring_AOP_Framework.html

3. SpringFrameWork中AOP的简单使用: http://blog.csdn.net/ylong/archive/2004/07/10/38482.aspx

I just copy the code from the onjava one, and implement a demo with
IDEA 4.5. But a minor change for the same issue in IoC example:

import org.springframework.context.support.ClassPathXmlApplicationContext;

    // Read the configuration file from classpath
    ApplicationContext ctx = new ClassPathXmlApplicationContext( "springconfig.xml");

必须的jar文件包括:
aopalliance.jar, commons-logging.jar, jakarta-oro-xxx.jar, spring-aop.jar, spring-context.jar, spring-core.jar.

GtkHTML programming

http://primates.ximian.com/~rodo/programing_with_gtkhtml_tutorial/guadec.html

Some useful functions of gtkhtml:

1. gtk_html_begin_content(), then gtk_html_write(), at last gtk_html_end().
2. gtk_html_set_base(), gtk_html_jump_to_anchor(), gtk_html_load_empty().
3. Contructor: gtk_html_new()

Signals:
“url-requested“
“obj-requested“ (embedded objects)
“load-done“
“submit“
“size-changed“
“link-clicked“
“button-press-event“
“redirect“
“title-changed“
“on-url“

The best startpoint is test/example along with gtkhtml. gtkhtml/src/testgtkhtml. It depends on 3 files: testgtkhtml.c, htmlurl.h, htmlurl.c. And these 3 files are not part of libgtkhtml.

Or, you can see chmsee's implementation http://211.92.88.40/~zhong/

How to debug shared librarys with gdb?


The simplest method is:


1. set a break point in main()

2. list the source code or symbol name of the shared library, and set the break point.

You could use add-symbol-file to load the symbols of the shared library. Use ldd, you can see the link address of this shared library, this is the address for the add-symbol-file command. But even you specify the correct address, because at that time, this library has not been loaded in memory, you can not set a break point. It will prompt such error "Cannot access memory at address 0x00xx00xx".

Another way, you can set a signal handler in gdb, e.g., (gdb) handle SIGINT stop. Then when you press Ctrl+C, the debugger will intercept the SIGINT signal to debuging application, then it will stop, you can set break point at that time. Use kill -l, you could list all signals in your system.

Use nocase string as g_hash_table's key

/* ghashtabledemo.c -- GHashTable demo */

#include <glib.h>
#include <string.h>

void print_entry(gpointer key, gpointer data, gpointer user_data)
{
  /* user_data not used */
  g_print("key: %-10s     value: %-10s\n", (gchar *)key, (gchar *)data);
}

guint g_str_case_hash (gconstpointer key) {
 gchar *upkey = g_ascii_strdown (key, strlen(key));
 guint hash = g_str_hash (upkey);
 g_free (upkey);
 return hash;
}

gboolean g_str_case_equal (gconstpointer a, gconstpointer b) {
 if (!g_ascii_strcasecmp (a, b))
  return TRUE;
 else
  return g_str_equal (a, b);
}

int main(int argc, char *argv[])
{
  GHashTable *hash1;
 
  hash1 = g_hash_table_new(g_str_case_hash, g_str_case_equal);

  /* insert a bunch of entries */
  g_hash_table_replace(hash1, g_strdup("foo"), g_strdup("bar"));
  g_hash_table_replace(hash1, g_strdup("FoO"), g_strdup("BAR"));
  g_hash_table_replace(hash1, g_strdup("more"), g_strdup("junk"));

  /* print the contents */
  g_print("Hash table entries:\n");
  g_hash_table_foreach(hash1, print_entry, NULL);

  return 0;
}

/*
 * gcc -ansi -Wall `pkg-config glib-2.0 --cflags` -o test test.c  `pkg-config glib-2.0 --libs`
 */

How to add a menuitem in Nautilus context menu.

1. In src/file-manager directory, add command section and menuitem section in nautilus-directory-view-ui.xml.

<commands>
    ...
    <cmd name=”Name Convert”
        _label=”Name _Convert”
        _tip=”Convert the file name”/>
    ...
</commands>

<popup name=“selection“ tearoff=“0“>
    ....
    <placeholder name=“File Actions“ delimit=“top“>
        ...
       <menuitem name=”Name Convert” verb=”Name Convert”/>
        ...
    </placeholder>
    ...
</popup>

2. In fm-directory-view.c:

    #define FM_DIRECTORY_VIEW_COMMAND_NAME_CONVERT    “/commands/Name Convert“

    In real_merge_menus () function, BonoboUIVerb verbs [] array, add the following item:
    BONOBO_UI_VERB (“Name Convert“, name_convert_callback),

    You could use nautilus_bonobo_set_sensitive () or nautilus_bonobo_hidden () to show or hide this menuitem.

3. How to launch the corresponding program in callback function:

    GnomeVFSMimeApplication *test;
   
    test = g_new0 (GnomeVFSMimeApplication, 1);
    test->id = g_strdup (“test“);
    test->name = g_strdup (“this is a test“);
    test->command = g_strdup (“test“);
    test->expects_uris = GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS;
   
    file = NAUTILUS_FILE (selection->data);
    nautilus_launch_application (test, file, NULL);

    g_free (test->id);
    g_free (test->name);
    g_free (test->name);
    g_free (test);

    You could use gnome_vfs-get_local_path_from_uri (nautilus_file_get_uri (file)) to get the actuall file name.

Java动态代理的示例

public interface SomeClass {
    public abstract void someMethod();
    public abstract void someOtherMethod(final String text);
}
public class SomeClassImpl implements SomeClass{
    private String userName;
    public SomeClassImpl(final String userName) {
        this.userName = userName;
    }
    public void someMethod( ) {
        System.out.println(this.userName);
    }
    public void someOtherMethod(final String text) {
        System.out.println(text);
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MethodCountingHandler implements InvocationHandler {
    /* whatever object, you can pass one in */
    private final Object impl;
    private int invocationCount = 0;
    /* constructor */
    public MethodCountingHandler(final Object impl) {
        this.impl = impl;
    }
    /* export the invocation Count */
    public int getInvocationCount( ) {
        return invocationCount;
    }
    /* implements the interface function of InvocationHandler */
    public Object invoke(Object proxy, Method meth, Object[] args)  throws Throwable {
        try {
            this.invocationCount++;
            Object result = meth.invoke(impl, args);
            return result;
        } catch (final InvocationTargetException ex) {
            throw ex.getTargetException( );
        }
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class SomeClassFactory {
    public static final SomeClass getDynamicSomeClassProxy( ) {
        /* get a implement instance of SomeClass */
        SomeClassImpl impl = new SomeClassImpl(System.getProperty("user.name"));
        if ( !(impl instanceof SomeClass) )
            return null;
        /* construct a invocation handler with the impl instance */
        InvocationHandler handler = new MethodCountingHandler(impl);
        /* get the class info, and the class loader used by this factory */
        Class[] interfaces = new Class[] { SomeClass.class };
        ClassLoader loader = SomeClassFactory.class.getClassLoader( );
        /*
        * install the handler for all implementations of this interface in this class loader
        * and return the proxy instance which accords to SomeClass interface.
        */
        SomeClass proxy = (SomeClass)Proxy.newProxyInstance(loader,
                interfaces,
                handler);
        return proxy;
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class DemoDynamicProxy {
    public static final void main(final String[] args) {
        SomeClass proxy = SomeClassFactory.getDynamicSomeClassProxy( );
        proxy.someMethod( );
        proxy.someOtherMethod("Our Proxy works!");
        /* get the handler associated with this proxy instance */
        InvocationHandler handler = Proxy.getInvocationHandler(proxy);
        if (handler instanceof MethodCountingHandler) {
            System.out.println(((MethodCountingHandler)handler).getInvocationCount( ));
        }
     }
}

Java的动态代理只支持基于Interface的Method Interception. 本例是从”Hardcore Java”一书中摘取出来的.

Monty Python和Monty Python Quote

我在翻译"Struts Kick Start"时遇到Monty Python Quote,不解何意,最后终于google到下面这篇文章,看来Monty Python团体对市井文化有很大的影响 :)

"MONTY PYTHON"(巨蟒)小组成立于60年代后期,成员包括Graham Chapman, John Cleese, Terry Gilliam, Eric Idle, Terry Jones,和Michael Palin。这六位成员在组团之前已经彼此熟识,首先是在大学时代-Graham,John和Eric同在剑桥就读,Terry J和Michael则是在牛津;后来他们又在一些电视喜剧节目中互相有过合作,例如著名的The Frost Report。 1967年,John和Graham合力创作并出演了“At Last, the 1948 Show”节目,同时出演的还有Marty Feldman, Tim Brooke-Taylor和Aimi MacDonald,Eric也在剧中时有出现。第二年,Eric,Michael和Terry J合力创作了儿童节目”Do Not Adjust Your Set”(DNAYS),出演的还有David Jason2和the Bonzo Dog (Doo Dah)乐队(乐队中的Neil Innes后来成了PYTHON附属成员中重要的一员),更重要的是,Terry Gilliam负责了此节目的动画部分。

1969年初,Michael和Terry J合写并出演了一出名为”The Complete and Utter History of Britain“的系列现场短剧。John也参与了此剧,当时他已经决定要与Michael进行合作。 BBC的一位制作人Barry Took为两人安排了一次会面。 John带上了自己的写作伙伴Graham,Michael也带上了DNAYS剧组的同事Terry J,Eric和Terry G。 六人一碰到一起就擦出了火花(他们都热爱The Goons组合和Spike Milligan的Q5电视节目),BBC毫不犹豫地提供了经费,让他们制作一个十三集的电视节目。

The Flying Circus 飞行的马戏团

第一集”Monty Pythons Flying Circus“于1969年10月5日播出,节目被搁在了午夜时段,并且还经常得为其他节目的时间安排而随意挪动,英国有些地区的观众甚至根本就看不到它。 尽管如此,节目还是获得了一定的口碑,这足以让BBC决定在70年继续制作第二季。

就在第二季开播之前,Python们开始涉足电影,推出了”And Now For Something Completely Different“。这部电影的主要目的是让Python打开美国市场,可惜结果并不理想,小组又回到了电视上。第三季于1972-1973年期间播出,在第三季的最后, John决定不再参与Flying Circus节目。 第四季(名字改成了简单的Monty Python) 于1974年播出,仅仅维持了6集,被大多数人认为是整个系列中最差的几集。

电影

吸取了上一部电影”And Now For Something Completely Different“的教训,Python们决定在下一部电影中要有完全的自主权。

在第三季和第四季Flying Circus节目的拍摄间隙,小组溜到了苏格兰,以很低的成本完成了”Monty Python and the Holy Grail“(巨蟒与圣杯)的拍摄工作,Terry Jones和Terry Gilliam担任了导演。尽管摄制过程中碰到了很多困难-尤其是苏格兰那糟糕的天气情况-小组还是完成了这部后来取得巨大成功的电影。更幸运的是,”Holy Grail“在美国上映时正值Python节目刚开始在美国流行,这一点大大促进了电影的成功,也坚定了小组以电影作为发展方向的信念。

接下来的Python电影就是那部引起了极大争议的”Monty Pythons Life Of Brian“(万世魔星),上映于1979年。电影的点子来源于Eric Idle的一句漫不经心的回答,他声称他们的下一部电影将叫做“Jesus Christ: Lust for Glory“(耶稣基督:荣耀的渴望)。经过多次改写后,最后的剧本已经几乎和耶稣本人毫无关系了,而是将故事集中在了一名被错认成了救世主的青年身上。由于原先的出资方EMI的退出,电影一度很有可能要被搁浅。幸运的是,乔治哈里森(前披头士成员),这位Python的粉丝,实在是太想看到这部电影了,为此,他冒着倾家荡产的危险,创立了自己的制片公司” Handmade Films“,以资助这部电影。电影上映后遭到了一些信徒的强烈攻击,并在某些地区遭到禁映。尽管如此(或许是正因为如此),影片还是获得了巨大的成功。

接下来,Python又发行了名为“Monty Python live in Hollywood Bowl"的电影,记录了他们1980年在洛杉矶好莱坞碗体育馆的舞台演出。 小组表演了一些他们最受欢迎的小品,热闹的场面就像是一出摇滚音乐会。

Python们的下一部电影最终成了他们的最后一部电影。 ”Monty Pythons The Meaning Of Life“(人生七部曲)上映于1983年,同样获得了评论与票房的双丰收,还勇夺当年嘎纳电影节的评委会大奖。电影包含了一些最疯狂的Python式段落,包括那首攻击天主教反避孕政策的歌曲”Every Sperm is Sacred“(每粒精子都是神圣的),学校里的现场性教育课,Graham Chapman被一群近乎全裸的女子赶下了悬崖,当然还有那位呕吐不止的Creosote先生。

同时......

在忙于电视系列和电影的同时,Python们也参与了一些其他工作,尤其是一系列的著作和录音。这些作品和他们的电视、电影一样具有创新性,唱片”The Monty Python Matching Tie and Handkerchief“(巨蟒鞋带与手帕)还是世界上第一张”三面“唱片-唱片的反面被第二道凹槽分成了两部分,听到什么内容取决于唱针落在哪一部分。作为Python的传统,他们的书籍和录音同样引起了一些争议,书籍”Monty Pythons Brand New Bok5“的白封面上特意做了一个仿真的脏手印,在书店里引起了一定的混乱; 唱片”Monty Pythons Instant Record Collection“同样给店主们添了很多麻烦,Terry Gilliam设计的折叠式封套(组合起来后看起来就像是一叠唱片)太过复杂,经常被客户无意间弄断,后来发行的版本不得不换上了一种简单得多了的封套;唱片“Monty Pythons Contractual Obligation Album”(巨蟒合同所迫下的专辑)在另一种方面也引起了争议,其中的那段小品“Farewell to John Denver"(一小段Denver名曲”Annies Song"之后传来的是某人被扼死的声音)在后来的版本中被删去(替换成了一段空白和Terry Jones的致歉),而另外一首"Sit on My Face"由于涉嫌抄袭也险些遭到同样命运。

如今,Python组合以网站的形式继续维持着,他们的官方网站WWW.PYTHONLINE.ORG. 这个网站更像是Eric Idle的个人作品,但其他几人也偶尔会参与进来。当然,如今的大众文化中也到处都是对Python的引用,短语“this is an ex-parrot”和“nudge, nudge, wink wink, say no more”已经成了英语术语,单词“Pythonesque"也进入了英语字典,它是这么定义的:Pythonesque,形容词, 意指幽默的,奇异的和超现实主义的, 来源于BBC电视喜剧节目”Monty Pythons Flying Circus“。

科学家(尤其是计算机科学家)在命名新事物时经常会从Python上寻找灵感:网络术语”spam"(垃圾邮件)来自于一个Python小品,而编程语言 "Python“更是一种直接的盗用。 1985年发现的一块巨大的蛇化石也被命名为拉丁语”Montypythonoides riversleighensis6“(Riversleigh是化石的发现地)。

最后

尽管"Meaning of Life"最终成了真正意义上Python的最后一部作品,但贯穿整个八十年代,一直都流传着Python要重组的说法,另一出舞台表演,另一部电影,另一部电视系列剧.....。 问题是每个独立后的Python成员都忙于自己的(或是互相的)事业,很难找出时间来让他们六个人重新聚在一起。 1988年,Graham Chapman被诊断出患上了癌症,尽管他一度声称已经战胜了病魔,但最终还是于1989年10月4日去世,就在“Flying Circus”节目播出二十周年的前一天。

Python小组在1998年重组参加了在美国科罗拉多州Aspen的一次舞台演出,英国喜剧演员Eddie Izzard替代了Graham的位置。 Graham也“出现”在了舞台上(在一个骨灰盒中),演出结束后被Terry Gilliam”不小心地“踢倒撒开。此时关于新的电影或是舞台演出之类的说法又开始流传,但都未能实现。 1999年,小组又聚在了BBC,参与了三十周年的庆典。悲伤的是,尽管他们彼此依然是朋友,但他们各自都实在太忙了,以至于根本无法再重新聚到一起投入新的计划。 而且,没有了Graham Chapman,也不会再有真正的Python了......