CN113419919A - Method for thread monitoring of third-party SDK - Google Patents

Method for thread monitoring of third-party SDK Download PDF

Info

Publication number
CN113419919A
CN113419919A CN202110703442.2A CN202110703442A CN113419919A CN 113419919 A CN113419919 A CN 113419919A CN 202110703442 A CN202110703442 A CN 202110703442A CN 113419919 A CN113419919 A CN 113419919A
Authority
CN
China
Prior art keywords
thread
instruction
party sdk
creating
plug
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN202110703442.2A
Other languages
Chinese (zh)
Inventor
曹峥
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Yeelion Online Network Technology Beijing Co Ltd
Original Assignee
Yeelion Online Network Technology Beijing Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Yeelion Online Network Technology Beijing Co Ltd filed Critical Yeelion Online Network Technology Beijing Co Ltd
Priority to CN202110703442.2A priority Critical patent/CN113419919A/en
Publication of CN113419919A publication Critical patent/CN113419919A/en
Pending legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/30Monitoring
    • G06F11/3003Monitoring arrangements specially adapted to the computing system or computing system component being monitored
    • G06F11/302Monitoring arrangements specially adapted to the computing system or computing system component being monitored where the computing system component is a software system
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/30Monitoring
    • G06F11/3051Monitoring arrangements for monitoring the configuration of the computing system or of the computing system component, e.g. monitoring the presence of processing resources, peripherals, I/O links, software programs
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs
    • G06F9/448Execution paradigms, e.g. implementations of programming paradigms
    • G06F9/4488Object-oriented
    • G06F9/449Object-oriented method invocation or resolution
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/20Software design
    • G06F8/24Object-oriented

Abstract

The invention relates to a method for thread monitoring of a third-party SDK, which comprises the following steps: compiling the source code of App to obtain a Java byte code file expanded to class; at least one third-party SDK is accessed into the source code of the App; traversing the Java byte code file through a pre-deployed plug-in, and automatically replacing an instruction for creating a shadow thread with a preset instruction for creating a shadow thread in the plug-in when the instruction for creating the thread by the third-party SDK is found; and realizing thread monitoring on the third-party SDK based on the instruction for creating the shadow thread. According to the invention, through operating the byte codes at the bottom layer, under the condition of not invading the source codes, the information of the threads created by the third-party SDK is acquired, so that the purpose of thread monitoring is achieved, and convenience is provided for the development and debugging of the application program.

Description

