16589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray/*
26589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * Copyright (C) 2018 The Android Open Source Project
36589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray *
46589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
56589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * you may not use this file except in compliance with the License.
66589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * You may obtain a copy of the License at
76589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray *
86589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
96589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray *
106589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * Unless required by applicable law or agreed to in writing, software
116589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
126589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * See the License for the specific language governing permissions and
146589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray * limitations under the License.
156589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray */
166589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
176589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffrayimport java.lang.reflect.Field;
186589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffrayimport java.lang.reflect.Method;
196589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
206589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffrayclass NotLoaded {
216589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  public void foo() {}
226589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray}
236589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
246589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffraypublic class Main {
256589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  public static void main(String[] args) throws Exception {
266589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    runTest(null);
276589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  }
286589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
296589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  // This method being synchronized means the SIGQUIT code in ART will call
306589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  // FindLocksAtDexPc (we check for the presence of try blocks and monitor-enter),
316589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  // which triggered a DCHECK of an invariant.
326589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  public static synchronized void runTest(Object m) throws Exception {
336589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    if (m != null) {
346589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      // We used to crash while trying to resolve NotLoaded and beint interrupted
356589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      // by the SIGQUIT.
366589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      if (m instanceof NotLoaded) {
376589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        ((NotLoaded)m).foo();
386589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      }
396589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    }
406589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    SigQuit.doKill();
416589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    // Sleep some time to get the kill while executing this method.
426589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    Thread.sleep(2);
436589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    System.out.println("Done");
446589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  }
456589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
466589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  private final static class SigQuit {
476589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    private final static int sigquit;
486589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    private final static Method kill;
496589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    private final static int pid;
506589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
516589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    static {
526589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      int pidTemp = -1;
536589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      int sigquitTemp = -1;
546589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      Method killTemp = null;
556589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
566589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      try {
576589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        Class<?> osClass = Class.forName("android.system.Os");
586589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        Method getpid = osClass.getDeclaredMethod("getpid");
596589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        pidTemp = (Integer)getpid.invoke(null);
606589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
616589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        Class<?> osConstants = Class.forName("android.system.OsConstants");
626589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        Field sigquitField = osConstants.getDeclaredField("SIGQUIT");
636589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        sigquitTemp = (Integer)sigquitField.get(null);
646589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
656589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        killTemp = osClass.getDeclaredMethod("kill", int.class, int.class);
666589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      } catch (Exception e) {
676589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray        throw new Error(e);
686589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      }
696589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
706589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      pid = pidTemp;
716589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      sigquit = sigquitTemp;
726589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      kill = killTemp;
736589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    }
746589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray
756589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    public static void doKill() throws Exception {
766589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray      kill.invoke(null, pid, sigquit);
776589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray    }
786589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray  }
796589af15b7dd5c1c6a7056bcdcdce8443b084c33Nicolas Geoffray}
80