You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ib...@apache.org on 2010/03/18 16:14:44 UTC

svn commit: r924854 - in /harmony/enhanced/drlvm/trunk: make/vm/ vm/port/src/modules/linux/ vm/port/src/modules/unix/ vm/port/src/modules/unix/freebsd/ vm/port/src/modules/unix/include/ vm/port/src/modules/unix/linux/

Author: iberezhn
Date: Thu Mar 18 15:14:43 2010
New Revision: 924854

URL: http://svn.apache.org/viewvc?rev=924854&view=rev
Log:
Fix native call stack and modules list in FreeBSD crash dump

Added:
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/freebsd/
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/freebsd/native_modules_procmap.c
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/include/
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/include/port_modules_unix.h
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/linux/
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/linux/native_modules_procmap.c
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/native_modules_os.c
Removed:
    harmony/enhanced/drlvm/trunk/vm/port/src/modules/linux/
Modified:
    harmony/enhanced/drlvm/trunk/make/vm/port_ch.xml

Modified: harmony/enhanced/drlvm/trunk/make/vm/port_ch.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/make/vm/port_ch.xml?rev=924854&r1=924853&r2=924854&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/make/vm/port_ch.xml (original)
+++ harmony/enhanced/drlvm/trunk/make/vm/port_ch.xml Thu Mar 18 15:14:43 2010
@@ -33,6 +33,7 @@
                 <include name="port/src/thread/include" />
                 <include name="port/src/crash_handler/include" />
                 <include name="port/src/encoder/ia32_em64t" unless="is.ia64"/>
+                <include name="port/src/modules/unix/include" if="is.unix"/>
             </dirset>
             <pathelement location="${drlvm.include.dir}"/>
             <pathelement location="${hy.hdk}/include" />
@@ -40,7 +41,9 @@
 
         <patternset id="ch.src.c">
             <include name="modules/*.c"/>
-            <include name="modules/linux/*.c" if="is.unix"/>
+            <include name="modules/unix/*.c" if="is.unix"/>
+            <include name="modules/unix/linux/*.c" if="is.unix" unless="is.freebsd"/>
+            <include name="modules/unix/freebsd/*.c" if="is.freebsd"/>
             <include name="modules/win/*.c" if="is.windows"/>
 
             <include name="thread/linux/thread_os.c" if="is.unix"/>

Added: harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/freebsd/native_modules_procmap.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/freebsd/native_modules_procmap.c?rev=924854&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/freebsd/native_modules_procmap.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/freebsd/native_modules_procmap.c Thu Mar 18 15:14:43 2010
@@ -0,0 +1,56 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <limits.h>
+#include <stdio.h>
+#include "open/platform_types.h"
+
+
+FILE* port_modules_procmap_open(pid_t pid)
+{
+    char buf[64];
+    sprintf(buf, "/proc/%d/map", pid);
+
+    return fopen(buf, "rt");
+}
+
+
+int port_modules_procmap_readline(FILE* map,
+            POINTER_SIZE_INT* pstart, POINTER_SIZE_INT* pend,
+            char* pacc_r, char* pacc_x, char* filename)
+{
+    char buf[PATH_MAX];
+    char type[64];
+
+    if (!map || feof(map))
+        return -1;
+
+    if (!fgets(buf, sizeof(buf), map))
+        return -1;
+
+    int res = sscanf(buf, "%" PI_FMT "x %" PI_FMT "x %*d %*d %*" PI_FMT "x %c%*c%c %*d %*d %*x %*s %*s %s %s",
+                    pstart, pend, pacc_r, pacc_x, type, filename);
+
+    if (res < 5 || strcmp(type, "vnode") != 0)
+        return 0;
+
+    if (res == 6 && filename[0] == '-' && filename[1] == '\0')
+        filename[0] = 0;
+
+     return res - 1;
+}

