std::string getValue(const TypeBase* tb, const void* addr, TypeBase::PrintFormat fmt) { StringPrintFunctor spf; //const char *caddr = (const char*)addr; // this isn't always true because some values has been evaluated in memory, should be a flag stating if this is the case. //if(caddr<gMemBuf || caddr+tb->size()>&gMemBuf[gMemSize]) return ""; tb->printMI(spf, addr, fmt); // special treatment for (const) char* and char[]. // first check if it's a pointer or array, and if so, find its target/element type. const TypeBase* target = NULL; if(tb->type() == TypeBase::ePointer) target = ((const PointerType*)tb)->mTarget; else if(tb->type() == TypeBase::eArray) target = ((const ArrayType*)tb)->mElemType; if(target != NULL) { // skip past the "const" container type. if(target->type() == TypeBase::eConst) { target = ((const ConstType*)target)->mTarget; } // then check if it's builtin->char. if(target->type() == TypeBase::eBuiltin) { const Builtin* builtin = (const Builtin*)target; if(builtin->subType() == Builtin::eChar) { int msAddr = *(int*)addr; if(msAddr<gMemSize) { int msLen = MAX_STRING_SIZE; if(msAddr+msLen>gMemSize) { msLen-= (msAddr+msLen)-gMemSize; } if(msLen > 0 && msAddr > 0) { //spf(" \\\"%.*s\\\"", msLen, &gMemBuf[msAddr]); // convert line endings to avoid breaking the GDB/MI protocol, // which mandates that every output unit be contained on a single line. spf(" \\\""); const char* p = &gMemBuf[msAddr]; const char* end = p + msLen; while(p != end) { if(*p == '\n') { spf("\\n"); } else { spf("%c", *p); } p++; } spf("\\\""); } } } } } if(spf.length() <= 0) { error("Evaluation failed.\n"); } return spf.getString(); }
void Variable::addStruct(const char* dataAdress, const StructType *structType, bool shouldCreateChildren, bool isPointer, bool invalidMemory) { const vector<BaseClass>& bases = structType->getBases(); const vector<DataMember>& dataMembers = structType->getDataMembers(); std::string value = ""; if(!isPointer) { std::string type = getType(structType, false); this->exp->updateData(value, type, structType->isSimpleValue()); } // children.resize(bases.size()+dataMembers.size()); // add private/public/protected variables.. for(size_t i = 0; i < dataMembers.size(); i++) { const TypeBase* deref = dataMembers[i].type->resolve(); deref = convertConstType(deref); if(isVTablePointer(deref)) continue; string virtualVarName = getVisibilityString(dataMembers[i].visibility); Variable& virtualVar = children[bases.size()+(int)dataMembers[i].visibility]; virtualVar.localName = virtualVarName; virtualVar.exp = NULL; virtualVar.name = name + "." + virtualVarName; virtualVar.mHasCreatedChildren = true; virtualVar.outOfScope = false; sVariableMap[virtualVar.name] = &virtualVar; } if(!shouldCreateChildren) { mHasCreatedChildren = false; //return; } mHasCreatedChildren = true; for(size_t i = 0; i < bases.size(); i++) { const TypeBase* deref = bases[i].type->resolve(); string varName = ((StructType*)deref)->mName.c_str(); Variable& var = children[i]; { var.outOfScope = false; var.printFormat = TypeBase::eNatural; string type = getType(deref, false); StringPrintFunctor spf; spf("%s.%s", name.c_str(), varName.c_str()); var.name = spf.getString(); spf.reset(); var.localName = varName; //if(isPointer) spf("((%s *)(%s))", type.c_str(), exp->mExprText.c_str()); if(isPointer) spf("((%s)(*(%s)))", type.c_str(), exp->mExprText.c_str()); else spf("((%s)(%s))", type.c_str(), exp->mExprText.c_str()); var.exp = new Expression(exp->mFrameAddr, spf.getString()); spf.reset(); } sVariableMap[var.name] = &var; if(shouldCreateChildren) var.addStruct(dataAdress+bases[i].offset, (const StructType*)deref, false, false, invalidMemory); } for(size_t i = 0; i < dataMembers.size(); i++) { const TypeBase* deref = dataMembers[i].type->resolve(); deref = convertConstType(deref); if(isVTablePointer(deref)) continue; string virtualVarName = getVisibilityString(dataMembers[i].visibility); Variable& virtualVar = children[bases.size()+(int)dataMembers[i].visibility]; string varName = dataMembers[i].name; sVariableMap[virtualVar.name] = &virtualVar; Variable& var = virtualVar.children[i]; { var.outOfScope = false; var.printFormat = TypeBase::eNatural; string type = getType(deref, false); StringPrintFunctor spf; spf("%s.%s", virtualVar.name.c_str(), varName.c_str()); var.name = spf.getString(); spf.reset(); var.localName = varName; if(isPointer) spf("(%s)->%s", exp->mExprText.c_str(), dataMembers[i].name.c_str()); else spf("(%s).%s", exp->mExprText.c_str(), dataMembers[i].name.c_str()); var.exp = new Expression(exp->mFrameAddr, spf.getString()); spf.reset(); } sVariableMap[var.name] = &var; if(shouldCreateChildren) { const char* childAddress = invalidMemory ? NULL : dataAdress+(dataMembers[i].offsetBits>>3); if(deref->type() == TypeBase::eArray) { var.addArray(childAddress, (ArrayType*)deref, false, invalidMemory); } else if(deref->type() == TypeBase::eStruct) { var.addStruct(childAddress, (StructType*)deref, false, false, invalidMemory); } else if(deref->type() == TypeBase::ePointer) { var.addPointer(childAddress, (PointerType*)deref, false, invalidMemory); } else { value = ""; if(dataAdress && !invalidMemory) value = getValue(deref, childAddress, var.printFormat); var.exp->updateData( value, getType(deref, false), deref->isSimpleValue()); } } } }
void Variable::addPointer(const char* dataAdress, const PointerType *pointerType, bool shouldCreateChildren, bool invalidMemory) { const TypeBase* deref = ((const PointerType*)pointerType)->deref()->resolve(); deref = convertConstType(deref); std::string type = getType(pointerType, false); std::string value = ""; if(dataAdress) value = getValue(pointerType, dataAdress, printFormat); bool simpleType = pointerType->isSimpleValue(); this->exp->updateData(value, type, simpleType); if(deref->type() == TypeBase::eBuiltin && ((Builtin*)deref)->mSubType==Builtin::eVoid) { // if it's a void-pointer we don't know the size of the data it is pointing to, thus we don´t give the variable a child. return; } //children.resize(1); if(!shouldCreateChildren) { if(deref->type() != TypeBase::eStruct) { StringPrintFunctor spf; spf("*(%s)", localName.c_str()); string varName = spf.getString(); spf.reset(); children[0].localName = varName; } else { addStruct(NULL, (StructType*)deref, false, true, true); } mHasCreatedChildren = false; return; } mHasCreatedChildren = true; const char* childAddress = NULL; if(!invalidMemory) { int addr = *((int*)dataAdress); childAddress = &gMemBuf[addr]; } if(deref->type() != TypeBase::eStruct) { StringPrintFunctor spf; spf("*(%s)", localName.c_str()); string varName = spf.getString(); spf.reset(); // Variable& var = children[varName]; Variable& var = children[0]; { var.outOfScope = false; var.printFormat = TypeBase::eNatural; //StringPrintFunctor spf; spf("%s.%s", name.c_str(), varName.c_str()); var.name = spf.getString(); spf.reset(); var.localName = varName; spf("*(%s)", exp->mExprText.c_str()); var.exp = new Expression(exp->mFrameAddr, spf.getString()); spf.reset(); } if(deref->type() == TypeBase::eArray) { var.addArray(childAddress, (ArrayType*)deref, false, invalidMemory); } else if(deref->type() == TypeBase::ePointer) { var.addPointer(childAddress, (PointerType*)deref, false, invalidMemory); } else { value = ""; if(!invalidMemory) { value = getValue(pointerType, childAddress, printFormat); } var.exp->updateData( value, getType(deref, false), deref->isSimpleValue()); } sVariableMap[var.name] = &var; } else { if(invalidMemory) { addStruct(NULL, (StructType*)deref, true, true, invalidMemory); } else { addStruct(childAddress, (StructType*)deref, true, true, invalidMemory); } } }
void Variable::addArray(const char* dataAdress, const ArrayType *arrayType, bool shouldCreateChildren, bool invalidMemory) { const TypeBase* deref = ((const ArrayType*)arrayType)->mElemType->resolve(); deref = convertConstType(deref); std::string type = getType(arrayType, false); std::string value = ""; this->exp->updateData(value, type, arrayType->isSimpleValue()); for(int i = 0; i < arrayType->mLength; i++) { Variable& var = children[i]; StringPrintFunctor spf; spf("[%d]", i); string varName = spf.getString(); spf.reset(); //Variable& var = children[varName]; var.name = name+"."+varName; var.outOfScope = false; var.printFormat = TypeBase::eNatural; } //children.resize(arrayType->mLength); if(!shouldCreateChildren) { mHasCreatedChildren = false; return; } mHasCreatedChildren = true; for(int i = 0; i < arrayType->mLength; i++) { StringPrintFunctor spf; spf("[%d]", i); string varName = spf.getString(); spf.reset(); // Variable& var = children[varName]; Variable& var = children[i]; { /* var.outOfScope = false; var.printFormat = TypeBase::eNatural; //StringPrintFunctor spf; spf("%s.%s", name.c_str(), varName.c_str()); var.name = spf.getString(); spf.reset(); */ var.localName = varName; spf("(%s)[%d]", exp->mExprText.c_str(), i); var.exp = new Expression(exp->mFrameAddr, spf.getString()); spf.reset(); } sVariableMap[var.name] = &var; const char* childAddress = invalidMemory ? NULL : dataAdress+i*deref->size(); if(deref->type() == TypeBase::eArray) { var.addArray(childAddress, (ArrayType*)deref, false, invalidMemory); } else if(deref->type() == TypeBase::eStruct) { var.addStruct(childAddress, (StructType*)deref, false, invalidMemory); } else if(deref->type() == TypeBase::ePointer) { var.addPointer(childAddress, (PointerType*)deref, false, invalidMemory); } else { value = ""; if(!invalidMemory && dataAdress) value = getValue(deref, childAddress, var.printFormat); var.exp->updateData( value, getType(deref, false), deref->isSimpleValue()); } } }
std::string getType(const TypeBase *tb, bool complex) { StringPrintFunctor spf; tb->printTypeMI(spf, complex); return spf.getString(); }