现在做一下记录,这个看了两天,看的过程发现了很多c++的高级特性,没接触过,还得慢慢撸,禁止很慢
那么现在开始 吧
先打两个断点
java.c:351
JavaMain(void * _args)
{
JavaMainArgs *args = (JavaMainArgs *)_args;
文件加载的断点
systemDictionary.cpp:1289
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
特别说明
如果你想在加载 特定名字的类class文件可以使用 break *** if $_streq(*,*)==0 来设断点 可参照我的上一篇文章
现在看下load_instance_class函数
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
if (class_loader.is_null()) {
// Search the shared system dictionary for classes preloaded into the
// shared spaces.
instanceKlassHandle k;
{
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
k = load_shared_class(class_name, class_loader, THREAD);
}
if (k.is_null()) {
// Use VM class loader
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
k = ClassLoader::load_classfile(class_name, CHECK_(nh));
}
// find_or_define_instance_class may return a different InstanceKlass
if (!k.is_null()) {
k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh));
}
return k;
} else {
// Use user specified class loader to load class. Call loadClass operation on class_loader.
ResourceMark rm(THREAD);
assert(THREAD->is_Java_thread(), "must be a JavaThread");
JavaThread* jt = (JavaThread*) THREAD;
PerfClassTraceTime vmtimer(ClassLoader::perf_app_classload_time(),
ClassLoader::perf_app_classload_selftime(),
ClassLoader::perf_app_classload_count(),
jt->get_thread_stat()->perf_recursion_counts_addr(),
jt->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::CLASS_LOAD);
Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nh));
// Translate to external class name format, i.e., convert '/' chars to '.'
Handle string = java_lang_String::externalize_classname(s, CHECK_(nh));
JavaValue result(T_OBJECT);
KlassHandle spec_klass (THREAD, SystemDictionary::ClassLoader_klass());
if (MustCallLoadClassInternal && has_loadClassInternal()) {
JavaCalls::call_special(&result,
class_loader,
spec_klass,
vmSymbols::loadClassInternal_name(),
vmSymbols::string_class_signature(),
string,
CHECK_(nh));
} else {
JavaCalls::call_virtual(&result,
class_loader,
spec_klass,
vmSymbols::loadClass_name(),
vmSymbols::string_class_signature(),
string,
CHECK_(nh));
}
assert(result.get_type() == T_OBJECT, "just checking");
oop obj = (oop) result.get_jobject();
// Primitive classes return null since forName() can not be
// used to obtain any of the Class objects representing primitives or void
if ((obj != NULL) && !(java_lang_Class::is_primitive(obj))) {
instanceKlassHandle k =
instanceKlassHandle(THREAD, java_lang_Class::as_Klass(obj));
// For user defined Java class loaders, check that the name returned is
// the same as that requested. This check is done for the bootstrap
// loader when parsing the class file.
if (class_name == k->name()) {
return k;
}
}
// Class is not found or has the wrong name, return NULL
return nh;
}
}
先看这个函数的参数,参数Symbol* class_name
获取符号的名字
(gdb) p class_name->as_utf8()
$3 = 0x7faadc009d08 "java/lang/Object"
看Handle定义,重点是只有一个oop* 类型的指针
class Handle VALUE_OBJ_CLASS_SPEC {
private:
oop* _handle;
protected:
oop obj() const { return _handle == NULL ? (oop)NULL : *_handle; }
oop non_null_obj() const { assert(_handle != NULL, "resolving NULL handle"); return *_handle; }
public:
// Constructors
Handle() { _handle = NULL; }
Handle(oop obj);
Handle(Thread* thread, oop obj);
// General access
oop operator () () const { return obj(); }
oop operator -> () const { return non_null_obj(); }
bool operator == (oop o) const { return obj() == o; }
bool operator == (const Handle& h) const { return obj() == h.obj(); }
// Null checks
bool is_null() const { return _handle == NULL; }
bool not_null() const { return _handle != NULL; }
// Debugging
void print() { obj()->print(); }
// Direct interface, use very sparingly.
// Used by JavaCalls to quickly convert handles and to create handles static data structures.
// Constructor takes a dummy argument to prevent unintentional type conversion in C++.
Handle(oop *handle, bool dummy) { _handle = handle; }
// Raw handle access. Allows easy duplication of Handles. This can be very unsafe
// since duplicates is only valid as long as original handle is alive.
oop* raw_value() { return _handle; }
static oop raw_resolve(oop *handle) { return handle == NULL ? (oop)NULL : *handle; }
};
其中参数赋值在这里,这个是 构造函数来创建对象
Klass* SystemDictionary::resolve_or_fail(Symbol* class_name,
bool throw_error, TRAPS)
{
return resolve_or_fail(class_name, Handle(), Handle(), throw_error, THREAD);
}
所以此时的oop* 类型的指针=null
进入接下来的流程
//流程
instanceKlassHandle SystemDictionary::load_shared_class(
Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle ik (THREAD, find_shared_class(class_name));//ik的构造函数,这个是隐式构造函数
return load_shared_class(ik, class_loader, THREAD);//if (ik->super() != NULL) {}不满足,因为ik是null 就直接返回了ik
}
};
{
instanceKlassHandle ik (THREAD, find_shared_class(class_name)); //find_shared_class(class_name)=null
};
{
instanceKlassHandle (Thread* thread, const Klass* k) : KlassHandle(thread, k) { //:后面是调用父类构造方法
assert(k == NULL || k->oop_is_instance(),
"illegal type");
}
};
在补充KlassHandle定义
class KlassHandle : public StackObj {
Klass* _value;
protected:
Klass* obj() const { return _value; }
Klass* non_null_obj() const { assert(_value != NULL, "resolving NULL _value"); return _value; }
public:
KlassHandle() : _value(NULL) {}
KlassHandle(const Klass* obj) : _value(const_cast<Klass *>(obj)) {};
KlassHandle(Thread* thread, const Klass* obj) : _value(const_cast<Klass *>(obj)) {};//构造方法, _value(xxx)初始化列表
Klass* operator () () const { return obj(); }
Klass* operator -> () const { return non_null_obj(); }
bool operator == (Klass* o) const { return obj() == o; }
bool operator == (const KlassHandle& h) const { return obj() == h.obj(); }
bool is_null() const { return _value == NULL; }
bool not_null() const { return _value != NULL; }
};
接着
instanceKlassHandle SystemDictionary::load_instance_class(Symbol* class_name, Handle class_loader, TRAPS) {
instanceKlassHandle nh = instanceKlassHandle(); // null Handle
if (class_loader.is_null()) {
// Search the shared system dictionary for classes preloaded into the
// shared spaces.
instanceKlassHandle k;
{
PerfTraceTime vmtimer(ClassLoader::perf_shared_classload_time());
k = load_shared_class(class_name, class_loader, THREAD);
}
if (k.is_null()) { //进入到这里,执行到这里,klass是null
// Use VM class loader
PerfTraceTime vmtimer(ClassLoader::perf_sys_classload_time());
k = ClassLoader::load_classfile(class_name, CHECK_(nh));
}
....
}
/进入加载文件
instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
ResourceMark rm(THREAD);
EventMark m("loading class %s", h_name->as_C_string());
ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
stringStream st;
// st.print() uses too much stack space while handling a StackOverflowError
// st.print("%s.class", h_name->as_utf8());
st.print_raw(h_name->as_utf8()); //这里能打印 name的字符串
st.print_raw(".class");
char* name = st.as_string(); //结果为:=>"java/lang/Object.class"
// Lookup stream for parsing .class file
ClassFileStream* stream = NULL;
int classpath_index = 0;
{
PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::CLASS_LOAD);
ClassPathEntry* e = _first_entry; //$6 = (LazyClassPathEntry *) 0x7faadc01a108
while (e != NULL) {
stream = e->open_stream(name, CHECK_NULL);
if (stream != NULL) {
break;
}
e = e->next();
++classpath_index;
}
}
instanceKlassHandle h;
if (stream != NULL) {
// class file found, parse it
ClassFileParser parser(stream);
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
Handle protection_domain;
TempNewSymbol parsed_name = NULL;
instanceKlassHandle result = parser.parseClassFile(h_name,
loader_data,
protection_domain,
parsed_name,
false,
CHECK_(h));
// add to package table
if (add_package(name, classpath_index, THREAD)) {
h = result;
}
}
return h;
}
ClassPathEntry这个类定义
class ClassPathEntry: public CHeapObj<mtClass> {
private:
ClassPathEntry* _next;
public:
// Next entry in class path
ClassPathEntry* next() { return _next; }
void set_next(ClassPathEntry* next) {
// may have unlocked readers, so write atomically.
OrderAccess::release_store_ptr(&_next, next);
}
virtual bool is_jar_file() = 0;
virtual const char* name() = 0;
virtual bool is_lazy();
// Constructor
ClassPathEntry();
// Attempt to locate file_name through this class path entry.
// Returns a class file parsing stream if successfull.
virtual ClassFileStream* open_stream(const char* name, TRAPS) = 0;
// Debugging
NOT_PRODUCT(virtual void compile_the_world(Handle loader, TRAPS) = 0;)
NOT_PRODUCT(virtual bool is_rt_jar() = 0;)
};
进入方法
ClassFileStream* LazyClassPathEntry::open_stream(const char* name, TRAPS) {
if (_meta_index != NULL &&
!_meta_index->may_contain(name)) {
return NULL;
}
if (_has_error) {
return NULL;
}
ClassPathEntry* cpe = resolve_entry(THREAD);
if (cpe == NULL) {
_has_error = true;
return NULL;
} else {
return cpe->open_stream(name, THREAD);//直接进入这里上边的if条件没有满足的
}
}
接着进入
ClassFileStream* ClassPathZipEntry::open_stream(const char* name, TRAPS) { //name为 $7 = 0x7faadc009ea8 "java/lang/Object.class"
// enable call to C land
JavaThread* thread = JavaThread::current();
ThreadToNativeFromVM ttn(thread);
// check whether zip archive contains name
jint filesize, name_len;
jzentry* entry = (*FindEntry)(_zip, name, &filesize, &name_len);//这里返回null,结束代码
if (entry == NULL) return NULL;
u1* buffer;
char name_buf[128];
char* filename;
if (name_len < 128) {
filename = name_buf;
} else {
filename = NEW_RESOURCE_ARRAY(char, name_len + 1);
}
// file found, get pointer to class in mmaped jar file.
if (ReadMappedEntry == NULL ||
!(*ReadMappedEntry)(_zip, entry, &buffer, filename)) {
// mmaped access not available, perhaps due to compression,
// read contents into resource array
buffer = NEW_RESOURCE_ARRAY(u1, filesize);
if (!(*ReadEntry)(_zip, entry, buffer, filename)) return NULL;
}
if (UsePerfData) {
ClassLoader::perf_sys_classfile_bytes_read()->inc(filesize);
}
// return result
return new ClassFileStream(buffer, filesize, _zip_name); // Resource allocated
}
以上是在jce.jar来查找java/lang/Object.Class,找不到就在下个循环来找
返回进入第二个循环,再次进入open_stream,但是你留心看发现进入的是ClassPathDirEntry,上一次进入的是ZIPEntry,是多态的体现
ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
// construct full path name
/**
* (gdb) p _dir
$9 = 0x7faadc06ebb8 "/home/atzhang/atzhang/openjdksource/openjdk8/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/classes"
**/
char path[JVM_MAXPATHLEN];
if (jio_snprintf(path, sizeof(path), "%s%s%s", _dir, os::file_separator(), name) == -1) {//拼接文件夹和目标类名
return NULL;
}
//(gdb) x/40s path
//0x7faae3a1cdb0: "/home/atzhang/atzhang/openjdksource/openjdk8/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/classes/java/lang/Object.class"
// check if file exists
struct stat st; //声明结构体固定格式 struct 结构体类型 变量名
if (os::stat(path, &st) == 0) {
// found file, open it
int file_handle = os::open(path, 0, 0);
if (file_handle != -1) {
// read contents into resource array
u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size);
//函数说明:read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。
size_t num_read = os::read(file_handle, (char*) buffer, st.st_size); //st_size 以字节为单位的文件容量=1734
// close file
os::close(file_handle); //关闭文件
// construct ClassFileStream
if (num_read == (size_t)st.st_size) {
if (UsePerfData) {
ClassLoader::perf_sys_classfile_bytes_read()->inc(num_read);
}
return new ClassFileStream(buffer, st.st_size, _dir); // Resource allocated
}
}
}
return NULL;
}
补充类定义
ClassPathDirEntry {
private:
char* _dir; // Name of directory
public:
bool is_jar_file() { return false; }
const char* name() { return _dir; }
ClassPathDirEntry(char* dir);
ClassFileStream* open_stream(const char* name, TRAPS);
// Debugging
NOT_PRODUCT(void compile_the_world(Handle loader, TRAPS);)
NOT_PRODUCT(bool is_rt_jar();)
};
看重点(黄色标记的)
//重点看
{
struct stat st;
if (os::stat(path, &st) == 0) {} //获取文件信息
}
(gdb) p/x st
$9 = {st_dev = 0xfd00, st_ino = 0x17b9b78, st_nlink = 0x1, st_mode = 0x81a4, st_uid = 0x0, st_gid = 0x0, __pad0 = 0x0, st_rdev = 0x0, st_size = 0x6c6, st_blksize = 0x1000, st_blocks = 0x8, st_atim = {tv_sec = 0x605bf569, tv_nsec = 0x36eea242}, st_mtim = {tv_sec = 0x60588cf6, tv_nsec = 0x2ff50a69}, st_ctim = {tv_sec = 0x60588cf6, tv_nsec = 0x2ff50a69}, __unused = {0x0, 0x0, 0x0}}
能看到stat是linux的系统函数,介绍如下
stat函数 作用:获取文件信息 函数原型:int stat(const char *path, struct stat *buf)
返回值:成功返回0,失败返回-1; 参数:文件路径(名),struct stat 类型的结构体
struct stat
{
dev_t st_dev; /* ID of device containing file */文件使用的设备号
ino_t st_ino; /* inode number */ 索引节点号
mode_t st_mode; /* protection */ 文件对应的模式,文件,目录等
nlink_t st_nlink; /* number of hard links */ 文件的硬连接数
uid_t st_uid; /* user ID of owner */ 所有者用户识别号
gid_t st_gid; /* group ID of owner */ 组识别号
dev_t st_rdev; /* device ID (if special file) */ 设备文件的设备号
off_t st_size; /* total size, in bytes */ 以字节为单位的文件容量
blksize_t st_blksize; /* blocksize for file system I/O */ 包含该文件的磁盘块的大小
blkcnt_t st_blocks; /* number of 512B blocks allocated */ 该文件所占的磁盘块
time_t st_atime; /* time of last access */ 最后一次访问该文件的时间
time_t st_mtime; /* time of last modification */ /最后一次修改该文件的时间
time_t st_ctime; /* time of last status change */ 最后一次改变该文件状态的时间
};
stat结构体中的st_mode 则定义了下列数种情况:
S_IFMT 0170000 文件类型的位遮罩
S_IFSOCK 0140000 套接字
S_IFLNK 0120000 符号连接
S_IFREG 0100000 一般文件
S_IFBLK 0060000 区块装置
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置
S_IFIFO 0010000 先进先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode) 判断是否为符号连接
S_ISREG (st_mode) 是否为一般文件
S_ISDIR (st_mode) 是否为目录
S_ISCHR (st_mode) 是否为字符装置文件
S_ISBLK (s3e) 是否为先进先出
S_ISSOCK (st_mode) 是否为socket
若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名,在linux中,最典型的就是这个/tmp目录啦。
st_mode 的结构
st_mode 主要包含了 3 部分信息:
15-12 位保存文件类型
11-9 位保存执行文件时设置的信息
8-0 位保存文件访问权限
可以通过参照来解读文件信息
接着看打开文件,读取文件,关闭文件
int file_handle = os::open(path, 0, 0);
if (file_handle != -1) {
// read contents into resource array
u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size);
//函数说明:read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。
size_t num_read = os::read(file_handle, (char*) buffer, st.st_size); //st_size 以字节为单位的文件容量=1734
// close file
os::close(file_handle); //关闭文件
接着看
// construct ClassFileStream
if (num_read == (size_t)st.st_size) {
if (UsePerfData) {
ClassLoader::perf_sys_classfile_bytes_read()->inc(num_read);
}
return new ClassFileStream(buffer, st.st_size, _dir); // Resource allocated
}
if成立,看UsePerfData
globals.hpp
#define RUNTIME_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw, lp64_product) \
\
lp64_product(bool, UseCompressedOops, false, \
"Use 32-bit object references in 64-bit VM. " \
"lp64_product means flag is always constant in 32 bit VM") \
...
product(bool, UsePerfData, falseInEmbedded, \
"Flag to disable jvmstat instrumentation for performance testing "\
"and problem isolation purposes") \
...
#define falseInEmbedded true
那么条件等于true进入里面
static PerfCounter* perf_sys_classfile_bytes_read() { return _perf_sys_classfile_bytes_read; }
还有
class PerfLongVariant : public PerfLong {
protected:
jlong* _sampled;
PerfLongSampleHelper* _sample_helper;
PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
jlong initial_value=0)
: PerfLong(ns, namep, u, v) {
if (is_valid()) *(jlong*)_valuep = initial_value;
}
PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
jlong* sampled);
PerfLongVariant(CounterNS ns, const char* namep, Units u, Variability v,
PerfLongSampleHelper* sample_helper);
void sample();
public:
inline void inc() { (*(jlong*)_valuep)++; }
inline void inc(jlong val) { (*(jlong*)_valuep) += val; }
inline void add(jlong val) { (*(jlong*)_valuep) += val; }
void clear_sample_helper() { _sample_helper = NULL; }
};
将值加上173几
接着进入
return new ClassFileStream(buffer, st.st_size, _dir); // Resource allocated
其中的参数
_dir 是
class ClassPathDirEntry: public ClassPathEntry {
private:
char* _dir; // Name of directory
(gdb) p _dir
$10= 0x7f56d806eb98 "/home/atzhang/atzhang/openjdksource/openjdk8/openjdk/build/linux-x86_64-normal-server-slowdebug/jdk/classes"
(gdb) p st.st_size
$11= 1734 =0x6c6 其实地址为 0x7f56d800ea28 结束地址为 ea28 +6c6 =f0ee
buffer 是字节码文件
(gdb) x/1734x buffer
0x7f56d800ea28: 0xbebafeca 0x34000000 0x00075700 0x01000a3a
0x7f56d800ea38: 0x000a3b00 0x0a3c0012 0x3e003d00 0x0001000a
0x7f56d800ea48: 0x4000083f 0x0012000a 0x42000a41 0x000a4300
0x7f56d800ea58: 0x07440001 0x00084500 0x0a000a46 0x00034700
0x7f56d800ea68: 0x083f420f 0x00034800 0x0a20a107 0x49001200
0x7f56d800ea78: 0x0012000a 0x4b00074a 0x3c060001 0x74696e69
0x7f56d800ea88: 0x0300013e 0x01562928 0x6f430400 0x00016564
0x7f56d800ea98: 0x6e694c0f 0x6d754e65 0x54726562 0x656c6261
0x7f56d800eaa8: 0x4c120001 0x6c61636f 0x69726156 0x656c6261
0x7f56d800eab8: 0x6c626154 0x04000165 0x73696874 0x4c120001
0x7f56d800eac8: 0x6176616a 0x6e616c2f 0x624f2f67 0x7463656a
0x7f56d800ead8: 0x0f00013b 0x69676572 0x72657473 0x6974614e
0x7f56d800eae8: 0x01736576 0x65670800 0x616c4374 0x00017373
0x7f56d800eaf8: 0x4c292813 0x6176616a 0x6e616c2f 0x6c432f67
0x7f56d800eb08: 0x3b737361 0x53090001 0x616e6769 0x65727574
0x7f56d800eb18: 0x28160001 0x616a4c29 0x6c2f6176 0x2f676e61
0x7f56d800eb28: 0x73616c43 0x3e2a3c73 0x0800013b 0x68736168
0x7f56d800eb38: 0x65646f43 0x28030001 0x00014929 0x75716506
0x7f56d800eb48: 0x01736c61 0x4c281500 0x6176616a 0x6e616c2f
0x7f56d800eb58: 0x624f2f67 0x7463656a 0x015a293b 0x626f0300
0x7f56d800eb68: 0x0d00016a 0x63617453 0x70614d6b 0x6c626154
0x7f56d800eb78: 0x05000165 0x6e6f6c63 0x14000165 0x6a4c2928
0x7f56d800eb88: 0x2f617661 0x676e616c 0x6a624f2f 0x3b746365
0x7f56d800eb98: 0x450a0001 0x70656378 0x6e6f6974 0x4c000773
0x7f56d800eba8: 0x74080001 0x7274536f 0x01676e69 0x29281400
0x7f56d800ebb8: 0x76616a4c 0x616c2f61 0x532f676e 0x6e697274
0x7f56d800ebc8: 0x00013b67 0x746f6e06 0x01796669 0x6f6e0900
0x7f56d800ebd8: 0x79666974 0x016c6c41 0x61770400 0x00017469
0x7f56d800ebe8: 0x294a2804 0x4d000756 0x28050001 0x5629494a
0x7f56d800ebf8: 0x74070001 0x6f656d69 0x00017475 0x00014a01
0x7f56d800ec08: 0x6e616e05 0x0001736f 0x00014901 0x6e696608
0x7f56d800ec18: 0x7a696c61 0x4e000765 0x3c080001 0x6e696c63
0x7f56d800ec28: 0x013e7469 0x6f530a00 0x65637275 0x656c6946
0x7f56d800ec38: 0x4f0b0001 0x63656a62 0x616a2e74 0x00016176
0x7f56d800ec48: 0x76616a17 0x616c2f61 0x532f676e 0x6e697274
0x7f56d800ec58: 0x69754267 0x7265646c 0x0013000c 0x1b000c14
0x7f56d800ec68: 0x00071c00 0x50000c4f 0x000c2a00 0x01520051
0x7f56d800ec78: 0x0c400100 0x20001f00 0x0c530007 0x55005400
0x7f56d800ec88: 0x0029000c 0x2200012a 0x6176616a 0x6e616c2f
0x7f56d800ec98: 0x6c492f67 0x6167656c 0x6772416c 0x6e656d75
0x7f56d800eca8: 0x63784574 0x69747065 0x00016e6f 0x6d697419
0x7f56d800ecb8: 0x74756f65 0x6c617620 0x69206575 0x656e2073
0x7f56d800ecc8: 0x69746167 0x000c6576 0x01560013 0x616e2500
0x7f56d800ecd8: 0x65736f6e 0x646e6f63 0x6d697420 0x74756f65
0x7f56d800ece8: 0x6c617620 0x6f206575 0x6f207475 0x61722066
0x7f56d800ecf8: 0x0c65676e 0x2e002d00 0x001a000c 0x10000114
0x7f56d800ed08: 0x6176616a 0x6e616c2f 0x624f2f67 0x7463656a
0x7f56d800ed18: 0x6a240001 0x2f617661 0x676e616c 0x6f6c432f
0x7f56d800ed28: 0x6f4e656e 0x70755374 0x74726f70 0x78456465
0x7f56d800ed38: 0x74706563 0x016e6f69 0x616a1e00 0x6c2f6176
0x7f56d800ed48: 0x2f676e61 0x65746e49 0x70757272 0x45646574
0x7f56d800ed58: 0x70656378 0x6e6f6974 0x6a130001 0x2f617661
0x7f56d800ed68: 0x676e616c 0x7268542f 0x6261776f 0x0001656c
0x7f56d800ed78: 0x76616a0f 0x616c2f61 0x432f676e 0x7373616c
0x7f56d800ed88: 0x67070001 0x614e7465 0x0001656d 0x70706106
0x7f56d800ed98: 0x01646e65 0x4c282d00 0x6176616a 0x6e616c2f
0x7f56d800eda8: 0x74532f67 0x676e6972 0x6a4c293b 0x2f617661
0x7f56d800edb8: 0x676e616c 0x7274532f 0x42676e69 0x646c6975
0x7f56d800edc8: 0x013b7265 0x616a1100 0x6c2f6176 0x2f676e61
0x7f56d800edd8: 0x65746e49 0x01726567 0x6f740b00 0x53786548
0x7f56d800ede8: 0x6e697274 0x15000167 0x4c294928 0x6176616a
0x7f56d800edf8: 0x6e616c2f 0x74532f67 0x676e6972 0x1500013b
0x7f56d800ee08: 0x616a4c28 0x6c2f6176 0x2f676e61 0x69727453
0x7f56d800ee18: 0x293b676e 0x00210056 0x00000012 0x00000000
0x7f56d800ee28: 0x0001000e 0x00140013 0x00150001 0x002b0000
0x7f56d800ee38: 0x00010000 0xb1010000 0x02000000 0x00001600
0x7f56d800ee48: 0x01000600 0x25000000 0x00001700 0x01000c00
0x7f56d800ee58: 0x01000000 0x19001800 0x0a010000 0x14001a00
0x7f56d800ee68: 0x11010000 0x1c001b00 0x1d000100 0x02000000
0x7f56d800ee78: 0x01011e00 0x20001f00 0x01000000 0x22002100
0x7f56d800ee88: 0x15000100 0x4a000000 0x02000200 0x0b000000
0x7f56d800ee98: 0x00a62b2a 0x00a70407 0x00ac0304 0x00030000
0x7f56d800eea8: 0x00000016 0x00010006 0x00950000 0x00000017
0x7f56d800eeb8: 0x00020016 0x000b0000 0x00190018 0x00000000
0x7f56d800eec8: 0x0023000b 0x00010019 0x00000024 0x09020005
0x7f56d800eed8: 0x04010140 0x26002500 0x27000100 0x04000000
0x7f56d800eee8: 0x28000100 0x29000100 0x01002a00 0x00001500
0x7f56d800eef8: 0x02004e00 0x00000100 0x00bb2400 0x00b75901
0x7f56d800ef08: 0x00b62a02 0x0400b603 0x120500b6 0x0500b606
0x7f56d800ef18: 0x0700b62a 0xb60800b8 0x00b60500 0x0000b009
0x7f56d800ef28: 0x16000200 0x06000000 0x00000100 0x1700ec00
0x7f56d800ef38: 0x0c000000 0x00000100 0x18002400 0x00001900
0x7f56d800ef48: 0x2b001101 0x00001400 0x2c001101 0x00001400
0x7f56d800ef58: 0x2d001101 0x01002e00 0x00002700 0x01000400
0x7f56d800ef68: 0x11002f00 0x30002d00 0x15000200 0xa5000000
0x7f56d800ef78: 0x04000400 0x3e000000 0x9c94091f 0x00bb0d00
0x7f56d800ef88: 0x0b12590a 0xbf0c00b7 0x09009b1d 0xa40d121d
0x7f56d800ef98: 0x00bb0d00 0x0e12590a 0xbf0c00b7 0xa20f121d
0x7f56d800efa8: 0x991d0d00 0x091f0d00 0x07009a94 0x40610a1f
0x7f56d800efb8: 0x00b61f2a 0x0000b110 0x16000300 0x22000000
0x7f56d800efc8: 0x00000800 0x0600bf01 0x1000c001 0x1a00c301
0x7f56d800efd8: 0x2400c401 0x3400c801 0x3800c901 0x3d00cc01
0x7f56d800efe8: 0x1700cd01 0x20000000 0x00000300 0x18003e00
0x7f56d800eff8: 0x00001900 0x3e000000 0x32003100 0x00000100
0x7f56d800f008: 0x33003e00 0x03003400 0x00002400 0x05000700
0x7f56d800f018: 0x0f090910 0x00270003 0x00040000 0x002f0001
0x7f56d800f028: 0x002d0011 0x00020014 0x00000015 0x00030034
0x7f56d800f038: 0x00000001 0xb6092a06 0x00b11000 0x00020000
0x7f56d800f048: 0x00000016 0x0002000a 0x00f60100 0x00f70105
0x7f56d800f058: 0x00000017 0x0001000c 0x00060000 0x00190018
0x7f56d800f068: 0x00270000 0x00040000 0x002f0001 0x00350004
0x7f56d800f078: 0x00020014 0x00000015 0x0000002b 0x00000001
0x7f56d800f088: 0x0000b101 0x16000200 0x06000000 0x00000100
0x7f56d800f098: 0x17002b02 0x0c000000 0x00000100 0x18000100
0x7f56d800f0a8: 0x00001900 0x00002700 0x01000400 0x08003600
0x7f56d800f0b8: 0x14003700 0x15000100 0x20000000 0x00000000
0x7f56d800f0c8: 0x04000000 0xb11100b8 0x01000000 0x00001600
0x7f56d800f0d8: 0x02000a00 0x29000000 0x2a000300 0x38000100
0x7f56d800f0e8: 0x02000000 0xabab3900 0xabababab 0xabababab
今天到此结束
具体之中有有许多细节总结下
1、 c++构造方法;
子类构造方法:父类构造方法{
}
2、 结构体的生命;
struct stat st; //c必须有struct来声明
stat st;// c++可以可以省略struct
3、 使用构造方法来建造对象;
return resolve_or_fail(class_name, Handle(), Handle(), throw_error, THREAD);
4、 使用gdb的内置函数来设置断点条件;
if $_strcmp("hello","hello")==00
if $_memcmp(参数1,参数2)==00