Method for thread monitoring of third-party SDK
Technical Field
The invention relates to the technical field of third-party thread monitoring, in particular to a method for thread monitoring of a third-party SDK. The SDK is a Software Development Kit (full name in foreign language), which is a simple way to standardize Software functions so that other apps (application programs) can be immediately plugged and used and have the standardized functions of the SDK.
Background
In App (application) development based on the Java language, it is inevitably necessary to use a third party SDK, such as: when App (application program) development is carried out in Android by adopting Java language, the api provided by the third-party SDK is called, and in the application scene, the fact that the thread of the third-party SDK cannot be monitored in the prior art is found, which brings inconvenience to development and debugging of the App (application program).
Most of the existing apps belong to applications with complex services (meaning complex service logics), the apps themselves generate a plurality of threads, and third-party SDKs accessed in the apps also generate a plurality of threads, for example: in an App with a certain e-commerce and travel service function, 33 third-party SDKs are used inside, and obviously, the third-party SDKs generate many threads, and due to the existence of the problems (that is, the threads of the third-party SDKs cannot be monitored), the problems are difficult to manage the threads, debug the App, and the like, so that the problem troubleshooting efficiency is low, and the method is embodied in the following aspects:
the competition among threads is difficult to monitor and manage due to a plurality of threads, so that considerable resources are consumed in thread scheduling, and the running stability of the App is influenced;
because the thread of the third-party SDK cannot be monitored, the risk of creating a wild anonymous thread exists, the resource consumption is aggravated by a large number of wild anonymous threads which are not uniformly managed, and the thread scheduling difficulty is further increased;
when an application program debugs, problems are sometimes located through analysis Of logs on the thread, but the threads cannot be further located (specific thread call stack information cannot be tracked), so that a service module (which the thread belongs to cannot be distinguished) which cannot be further located according to the thread is caused, and finally OOM (Out Of Memory overflow) and the like are crashed;
because the thread of the third-party SDK cannot be monitored, the thread in the third-party SDK cannot be effectively managed and intervened in the existing scene.
The information disclosed in this background section is only for enhancement of understanding of the general background of the invention and should not be taken as an acknowledgement or any form of suggestion that this information forms the prior art already known to a person skilled in the art.
Disclosure of Invention
Aiming at the defects in the prior art, the invention aims to provide a method for monitoring the thread of the third-party SDK, which realizes the information acquisition of the thread created by the third-party SDK by operating the byte codes at the bottom layer without intruding source codes, further achieves the purpose of thread monitoring and provides convenience for the development and debugging of application programs.
In order to achieve the above purposes, the technical scheme adopted by the invention is as follows:
a method for thread monitoring of a third-party SDK is characterized by comprising the following steps:
compiling the source code of App to obtain a Java byte code file expanded to class;
at least one third-party SDK is accessed into the source code of the App;
traversing the Java byte code file through a pre-deployed plug-in, and automatically replacing an instruction for creating a shadow thread with a preset instruction for creating a shadow thread in the plug-in when the instruction for creating the thread by the third-party SDK is found;
and realizing thread monitoring on the third-party SDK based on the instruction for creating the shadow thread.
On the basis of the technical scheme, the instruction of the third-party SDK thread creation is replaced by the instruction of the shadow thread creation, and the shadow thread creation is realized through asm byte code operation.
On the basis of the technical scheme, the pre-deployed plug-in is a Gradle plug-in which is declared as a thread monitoring module, and the thread monitoring module is uploaded to a Maven warehouse in a plug-in mode to complete the pre-deployment.
On the basis of the technical scheme, when the instruction of the third-party SDK for creating the thread is found, the instruction of the third-party SDK for creating the thread is replaced by the instruction for creating the shadow thread in a mode of declaring the introduction of a Gradle plug-in, and the instruction for creating the shadow thread completes the operation of initializing the thread monitoring module when the program is executed.
On the basis of the technical scheme, the method further comprises the following steps: saving the bytecode file which completes traversal and replacement operation as a target bytecode file;
sending the target bytecode file to the virtual machine jvm, converting the target bytecode file into executable binary machine code by an interpreter in the virtual machine jvm, and storing the executable binary machine code to obtain an App program;
when the App program is executed, the thread is generated by creating an instruction of the shadow thread, and an interface for acquiring thread information is provided, so that thread monitoring is realized.
The method for monitoring the thread of the third-party SDK has the following beneficial effects:
by operating the byte codes at the bottom layer, the information of the threads created by the third-party SDK is acquired under the condition of not invading the source codes, so that the purpose of thread monitoring is achieved, and convenience is provided for application program development and debugging.
Drawings
The invention has the following drawings:
the drawings are included to provide a better understanding of the invention and are not to be construed as unduly limiting the invention. Wherein:
FIG. 1 is a flow chart of a method for thread monitoring of a third party SDK according to the present invention.
Detailed Description
The present invention will be described in further detail with reference to the accompanying drawings. The detailed description, while indicating exemplary embodiments of the invention, is given by way of illustration only, in which various details of embodiments of the invention are included to assist understanding. Accordingly, it will be appreciated by those skilled in the art that various changes and modifications may be made to the embodiments described herein without departing from the scope and spirit of the invention. Also, descriptions of well-known functions and constructions are omitted in the following description for clarity and conciseness.
As shown in fig. 1, the method for thread monitoring of a third-party SDK according to the present invention includes the following steps:
compiling the source code of App to obtain a Java byte code file (simply referred to as byte code file) extended to class; the App is based on a Java language, the source code of the App is the Java source code of the App, and the Java source code is compiled to obtain a Java byte code file which is extended to class;
at least one third-party SDK is accessed into the source code of the App;
traversing the Java bytecode file through a pre-deployed plugin, and when finding out an instruction for creating a Thread by a third-party SDK (for example, a Thread () instruction), automatically replacing the instruction with an instruction for creating a shadow Thread preset in the plugin (for example, replacing the instruction with a Thread new Thread () instruction, and performing Thread monitoring on the third-party SDK by using the shadow Thread);
and realizing thread monitoring on the third-party SDK based on the instruction for creating the shadow thread.
The method has the advantages that the plug-in access is realized in a non-invasive manner, byte code operation is carried out on the application self and the third-party SDK in a non-perception manner during the compiling period, the byte code is operated on the bottom layer, the monitoring on the third-party SDK and the thread of the application self is realized, and the corresponding service scene where the problem belongs is helped to be quickly positioned by application developers;
the compilation supports concurrent compilation.
On the basis of the technical scheme, the instruction of the third-party SDK thread creation is replaced by the instruction of the shadow thread creation, and the method is realized through asm byte code operation, namely: modifying the bytecode based on the asm;
the asm is a byte code operation frame of Java, can dynamically check the class information, dynamically modify, delete and add the class method, the invention realizes the indirect intervention to the Java source code during the compiling period through the substitution of the asm byte code, the asm byte code operation is implemented according to the prior art, and the invention is not detailed any more.
On the basis of the technical scheme, the pre-deployed plug-in is a Gradle plug-in and is declared as a thread monitoring module, and the thread monitoring module is uploaded to a Maven warehouse in a plug-in mode to complete the pre-deployment;
the method comprises the following steps that the Gradle is a framework and is responsible for defining processes and rules, and specific compiling work is finished in a plug-in mode, for example, Java plug-ins are compiled in Java, Groovy plug-ins are compiled in Groovy, Android APP plug-ins are compiled in Android APP, and Android Library plug-ins are compiled in Android Library;
when the instruction of the third-party SDK creating thread is found, the instruction of the third-party SDK creating thread is replaced by the instruction of the shadow thread by declaring the mode of introducing a Gradle plug-in, and the instruction of the shadow thread is created to complete the operation of initializing the thread monitoring module when the program is executed.
The access form of the invention is a Gradle plug-in, only the plug-in is required to be introduced in a statement of an application Gradle, the Gradle provides transformAPI (application program interface for injecting self-defined operation), and the third party SDK and the extension of the application itself can be taken in the compiling process by inheriting the transformAPI, and the Java byte code file of class can be subjected to byte code operation on the Java byte code file of class extended in the compiling period by combining with asm.
TransformAPI is a way of the newly introduced operation Class, the Transform API works after compilation and before dex is generated, by writing a Transform to receive the Class file produced by the compilation and add something to the already produced input.
As an alternative embodiment, other technical implementation such as non-buried point data acquisition can be expanded on the basis of the scheme of the invention.
On the basis of the technical scheme, the method further comprises the following steps: saving the bytecode file which completes traversal and replacement operation as a target bytecode file;
sending the target bytecode file to the virtual machine jvm, converting the target bytecode file into executable binary machine code by an interpreter in the virtual machine jvm, and storing the executable binary machine code to obtain an App program;
when the App program is executed, the thread is generated by creating an instruction of the shadow thread, and an interface for acquiring thread information is provided, so that thread monitoring is realized.
The following are specific examples.
Example 1:
the function of acquiring input and also acquiring output by using the parameter transformation invocation in the Transform API comprises the following input:
JarInput corresponds to a third party Jar needing to be processed, the third party Jar refers to a Jar package of a third party SDK accessed in the source code,
DirectoryInput, corresponding to the class of the application itself,
reading and writing are carried out by combining ClassReader and ClassWriter with ClassVisitor;
when a Java function is executed, a visitMethod in a ClassVisitor is triggered, and a bytecode operation can be performed on a class file to be processed through the MethodVisitor, specifically:
mainly using calling method visitmedinsn (int opcode, String owner, String name, String desc, byte itf) and bytecode instruction visittypeen (int opcode, String type) with reference type parameter to perform bytecode substitution operation; wherein:
opcode is invokespecific and owner is java/lang/Thread, name is < init >, which represents that a constructor of a Thread is called, desc is a parameter signature, such as () V, (Ljava/lang/Runnable) V, (Ljava/lang/String) V, etc., which respectively correspond to a parameterless construction, a constructor with parameters Runnable and a constructor with parameters of a String.
Example 2:
an example of a use procedure is as follows:
introducing plug-ins by using a maven warehouse, and specifically comprises the following steps:
instructions to configure the plug-in:
maven{url
'http://172.17.90.43:8081/repository/kwplugin/
}classpath'cn.kuwo.boxer:thread:1.0.1'
instructions to use the plug-in;
apply plugin:'cn.kuwo.boxer.thread'
declare and introduce the above-mentioned plug-in 'cn.kuwo.box.thread' in the Gradle file of the project;
executing a compiling and packaging process, then performing asm byte code replacement, and taking over and intervening in the compiling process by a plug-in so as to achieve the purpose of replacing the object to be monitored;
and generating an executable Android application, and monitoring the states of all internal threads in real time in the application running process.
Example 3:
replacement of monitor thread objects by asm bytecodes
A custom plug-in kwboxerthreadrandsform is registered,
App Extension.register Transform(new KwBoxerThreadTransform(project));
by registering the plug-in, the purpose that the system uses the plug-in to intervene the compiling process in the compiling process is achieved;
the custom plug-in kwboxerthreadrandsform is used in the compilation process,
the following information is set in the compilation configuration:
inputting types: transform manager. content _ CLASS,
the action range is as follows: SCOPE _ FULL _ PROJECT,
the scope of reference: transform manager, empty _ SCOPES;
defining that in KwBoxerThreadTransform, a scan Jar Input conversion process is executed or a scan Directory Input conversion process is executed, the two conversion processes are alternatively used,
Void transform(Transform Invocation transform Invocation)
jar Input is a form where the Input type is third party SDK or the like in Jar package,
the Directory Input is Input with the Input type being a Directory type;
for Jar Input, if monitoring third party Jar is not carried out, the Input is not specially processed, the output is directly copied,
if the monitoring of the third party Jar is needed, Jar Entry (each node in the Jar package) is acquired,
after finding the Java byte code file, constructing a Class Visitor and preparing to modify a monitoring object;
ClassVisitor is a class in the ASM module that provides the ability to browse class files;
for the Directory Input, a Java byte code file is found by scanning a file or a Directory, and after the Java byte code file is found, a Class Visitor is constructed to prepare for modifying a monitoring object;
ClassVisitor is a class in the ASM module that provides the ability to browse class files;
browsing the Class file, searching the thread object in the Class file, directly outputting byte codes if the thread object is not the thread object, and further executing the following operations if the thread object is the thread object:
constructing a MethodVisitor, judging whether an OpCode is a NEW operation and a thread object through visitTypeInsn, if not, directly ignoring, and not performing replacement processing, if so, performing the following replacement processing:
automatically replacing the instruction with an instruction for creating a shadow thread preset in the plug-in;
judging whether the OpCode is an invokespecial by visitMethodInn, simultaneously meeting two conditions of thread object and initialization, if not, directly outputting byte codes, if so, replacing objects created by the original threads by different creation modes according to rules to be monitoring threads, and then outputting the byte codes;
executing a file packaging process;
and generating an executable Android installation file. Wherein:
the MethodVisitor is a class in the asm module that provides the functions defined in the browse class;
OpCode is an operator of Java bytecode mapping, such as: NEW is the create object. invokespecial is a static call, etc.;
the visitTypeInsn (int opcode, String type) is an access type, defined in the MethodVisitor, and is mapped to be called when an instruction is triggered in Java source code, for example: NEW Thread ("a") introduced OpCode is NEW, and the type is java/lang/Thread ");
visitMethodedInsn (int opcode, String owner, String name, String desc, bootean itf) is a function call, defined in the MethodVisitor, that maps to a Java source code that triggers when a function is called, for example: public Thread (String name); the receiving parameter of the constructor of the Java Thread is a String type, and the corresponding parameter is opcode InVOKESPECIAL, inner is Java/lang/Thread, name is "< init >", desc is "(Ljava/lang/String;) V").
Those not described in detail in this specification are within the skill of the art.
The above description is only a preferred embodiment of the present invention, and the scope of the present invention is not limited to the above embodiment, but equivalent modifications or changes made by those skilled in the art according to the present disclosure should be included in the scope of the present invention as set forth in the appended claims.

