2017-09-25 3 views
0

Ich versuchte pthread_create auf ubuntu14.04 abzufangen, ist der Code wie folgt:Intercept Linux pthread_create Funktion, was zu einer JVM/SSH Absturz

struct thread_param{ 
    void * args; 
    void *(*start_routine) (void *); 
}; 

typedef int(*P_CREATE)(pthread_t *thread, const pthread_attr_t *attr,void * 
    (*start_routine) (void *), void *arg); 

void *intermedia(void * arg){ 

struct thread_param *temp; 
temp=(struct thread_param *)arg; 
//do some other things 
return temp->start_routine(temp->args); 
} 

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * 
(*start_routine)(void *), void *arg){ 
    static void *handle = NULL; 
    static P_CREATE old_create=NULL; 
    if(!handle) 
    { 
     handle = dlopen("libpthread.so.0", RTLD_LAZY); 
     old_create = (P_CREATE)dlsym(handle, "pthread_create"); 
    } 
    struct thread_param temp; 
    temp.args=arg; 
    temp.start_routine=start_routine; 

    int result=old_create(thread,attr,intermedia,(void *)&temp); 
//  int result=old_create(thread,attr,start_routine,arg); 
    return result; 
} 

Es funktioniert mit meinem eigenen pthread_create Testfall (geschrieben in C). Aber wenn ich es mit Hadoop auf Jvm verwendet, gab es mir die Fehlermeldung wie folgt aus:

Starting namenodes on [ubuntu] 
ubuntu: starting namenode, logging to /home/yangyong/work/hadooptrace/hadoop-2.6.5/logs/hadoop-yangyong-namenode-ubuntu.out 
ubuntu: starting datanode, logging to /home/yangyong/work/hadooptrace/hadoop-2.6.5/logs/hadoop-yangyong-datanode-ubuntu.out 
ubuntu: /home/yangyong/work/hadooptrace/hadoop-2.6.5/sbin/hadoop-daemon.sh: line 131: 7545 Aborted     (core dumped) nohup nice -n 
$HADOOP_NICENESS $hdfsScript --config $HADOOP_CONF_DIR $command "[email protected]" > "$log" 2>&1 < /dev/null 
Starting secondary namenodes [0.0.0.0 
# 
# A fatal error has been detected by the Java Runtime Environment: 
# 
# SIGSEGV (0xb) at pc=0x0000000000000000, pid=7585, tid=140445258151680 
# 
# JRE version: OpenJDK Runtime Environment (7.0_121) (build 1.7.0_121-b00) 
# Java VM: OpenJDK 64-Bit Server VM (24.121-b00 mixed mode linux-amd64 compressed oops) 
# Derivative: IcedTea 2.6.8 
# Distribution: Ubuntu 14.04 LTS, package 7u121-2.6.8-1ubuntu0.14.04.1 
# Problematic frame: 
# C 0x0000000000000000 
# 
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again 
# 
# An error report file with more information is saved as: 
# /home/yangyong/work/hadooptrace/hadoop-2.6.5/hs_err_pid7585.log 
# 
# If you would like to submit a bug report, please include 
# instructions on how to reproduce the bug and visit: 
# http://icedtea.classpath.org/bugzilla 
#] 
A: ssh: Could not resolve hostname a: Name or service not known 
#: ssh: Could not resolve hostname #: Name or service not known 
fatal: ssh: Could not resolve hostname fatal: Name or service not known 
been: ssh: Could not resolve hostname been: Name or service not known 
#: ssh: Could not resolve hostname #: Name or service not known 
#: ssh: Could not resolve hostname #: Name or service not known 
#: ssh: Could not resolve hostname #: Name or service not known 
^COpenJDK: ssh: Could not resolve hostname openjdk: Name or service not known 
detected: ssh: Could not resolve hostname detected: Name or service not known 
version:: ssh: Could not resolve hostname version:: Name or service not known 
JRE: ssh: Could not resolve hostname jre: Name or service not known 

Gibt es etwas falsch mit meinem Code? Oder liegt es an etwas anderem wie dem Schutzmechanismus von JVM oder SSH? Danke.

+0

Es gibt ein anderes ähnliches Fehlerbeispiel: [link] (https://sourceware.org/ml/glibc-linux/2001-q1/msg00048.html) – Chalex

Antwort

0

Dieser Code bewirkt, dass das Kind Thread einen ungültigen arg Wert hat:

struct thread_param temp; 
    temp.args=arg; 
    temp.start_routine=start_routine; 

    int result=old_create(thread,attr,intermedia,(void *)&temp); 
//  int result=old_create(thread,attr,start_routine,arg); 
    return result; // <-- temp and its contents are now invalid 

temp wird nicht mehr in dem neuen Thread als Mutter Anruf zu Ihren pthread_create() zurückgekehrt kann, ungültig zu machen, die Werte existieren garantiert es beinhaltet.

+0

Danke! Es löst dieses Problem! – Chalex

0

Das sind eine Menge Probleme in Ihrem Code. Ich weiß nicht, welche (wenn überhaupt) die Probleme verursacht, die Sie sehen, aber Sie sollten sie definitiv beheben.

Zuerst können Sie das Kerndumping aktivieren (normalerweise unter Verwendung von ulimit -c unlimited) und den Kern in GDB laden. Sehen Sie, worauf der Backtrace zeigt.

Nicht dlopen Pthreads. Stattdessen sollten Sie nur dlsym(RTLD_NEXT, "pthread_create") verwenden können.

Die wahrscheinlichste Quelle des Problems ist jedoch die Tatsache, dass Sie die ursprünglichen Argumente in einer globalen Variablen speichern. Dies bedeutet, dass wenn jemand (sagen wir, die Java-Laufzeit) gleichzeitig viele Threads öffnet, Sie vertauschen, was was tun soll.

+0

Vielen Dank für Ihre Antwort. Für den ersten Punkt bin ich mit gdb debuggen nicht sehr vertraut und ich habe es später eingeschaltet, aber ich kann immer noch nicht das Problem herausfinden. Und die zweiten Punkte, wenn ich nur dlsym (RTLD_NEXT, "pthread_create") verwende, wird es Warnungen werfen und der jvm wird immer noch abstürzen. Der dritte Punkt, ich bin mir nicht ganz sicher, welche Variable global ist. Vielen Dank für Ihre schnelle Antwort. – Chalex

Verwandte Themen