Added: harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/include/port_modules_unix.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/include/port_modules_unix.h?rev=924854&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/include/port_modules_unix.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/include/port_modules_unix.h Thu Mar 18 15:14:43 2010
@@ -0,0 +1,32 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef _PORT_MODULES_UNIX_H_
+#define _PORT_MODULES_UNIX_H_
+
+#include <sys/types.h>
+
+
+FILE* port_modules_procmap_open(pid_t pid);
+
+// filename must be able to store PATH_MAX bytes
+int port_modules_procmap_readline(FILE* map,
+            POINTER_SIZE_INT* pstart, POINTER_SIZE_INT* pend,
+            char* pacc_r, char* pacc_x, char* filename);
+
+
+#endif /* _PORT_MODULES_UNIX_H_ */

Added: harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/linux/native_modules_procmap.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/linux/native_modules_procmap.c?rev=924854&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/linux/native_modules_procmap.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/linux/native_modules_procmap.c Thu Mar 18 15:14:43 2010
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <sys/types.h>
+#include <limits.h>
+#include <stdio.h>
+#include "open/platform_types.h"
+
+
+FILE* port_modules_procmap_open(pid_t pid)
+{
+    char buf[64];
+    sprintf(buf, "/proc/%d/maps", pid);
+
+    return fopen(buf, "rt");
+}
+
+
+int port_modules_procmap_readline(FILE* map,
+            POINTER_SIZE_INT* pstart, POINTER_SIZE_INT* pend,
+            char* pacc_r, char* pacc_x, char* filename)
+{
+    char buf[PATH_MAX];
+
+    if (!map || feof(map))
+        return -1;
+
+    if (!fgets(buf, sizeof(buf), map))
+        return -1;
+
+    return sscanf(buf, "%" PI_FMT "x-%" PI_FMT "x %c%*c%c%*c %*" PI_FMT "x %*02x:%*02x %*u %s",
+                    pstart, pend, pacc_r, pacc_x, filename);
+}