Claims (5)

1. A method for thread monitoring of a third-party SDK is characterized by comprising the following steps:
compiling the source code of App to obtain a Java byte code file expanded to class;
at least one third-party SDK is accessed into the source code of the App;
traversing the Java byte code file through a pre-deployed plug-in, and automatically replacing an instruction for creating a shadow thread with a preset instruction for creating a shadow thread in the plug-in when the instruction for creating the thread by the third-party SDK is found;
and realizing thread monitoring on the third-party SDK based on the instruction for creating the shadow thread.
2. The method of thread monitoring a third party SDK as recited in claim 1, wherein the instructions that the third party SDK creates threads are replaced with instructions that create shadow threads by asm bytecode operation.
3. The method of thread monitoring a third party SDK as recited in claim 1, wherein the pre-deployed plug-in is a Gradle plug-in declared as a thread monitoring module, and wherein the thread monitoring module is uploaded to a Maven repository in the form of a plug-in to complete the pre-deployment.
4. The method according to claim 3, wherein when the instruction of the thread created by the third-party SDK is found, the instruction of the thread created by the third-party SDK is replaced by the instruction of the shadow thread created by declaring the way of introducing a Gradle plug-in, and when the program is executed, the instruction of the shadow thread created completes the operation of initializing the thread monitoring module.
5. The method for thread monitoring of a third party SDK of claim 1, further comprising the steps of: saving the bytecode file which completes traversal and replacement operation as a target bytecode file;
sending the target bytecode file to the virtual machine jvm, converting the target bytecode file into executable binary machine code by an interpreter in the virtual machine jvm, and storing the executable binary machine code to obtain an App program;
when the App program is executed, the thread is generated by creating an instruction of the shadow thread, and an interface for acquiring thread information is provided, so that thread monitoring is realized.
CN202110703442.2A 2021-06-24 2021-06-24 Method for thread monitoring of third-party SDK Pending CN113419919A (en)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202110703442.2A CN113419919A (en) 2021-06-24 2021-06-24 Method for thread monitoring of third-party SDK

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202110703442.2A CN113419919A (en) 2021-06-24 2021-06-24 Method for thread monitoring of third-party SDK

