This is the mail archive of the
frysk@sources.redhat.com
mailing list for the frysk project.
Re: remote dwarf info using libunwind
On Sep 13, 2006, Mike Cvet <mcvet@redhat.com> wrote:
> On Wed, 2006-09-13 at 06:43 -0300, Alexandre Oliva wrote:
>> It still fails to print line numbers for main and for kernel vdso
>> syscalls and their callers, but other than that, it's much better than
>> before.
>> The patch is not quite ready for public consumption (still missing a
>> ChangeLog, for one), but I thought I'd post it for people who'd like
>> to use it as is.
I've added ChangeLog entries and some comments, but couldn't get any
further on debugging the (unrelated) problems mentioned above. I had
other fires to put out tonight, unfortunately.
Ok to install this patch, and get to fix the other problems that were
already present before in a separate patch?
> According to upstream, all the dyn_list_* stuff is to handle
> dynamically-generated code only. So, probably shouldn't have an effect
> on what we're doing currently anyway.
I see. Thanks for the info, I'll leave that alone then.
for frysk/frysk-imports/libunwind/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* configure.ac: Don't define UNW_REMOTE_ONLY.
* configure: Rebuilt.
* src/os-linux.c: Restore #ifndef removed it previous patch.
for frysk/frysk-core/frysk/rt/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* StackCallbacks.java (findProcInfo, putUnwindInfo,
getDynInfoListAddr, getProcName, populate_procinfo,
populate_procinfo_nounwind, free_proc_info): Remove, obsolete.
(getPid): New.
* cni/StackCallbacks.cxx: Delete.
for frysk/frysk-imports/lib/unwind/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* UnwindCallbacks.java (findProcInfo, putUnwindInfo,
getDynInfoListAddr, getProcName): Remove, obsolete.
(getPid): New.
* StackTraceCreator.java (UnwindArgs::UPTarg,
UnwindArgs::unwas): Change to pointer type.
(arg_hash): New static fields.
(pointer_to_long, dispatch_todo): New static native methods.
(register_hashes, unregister_hashes, find_arg_from_long,
catch_errors): New static methods.
* cni/StackTraceCreator.cxx (find_unwargs): New. Use it all over.
(struct todo): New.
(StackTraceCreator::dispatch_todo): New.
(struct access_mem_todo): New.
(access_mem): Turn into dispatch_todo wrapper. Rename
original to...
(real_access_mem): ... this. Unwrap incoming arguments.
(get_proc_name): Use libunwind implementation.
(StackTraceCreator::unwind_setup): Pass pid to _UPT_create.
Register args hashes.
(StackTraceCreator::unwind_finish): Unregister them.
(StackTraceCreator::pointer_to_long): New.
Index: frysk/frysk-core/frysk/rt/StackCallbacks.java
===================================================================
--- frysk.orig/frysk-core/frysk/rt/StackCallbacks.java 2006-09-13 06:33:23.000000000 -0300
+++ frysk/frysk-core/frysk/rt/StackCallbacks.java 2006-09-13 06:33:27.000000000 -0300
@@ -42,15 +42,6 @@ package frysk.rt;
import java.util.logging.Level;
-import lib.dw.DwarfDie;
-import lib.dw.Dwfl;
-import lib.dw.DwflDieBias;
-import lib.elf.Elf;
-import lib.elf.ElfCommand;
-import lib.elf.ElfData;
-import lib.elf.ElfException;
-import lib.elf.ElfFileException;
-import lib.elf.ElfSection;
import lib.unwind.RegisterX86;
import lib.unwind.UnwindCallbacks;
import frysk.proc.Host;
@@ -72,104 +63,6 @@ public class StackCallbacks
isa = myTask.getIsa();
}
- public boolean findProcInfo (long procInfo, long addressSpace,
- long instructionAddress, boolean needInfo)
- {
- Host.logger.log(Level.FINE, "Libunwind: findProcInfo for 0x"
- + Long.toHexString(instructionAddress) + "\n");
-
- Dwfl dwfl = new Dwfl(myTask.getTid());
- DwflDieBias bias = dwfl.getDie(instructionAddress);
-
- if (bias == null)
- {
- Host.logger.log(Level.FINE,
- "Libunwind: aborted, could not find dwfl die and bias\n");
- return false;
- }
-
- DwarfDie die = bias.die;
- long adjustedAddress = instructionAddress - bias.bias;
-
- if (die == null)
- {
- Host.logger.log(Level.FINE,
- "Libunwind: aborted, could not find dwfl die\n");
- return false;
- }
-
- DwarfDie lowest = die.getScopes(adjustedAddress)[0];
- if (lowest == null)
- {
- Host.logger.log(Level.FINE,
- "Libunwind: aborted, could not find lowest scope information\n");
- return false;
- }
-
- if (needInfo)
- {
- Elf elf = null;
- // elf = dwfl.getModule(adjustedAddress).getElf().elf;
- try
- {
- elf = new Elf(myTask.getTid(), ElfCommand.ELF_C_READ);
- }
- catch (ElfFileException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- Host.logger.log(Level.FINE,
- "Libunwind: aborted, could not find elf information\n");
- return false;
- }
- catch (ElfException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- Host.logger.log(Level.FINE,
- "Libunwind: aborted, could not find elf information\n");
- return false;
- }
-
- ElfSection found = null;
- for (int i = 0; i < elf.getSectionCount(); i++)
- {
- ElfSection current = elf.getSection(i);
- if (current.getSectionHeader().name.equals(".debug_frame"))
- {
- found = current;
- break;
- }
- }
-
- if (found == null)
- {
- Host.logger.log(Level.FINE,
- "Libunwind: aborted, could not .debug_frame section\n");
- return false;
- }
-
- populate_procinfo(procInfo, lowest.getLowPC(), lowest.getHighPC(), 0,
- 0, 0, found.getData());
- }
- else
- populate_procinfo_nounwind(procInfo, lowest.getLowPC(),
- lowest.getHighPC(), 0, 0, 0);
-
- return true;
- }
-
- public void putUnwindInfo (long addressSpace, long procInfo)
- {
- free_proc_info(procInfo);
- }
-
- public long getDynInfoListAddr (long addressSpace)
- {
- // No such thing :)
- return 0;
- }
-
public long accessMem (long addressSpace, long addr)
{
Host.logger.log(Level.FINE, "Libunwind: reading memory at 0x"
@@ -179,7 +72,8 @@ public class StackCallbacks
long value = myTask.getMemory().getInt(addr);
Host.logger.log(Level.FINE, "Libunwind: read value 0x"
- + Long.toHexString(value) + "\n");
+ + Long.toHexString(value) + "\n");
+
return value;
}
@@ -243,53 +137,10 @@ public class StackCallbacks
// return 0;
}
- public String getProcName (long as, long addr)
+ public int getPid ()
{
- Host.logger.log(Level.FINE, "Libunwind: getting procedure name at 0x"
- + Long.toHexString(addr) + "\n");
-
- Dwfl dwfl = new Dwfl(myTask.getTid());
- DwflDieBias bias = dwfl.getDie(addr);
- if (bias == null)
- return "";
- DwarfDie die = bias.die;
- if (die == null)
- return "";
-
- DwarfDie lowest = die.getScopes(addr - bias.bias)[0];
- if (lowest == null)
- return "";
-
- return lowest.getName();
+ /* FIXME: this relies on the hashCode of a ProcId returning the
+ * actual id. */
+ return myTask.getProc().getId().hashCode();
}
-
- public long getProcOffset (long as, long addr)
- {
- Host.logger.log(Level.FINE, "Libunwind: getting procedure offset at 0x"
- + Long.toHexString(addr) + "\n");
-
- Dwfl dwfl = new Dwfl(myTask.getTid());
- DwflDieBias bias = dwfl.getDie(addr);
- if (bias == null)
- return 0;
- DwarfDie die = bias.die;
- if (die == null)
- return 0;
-
- DwarfDie lowest = die.getScopes(addr - bias.bias)[0];
- if (lowest == null)
- return 0;
-
- return addr - lowest.getLowPC();
- }
-
- private native void populate_procinfo (long procInfo, long lowPC,
- long highPC, long lsda, long gp,
- long flags, ElfData debug_frame);
-
- private native void populate_procinfo_nounwind (long procInfo, long lowPC,
- long highPC, long lsda,
- long gp, long flags);
-
- private native void free_proc_info (long proc_info);
}
Index: frysk/frysk-core/frysk/rt/cni/StackCallbacks.cxx
===================================================================
--- frysk.orig/frysk-core/frysk/rt/cni/StackCallbacks.cxx 2006-09-13 06:33:23.000000000 -0300
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,91 +0,0 @@
-// This file is part of the program FRYSK.
-//
-// Copyright 2005, Red Hat Inc.
-//
-// FRYSK is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by
-// the Free Software Foundation; version 2 of the License.
-//
-// FRYSK is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with FRYSK; if not, write to the Free Software Foundation,
-// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-//
-// In addition, as a special exception, Red Hat, Inc. gives You the
-// additional right to link the code of FRYSK with code not covered
-// under the GNU General Public License ("Non-GPL Code") and to
-// distribute linked combinations including the two, subject to the
-// limitations in this paragraph. Non-GPL Code permitted under this
-// exception must only link to the code of FRYSK through those well
-// defined interfaces identified in the file named EXCEPTION found in
-// the source code files (the "Approved Interfaces"). The files of
-// Non-GPL Code may instantiate templates or use macros or inline
-// functions from the Approved Interfaces without causing the
-// resulting work to be covered by the GNU General Public
-// License. Only Red Hat, Inc. may make changes or additions to the
-// list of Approved Interfaces. You must obey the GNU General Public
-// License in all respects for all of the FRYSK code and other code
-// used in conjunction with FRYSK except the Non-GPL Code covered by
-// this exception. If you modify this file, you may extend this
-// exception to your version of the file, but you are not obligated to
-// do so. If you do not wish to provide this exception without
-// modification, you must delete this exception statement from your
-// version and license this file solely under the GPL without
-// exception.
-
-#include <libunwind.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <gcj/cni.h>
-
-#include "frysk/rt/StackCallbacks.h"
-#include "../frysk-imports/lib/elf/ElfData.h"
-
-void
-frysk::rt::StackCallbacks::populate_procinfo(
- jlong procInfo, jlong lowPC, jlong highPC, jlong lsda, jlong gp, jlong flags,
- lib::elf::ElfData* debug_frame)
-{
- unw_proc_info_t *proc_info = (unw_proc_info_t *) procInfo;
-
- proc_info->start_ip = (unw_word_t) lowPC;
- proc_info->end_ip = (unw_word_t) highPC;
- proc_info->lsda = (unw_word_t) lsda;
- proc_info->gp = (unw_word_t) gp;
- proc_info->flags = (unw_word_t) flags;
- proc_info->format = UNW_INFO_FORMAT_TABLE;
-
- int data_size = (int) debug_frame->getSize();
- unsigned char* frame_data = (unsigned char*) malloc(data_size);
-
- for(int i = 0; i < data_size; i++)
- frame_data[i] = (unsigned char) debug_frame->getByte((jlong) i);
-
- proc_info->unwind_info_size = data_size;
- proc_info->unwind_info = (void *) frame_data;
-}
-
-void
-frysk::rt::StackCallbacks::populate_procinfo_nounwind(
- jlong procInfo, jlong lowPC, jlong highPC, jlong lsda, jlong gp, jlong flags)
-{
- unw_proc_info_t *proc_info = (unw_proc_info_t *) procInfo;
-
- proc_info->start_ip = (unw_word_t) lowPC;
- proc_info->end_ip = (unw_word_t) highPC;
- proc_info->lsda = (unw_word_t) lsda;
- proc_info->gp = (unw_word_t) gp;
- proc_info->flags = (unw_word_t) flags;
- proc_info->unwind_info = NULL;
-}
-
-void
-frysk::rt::StackCallbacks::free_proc_info(jlong proc_info)
-{
- if(((unw_proc_info_t *) proc_info)->unwind_info != NULL)
- JvFree(((unw_proc_info_t *) proc_info)->unwind_info);
-}
Index: frysk/frysk-imports/lib/unwind/UnwindCallbacks.java
===================================================================
--- frysk.orig/frysk-imports/lib/unwind/UnwindCallbacks.java 2006-09-13 06:33:23.000000000 -0300
+++ frysk/frysk-imports/lib/unwind/UnwindCallbacks.java 2006-09-13 06:33:27.000000000 -0300
@@ -42,40 +42,6 @@ package lib.unwind;
public interface UnwindCallbacks
{
/**
- * Retrieves the information about a procedure that will be needed to unwind
- * it. If needinfo is true the returned struct does not need to contain values
- * for format, unwind_info_size, and unwind_info
- * @param procInfo TODO
- * @param addressSpace The unwind address space
- * @param instructionAddress The address within the procedure whose
- * information is needed
- * @param needInfo Whether or not to fill in extra information
- *
- * @return The value of the pointer to the returned struct.
- */
- boolean findProcInfo (long procInfo, long addressSpace,
- long instructionAddress, boolean needInfo);
-
- /**
- * Releases the resources allocated by the call to findProcInfo with needInfo
- * set to true.
- *
- * @param addressSpace The unwind address space
- * @param procInfo The value of the pointer to the proc info struc to be
- * freed.
- */
- void putUnwindInfo (long addressSpace, long procInfo);
-
- /**
- * Gets the address of the head of the dynamic unwind-info registration list,
- * or zero if no such record exist.
- *
- * @param as
- * @return the address of the head of the list, or zero if no list exists.
- */
- long getDynInfoListAddr (long addressSpace);
-
- /**
* Reads a word of memory from from the given address
*
* @param as The unwind_addr_space
@@ -139,21 +105,8 @@ public interface UnwindCallbacks
int resume (long as, long cp);
/**
- * Returns the name of a static (not dynamically generated) procedure.
- *
- * @param as The unw_addr_space
- * @param addr An address within the procedure to get the name of
- * @return The name of the procedure
- */
- String getProcName (long as, long addr);
-
- /**
- * Returns the offset within the procudure that the current address is located
- * at
- *
- * @param as The unw_addr_space
- * @param addr The address to get the offset of.
- * @return The offset from the start of the current procedure to addr.
- */
- long getProcOffset (long as, long addr);
+ * Obtain the PID of the target process.
+ *
+ * @return the PID of the target process. */
+ int getPid ();
}
Index: frysk/frysk-imports/lib/unwind/cni/StackTraceCreator.cxx
===================================================================
--- frysk.orig/frysk-imports/lib/unwind/cni/StackTraceCreator.cxx 2006-09-13 06:33:23.000000000 -0300
+++ frysk/frysk-imports/lib/unwind/cni/StackTraceCreator.cxx 2006-09-13 06:33:27.000000000 -0300
@@ -57,64 +57,102 @@ typedef lib::unwind::StackTraceCreator$U
* functionality
***************************/
+static inline unwargs *find_unwarg(void *arg, ::unw_addr_space_t as)
+{
+ return lib::unwind::StackTraceCreator::find_arg_from_long
+ ((jlong)arg, (gnu::gcj::RawDataManaged *)as);
+}
+
/*
* Get misc. proc info
*/
int find_proc_info (::unw_addr_space_t as, ::unw_word_t ip,
- ::unw_proc_info_t *pip, int need_unwind_info, void *arg)
+ ::unw_proc_info_t *pip, int need_unwind_info,
+ void *arg)
{
- return _UPT_find_proc_info (as, ip, pip, need_unwind_info,
- (void *)((unwargs *)arg)->UPTarg);
+ return _UPT_find_proc_info (as, ip, pip, need_unwind_info,
+ find_unwarg (arg, as)->UPTarg);
}
/*
* Free space allocated during find_proc_info
*/
void put_unwind_info (::unw_addr_space_t as, ::unw_proc_info_t *pip,
- void *arg)
+ void *arg)
{
- return _UPT_put_unwind_info (as, pip,
- (void *)((unwargs *)arg)->UPTarg);
+ return _UPT_put_unwind_info (as, pip, find_unwarg (arg, as)->UPTarg);
}
/*
* Get the head of the dynamic unwind registration list.
*/
int get_dyn_info_list_addr (::unw_addr_space_t as, ::unw_word_t *dilap,
- void *arg)
+ void *arg)
{
- return _UPT_get_dyn_info_list_addr (as, dilap,
- (void *)((unwargs *)arg)->UPTarg);
+ return _UPT_get_dyn_info_list_addr (as, dilap,
+ find_unwarg (arg, as)->UPTarg);
}
+struct todo {
+ jint (*func) (struct todo *arg);
+};
+
+jint
+lib::unwind::StackTraceCreator::dispatch_todo (gnu::gcj::RawDataManaged *todo_)
+{
+ struct todo *todo = (struct todo *)todo_;
+ return todo->func (todo);
+}
+
+struct access_mem_todo {
+ struct todo todo;
+ ::unw_addr_space_t as;
+ ::unw_word_t addr;
+ ::unw_word_t *valp;
+ int write;
+ void *arg;
+};
+
/*
* Perform memory read/write
*/
-int access_mem (::unw_addr_space_t as, ::unw_word_t addr,
- ::unw_word_t *valp, int write, void *arg)
+jint real_access_mem (struct todo *todo_)
{
- lib::unwind::UnwindCallbacks *cb = ((unwargs *)arg)->CBarg;
+ struct access_mem_todo *todo = (struct access_mem_todo *)todo_;
+
+ lib::unwind::UnwindCallbacks *cb = find_unwarg (todo->arg,
+ todo->as)->CBarg;
// we've separated read and write in the java interface for simplicity
- if(write == 0){
- jlong retval = cb->accessMem ((jlong) as, (jlong) addr);
- *valp = (::unw_word_t) retval;
+ if(todo->write == 0){
+ jlong retval = cb->accessMem ((jlong) todo->as,
+ (jlong) todo->addr);
+ *todo->valp = (::unw_word_t) retval;
}
else{
- cb->writeMem ((jlong) as, (jlong) addr, (jlong) *valp);
+ cb->writeMem ((jlong) todo->as, (jlong) todo->addr,
+ (jlong) *todo->valp);
}
return 0;
}
+int access_mem (::unw_addr_space_t as, ::unw_word_t addr,
+ ::unw_word_t *valp, int write, void *arg) {
+ struct access_mem_todo todo = {
+ { real_access_mem }, as, addr, valp, write, arg
+ };
+ return lib::unwind::StackTraceCreator::catch_errors
+ ((gnu::gcj::RawDataManaged *)&todo);
+}
+
/*
* perform register read/write
*/
-int access_reg(::unw_addr_space_t as,
- ::unw_regnum_t regnum, ::unw_word_t *valp,
- int write, void *arg)
+int access_reg(::unw_addr_space_t as, ::unw_regnum_t regnum,
+ ::unw_word_t *valp, int write, void *arg)
{
- lib::unwind::UnwindCallbacks *cb = ((unwargs *)arg)->CBarg;
+ lib::unwind::UnwindCallbacks *cb = find_unwarg (arg, as)->CBarg;
// read and write are separated in the java interface
if(write == 0){
@@ -131,11 +169,10 @@ int access_reg(::unw_addr_space_t as,
/*
* Perform a floating point register read/write
*/
-int access_fpreg(::unw_addr_space_t as,
- ::unw_regnum_t regnum, ::unw_fpreg_t *fpvalp,
- int write, void *arg)
+int access_fpreg(::unw_addr_space_t as, ::unw_regnum_t regnum,
+ ::unw_fpreg_t *fpvalp, int write, void *arg)
{
- lib::unwind::UnwindCallbacks *cb = ((unwargs *)arg)->CBarg;
+ lib::unwind::UnwindCallbacks *cb = find_unwarg (arg, as)->CBarg;
if(write == 0){
jdouble retval = cb->accessFpreg ((jlong) as, (jlong) regnum);
@@ -151,10 +188,9 @@ int access_fpreg(::unw_addr_space_t as,
/*
* Resumes the process at the provided stack level
*/
-int resume(::unw_addr_space_t as,
- ::unw_cursor_t *cp, void *arg)
+int resume(::unw_addr_space_t as, ::unw_cursor_t *cp, void *arg)
{
- lib::unwind::UnwindCallbacks *cb = ((unwargs *)arg)->CBarg;
+ lib::unwind::UnwindCallbacks *cb = find_unwarg (arg, as)->CBarg;
return (int) cb->resume ((jlong) as, (jlong) cp);
}
@@ -164,25 +200,11 @@ int resume(::unw_addr_space_t as,
* the offset from the start of the procedure.
*/
int get_proc_name(::unw_addr_space_t as,
- ::unw_word_t addr, char *bufp,
- size_t buf_len, ::unw_word_t *offp, void *arg)
+ ::unw_word_t addr, char *bufp,
+ size_t buf_len, ::unw_word_t *offp, void *arg)
{
- lib::unwind::UnwindCallbacks *cb = ((unwargs *)arg)->CBarg;
-
- jstring name = cb->getProcName ((jlong) as, (jlong) addr);
- jlong offset = cb->getProcOffset ((jlong) as, (jlong) addr);
-
- *offp = (::unw_word_t) offset;
- if((unsigned int) buf_len <= (unsigned int) name->length ()){
- JvGetStringUTFRegion (name, 0, buf_len, bufp);
- bufp[buf_len-1] = '\0';
- return -UNW_ENOMEM;
- }
- else{
- JvGetStringUTFRegion (name, 0, name->length (), bufp);
- bufp[name->length ()] = '\0';
- return 0;
- }
+ return _UPT_get_proc_name (as, addr, bufp, buf_len, offp,
+ find_unwarg (arg, as)->UPTarg);
}
lib::unwind::FrameCursor*
@@ -197,12 +219,14 @@ lib::unwind::StackTraceCreator::unwind_s
// Initialize libunwind
::unw_addr_space_t addr_space = ::unw_create_addr_space(&accessors, 0);
- args->unwas = (jlong)addr_space;
+ args->unwas = (gnu::gcj::RawDataManaged *)addr_space;
::unw_cursor_t cursor;
- /* Since we're not actually using ptrace, the PID below is unused. */
- args->UPTarg = (jlong)_UPT_create (/* PID = */ 0);
- ::unw_init_remote(&cursor, addr_space, args);
+ /* Since we're not actually using ptrace, the PID below is unused. */
+ args->UPTarg = (gnu::gcj::RawDataManaged *)
+ _UPT_create (args->CBarg->getPid());
+ register_hashes (args);
+ ::unw_init_remote(&cursor, addr_space, args);
::unw_set_caching_policy(addr_space, UNW_CACHE_PER_THREAD);
// Create the frame objects and return the top (most recent one)
@@ -221,12 +245,16 @@ lib::unwind::StackTraceCreator::unwind_s
return base_frame;
}
-void
-lib::unwind::StackTraceCreator::unwind_finish (unwargs *args)
+void lib::unwind::StackTraceCreator::unwind_finish (unwargs *args)
{
- unw_destroy_addr_space ((unw_addr_space_t)args->unwas);
- args->unwas = 0;
- _UPT_destroy ((void*)args->UPTarg);
- args->UPTarg = 0;
+ unregister_hashes (args);
+ unw_destroy_addr_space ((unw_addr_space_t)args->unwas);
+ args->unwas = 0;
+ _UPT_destroy ((void*)args->UPTarg);
+ args->UPTarg = 0;
}
+jlong lib::unwind::StackTraceCreator::pointer_to_long (java::lang::Object *obj)
+{
+ return (jlong)obj;
+}
Index: frysk/frysk-imports/libunwind/configure
===================================================================
--- frysk.orig/frysk-imports/libunwind/configure 2006-09-13 06:33:23.000000000 -0300
+++ frysk/frysk-imports/libunwind/configure 2006-09-13 06:33:27.000000000 -0300
@@ -4357,7 +4357,6 @@ fi
CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE"
-CFLAGS="${CFLAGS} -DUNW_REMOTE_ONLY"
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
Index: frysk/frysk-imports/libunwind/configure.ac
===================================================================
--- frysk.orig/frysk-imports/libunwind/configure.ac 2006-09-13 06:33:23.000000000 -0300
+++ frysk/frysk-imports/libunwind/configure.ac 2006-09-13 06:33:27.000000000 -0300
@@ -34,7 +34,6 @@ AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE"
-CFLAGS="${CFLAGS} -DUNW_REMOTE_ONLY"
AC_ARG_ENABLE(debug,
[ --enable-debug turn on debug support (slows down execution)],
Index: frysk/frysk-imports/libunwind/src/os-linux.c
===================================================================
--- frysk.orig/frysk-imports/libunwind/src/os-linux.c 2006-09-13 06:33:23.000000000 -0300
+++ frysk/frysk-imports/libunwind/src/os-linux.c 2006-09-13 06:33:27.000000000 -0300
@@ -23,6 +23,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER L
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#ifndef UNW_REMOTE_ONLY
#include <limits.h>
#include <stdio.h>
@@ -54,3 +55,4 @@ tdep_get_elf_image (struct elf_image *ei
return elf_map_image (ei, path);
}
+#endif /* UNW_REMOTE_ONLY */
Index: frysk/frysk-imports/lib/unwind/StackTraceCreator.java
===================================================================
--- frysk.orig/frysk-imports/lib/unwind/StackTraceCreator.java 2006-09-13 06:33:23.000000000 -0300
+++ frysk/frysk-imports/lib/unwind/StackTraceCreator.java 2006-09-14 05:42:50.000000000 -0300
@@ -40,6 +40,9 @@
package lib.unwind;
+import gnu.gcj.RawDataManaged;
+import java.util.Hashtable;
+
public class StackTraceCreator
{
/**
@@ -62,20 +65,84 @@ public class StackTraceCreator
{
public UnwindCallbacks CBarg;
- public long UPTarg;
+ public RawDataManaged UPTarg;
- public long unwas;
+ public RawDataManaged unwas;
public UnwindArgs (UnwindCallbacks CBarg)
{
this.CBarg = CBarg;
- this.UPTarg = 0;
- this.unwas = 0;
+ this.UPTarg = null;
+ this.unwas = null;
+
+ /* register_hashes must be called later, from within
+ unwind_setup(). Calling it within an if (false) avoids a
+ warning about the unused method. */
+ if (false)
+ try {
+ register_hashes (this);
+ } catch (UnwindException _) {
+ }
}
public void finalize ()
{
+ /* unregister_hashes could be called here, but we call it in
+ unwind_finish(), to mirror the constructor above. */
+ if (false)
+ unregister_hashes (this);
unwind_finish(this);
}
}
+
+ /* arg_hash maps long values corresponding to the addresses of an
+ * UnwindArgs object and its CBarg and UPTarg fields, to the
+ * UnwindArgs object itself. This enables us to choose the right
+ * argument to pass to callbacks even when one callback calls
+ * another. */
+ private static Hashtable arg_hash = new Hashtable();
+ private static native long pointer_to_long (Object obj);
+
+ private static void register_hashes (UnwindArgs args)
+ throws UnwindException {
+ if (args.CBarg == null || args.UPTarg == null)
+ throw new UnwindException ("Internal error in unwinder set up");
+ arg_hash.put (new Long (pointer_to_long (args)), args);
+ arg_hash.put (new Long (pointer_to_long (args.CBarg)), args);
+ arg_hash.put (new Long (pointer_to_long (args.UPTarg)), args);
+ }
+
+ private static void unregister_hashes (UnwindArgs args) {
+ arg_hash.remove (new Long (pointer_to_long (args.UPTarg)));
+ arg_hash.remove (new Long (pointer_to_long (args.CBarg)));
+ arg_hash.remove (new Long (pointer_to_long (args)));
+ }
+
+ public static UnwindArgs find_arg_from_long (long val,
+ RawDataManaged unwas)
+ throws UnwindException {
+ UnwindArgs arg = (UnwindArgs) arg_hash.get (new Long (val));
+ if (arg.unwas != unwas)
+ throw new UnwindException ("Internal error in unwinder use");
+ return arg;
+ }
+
+ /**
+ * This method is used in combination with dispatch_todo in order to
+ * turn any exception into a -1 return value. It's used in the
+ * access_mem callback, that would otherwise throw an exception if
+ * given an address not available in the target address space.
+
+ * @param todo The argument to be passed to dispatch_todo.
+ * @return The return value of dispatch_todo, unless it throws a
+ * RuntimeException, in which case -1 is returned. */
+ public static int catch_errors (RawDataManaged todo) {
+ try {
+ return dispatch_todo (todo);
+ } catch (RuntimeException whatever) {
+ return -1;
+ }
+ }
+
+ private static native int dispatch_todo (RawDataManaged todo);
}
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}