Added: harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/native_modules_os.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/native_modules_os.c?rev=924854&view=auto
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/native_modules_os.c (added)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/modules/unix/native_modules_os.c Thu Mar 18 15:14:43 2010
@@ -0,0 +1,248 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <memory.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "open/types.h"
+#include "port_malloc.h"
+#include "port_modules.h"
+#include "port_modules_unix.h"
+
+
+typedef struct _raw_module raw_module;
+
+// Structure to accumulate several segments for the same module
+struct _raw_module
+{
+    void*               start;
+    void*               end;
+    Boolean             acc_r;
+    Boolean             acc_x;
+    char*               name;
+    raw_module*         next;
+};
+
+void native_clear_raw_list(raw_module*);
+raw_module* native_add_raw_segment(raw_module*, void*, void*, char, char);
+native_module_t* native_fill_module(raw_module*, size_t);
+
+
+void native_clear_raw_list(raw_module* list)
+{
+    raw_module* cur;
+
+    if (list->name)
+        STD_FREE(list->name);
+
+    cur = list->next;
+
+    while (cur)
+    {
+        raw_module* next = cur->next;
+        STD_FREE(cur);
+        cur = next;
+    }
+}
+
+raw_module* native_add_raw_segment(raw_module* last,
+                                    void* start, void* end,
+                                    char acc_r, char acc_x)
+{
+    if (last->next == NULL)
+    {
+        last->next = (raw_module*)STD_MALLOC(sizeof(raw_module));
+        if (last->next == NULL)
+            return NULL;
+
+        last->next->name = NULL;
+        last->next->next = NULL;
+    }
+
+    last = last->next;
+
+    last->start = start;
+    last->end = end;
+    last->acc_r = (acc_r == 'r');
+    last->acc_x = (acc_x == 'x');
+
+    return last;
+}
+
+native_module_t* native_fill_module(raw_module* rawModule, size_t count)
+{
+    size_t i;
+
+    native_module_t* module =
+        (native_module_t*)STD_MALLOC(sizeof(native_module_t) + sizeof(native_segment_t)*(count - 1));
+
+    if (module == NULL)
+        return NULL;
+
+    module->seg_count = count;
+    module->filename = rawModule->name;
+    rawModule->name = NULL;
+    module->next = NULL;
+
+    for (i = 0; i < count; i++)
+    {
+        if (rawModule->acc_x)
+            module->segments[i].type = SEGMENT_TYPE_CODE;
+        else if (rawModule->acc_r)
+            module->segments[i].type = SEGMENT_TYPE_DATA;
+        else
+            module->segments[i].type = SEGMENT_TYPE_UNKNOWN;
+
+        module->segments[i].base = rawModule->start;
+        module->segments[i].size =
+            (size_t)((POINTER_SIZE_INT)rawModule->end -
+                        (POINTER_SIZE_INT)rawModule->start);
+
+        rawModule = rawModule->next;
+    }
+
+    return module;
+}
+
+Boolean port_get_all_modules(native_module_t** list_ptr, int* count_ptr)
+{
+    FILE* file;
+
+    POINTER_SIZE_INT start, end;
+    char acc_r, acc_x;
+    char filename[PATH_MAX];
+    raw_module module; // First raw module
+    raw_module* lastseg = &module; // Address of last filled segment
+    size_t segment_count;
+    int module_count;
+    native_module_t** cur_next_ptr;
+
+    if (list_ptr == NULL || count_ptr == NULL)
+        return FALSE;
+
+    file = port_modules_procmap_open(getpid());
+    if (!file)
+        return FALSE;
+
+    segment_count = 0;
+    module_count = 0;
+    cur_next_ptr = list_ptr;
+    module.name = NULL;
+    module.next = NULL;
+    *list_ptr = NULL;
+
+    while (!feof(file))
+    {
+        int res = port_modules_procmap_readline(file, &start, &end, &acc_r, &acc_x, filename);
+
+        if (res < 0)
+            break;
+
+        if (res < 4)
+            continue;
+
+        if (res < 5)
+            *filename = 0;
+
+        if (module.name == NULL || // First module, or single memory region
+            !(*filename)        || // Single memory region
+            strcmp(module.name, filename) != 0) // Next module
+        {
+            if (segment_count) // Add previous module
+            {
+                native_module_t* filled =
+                    native_fill_module(&module, segment_count);
+
+                if (!filled)
+                {
+                    native_clear_raw_list(&module);
+                    port_clear_modules(list_ptr);
+                    fclose(file);
+                    return FALSE;
+                }
+
+                *cur_next_ptr = filled;
+                cur_next_ptr = &filled->next;
+            }
+
+            if (*filename)
+            {
+                module.name = (char*)STD_MALLOC(strlen(filename) + 1);
+                if (module.name == NULL)
+                {
+                    native_clear_raw_list(&module);
+                    port_clear_modules(list_ptr);
+                    fclose(file);
+                    return FALSE;
+                }
+
+                strcpy(module.name, filename);
+            }
+            else
+                module.name = NULL;
+
+            // Store new module information
+            module.start = (void*)start;
+            module.end =  (void*)end;
+            module.acc_r = (acc_r == 'r');
+            module.acc_x = (acc_x == 'x');
+            module.next = NULL;
+            ++module_count;
+
+            lastseg = &module;
+            segment_count = 1; 
+        }
+        else
+        {
+            lastseg = native_add_raw_segment(lastseg,
+                                (void*)start, (void*)end, acc_r, acc_x);
+
+            if (lastseg == NULL)
+            {
+                native_clear_raw_list(&module);
+                port_clear_modules(list_ptr);
+                fclose(file);
+                return FALSE;
+            }
+
+            ++segment_count;
+        }
+    }
+
+    if (segment_count) // To process the last module
+    {
+        native_module_t* filled = native_fill_module(&module, segment_count);
+
+        if (!filled)
+        {
+            native_clear_raw_list(&module);
+            port_clear_modules(list_ptr);
+            fclose(file);
+            return FALSE;
+        }
+
+        *cur_next_ptr = filled;
+    }
+
+    native_clear_raw_list(&module);
+    fclose(file);
+
+    *count_ptr = module_count;
+    return TRUE;
+}