Publications (1)

Publication Number Publication Date
CN113419919A true CN113419919A (en) 2021-09-21

Family

ID=77716535

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202110703442.2A Pending CN113419919A (en) 2021-06-24 2021-06-24 Method for thread monitoring of third-party SDK

Country Status (1)

Country Link
CN (1) CN113419919A (en)

Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
KR20070038637A (en) * 2005-10-06 2007-04-11 (주)아이피엠에스 A method of data call stack tracing in data monitoring of java byte code
CN103430145A (en) * 2011-03-15 2013-12-04 英特尔公司 Page fault handling mechanism
CN108334441A (en) * 2017-01-19 2018-07-27 深圳市优朋普乐传媒发展有限公司 A kind of automated testing method and system of Software Development Kit
CN108563581A (en) * 2018-04-25 2018-09-21 咪咕文化科技有限公司 Abnormality detection processing method and processing device, electronic equipment and computer storage media
CN109960582A (en) * 2018-06-19 2019-07-02 华为技术有限公司 The method, apparatus and system of multi-core parallel concurrent are realized in the side TEE
CN111679831A (en) * 2020-06-04 2020-09-18 同盾控股有限公司 Software development kit processing method, operation monitoring method, device and storage medium
CN112287343A (en) * 2020-10-16 2021-01-29 深圳市和讯华谷信息技术有限公司 SDK monitoring method and device, computer equipment and storage medium

Patent Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
KR20070038637A (en) * 2005-10-06 2007-04-11 (주)아이피엠에스 A method of data call stack tracing in data monitoring of java byte code
CN103430145A (en) * 2011-03-15 2013-12-04 英特尔公司 Page fault handling mechanism
CN108334441A (en) * 2017-01-19 2018-07-27 深圳市优朋普乐传媒发展有限公司 A kind of automated testing method and system of Software Development Kit
CN108563581A (en) * 2018-04-25 2018-09-21 咪咕文化科技有限公司 Abnormality detection processing method and processing device, electronic equipment and computer storage media
CN109960582A (en) * 2018-06-19 2019-07-02 华为技术有限公司 The method, apparatus and system of multi-core parallel concurrent are realized in the side TEE
CN111679831A (en) * 2020-06-04 2020-09-18 同盾控股有限公司 Software development kit processing method, operation monitoring method, device and storage medium
CN112287343A (en) * 2020-10-16 2021-01-29 深圳市和讯华谷信息技术有限公司 SDK monitoring method and device, computer equipment and storage medium

Similar Documents

Publication Publication Date Title
US10795660B1 (en) Live code updates
US9891900B2 (en) Generation of specialized methods based on generic methods and type parameterizations
US6158045A (en) Portable debugging services utilizing a client debugger object and a server debugger object with flexible addressing support
US5815653A (en) Debugging system with portable debug environment-independent client and non-portable platform-specific server
US6925638B1 (en) Mutability analysis in Java
US5787245A (en) Portable debugging service utilizing a client debugger object and a server debugger object
Baker et al. Runtime aspect weaving through metaprogramming
Sato et al. A selective, just-in-time aspect weaver
Fokin et al. SmartDec: approaching C++ decompilation
Grech et al. Heaps don't lie: countering unsoundness with heap snapshots
CN110245467B (en) Android application program protection method based on Dex2C and LLVM
US8863093B1 (en) Load-time instrumentation of virtual machine program code
Bolz et al. Back to the future in one week—implementing a Smalltalk VM in PyPy
CN106293870A (en) Computer system and strategy thereof guide compression method
US9710358B2 (en) Native backtracing
US20240103821A1 (en) Optimising computer program code
Ponge et al. Golo, a dynamic, light and efficient language for post-invokedynamic jvm
Salib Faster than C: Static type inference with Starkiller
CN113419919A (en) Method for thread monitoring of third-party SDK
Jackson et al. Sourceweave. net: Cross-language aspect-oriented programming
US20020038454A1 (en) Method of compiling code in an object oriented programming language
US11288108B2 (en) Automatic out-of-bound access prevention in GPU kernels executed in a managed environment
US20110321009A1 (en) Implementing encryption via aspect oriented programming
Kozak et al. Comparing Rapid Type Analysis with Points-To Analysis in GraalVM Native Image
Pimás et al. Garbage collection and efficiency in dynamic metacircular runtimes: an experience report

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination