-
目的
为了更方便的调试AntDB,生成gdb调试脚本。
-
gdb调试脚本gengdb.sh
# !/bin/bash
# Author Sunny
# Version 2016-11-11
function Usage()
{
echo "\
Help
Just keep enum NodeTag which read from the
file src/include/nodes/nodes.h saving in the
file node.txt of current path." && exit 1
}
if [ $# -gt 0 ] || [ "x$1" = "-h" ] || [ "x$1" = "--help" ]; then
Usage
fi
# define input and output file
curdir=$(pwd)
input="$curdir/node.txt"
output="$curdir/my.gdb"
nodeinfo="$curdir/node.out"
gdbinit="$curdir/gdbinit"
[ ! -e $input ] && echo "no input file, quit" && exit 1
[ -e $output ] && mv $output $output""_$(date +%F_%T)
[ -e $nodeinfo ] && rm -rf $nodeinfo
[ -e $gdbinit ] && rm -rf $gdbinit
function generate_print_node()
{
# define step number
step=20
# preprocess the input file
declare -a nodes
nodes=($(grep -Eo 'T_[A-Za-z_]+' $input | grep -v "T_Invalid"))
for node in ${nodes[@]}
do
echo "$node" >> $nodeinfo
done
total=${#nodes[@]}
echo "\
define pnode
if \$argc == 0
help pnode
else
while \$arg0
" >> $output
# define pnode
for ((cnt=0; cnt<$total; cnt+=$step))
do
let idx=$cnt+$step-1
[ $idx -ge $total ] && let idx=$total-1
curnode=${nodes[$idx]%,*}
echo "\
if ((const Node *)(\$arg0))->type <= $curnode
lesseq$curnode (\$arg0)
loop_break
end
" >> $output
done
echo "\
print (char*) \$arg0
loop_break
end
end
end
" >> $output
# define pnode help
echo "\
document pnode
Usage:
pnode node variable / node address
Print node infomation
end
" >> $output
# define each step circle lesseq"T_node"
for ((cnt=0; cnt<$total; cnt+=$step))
do
let idx=$cnt+$step-1
[ $idx -ge $total ] && let idx=$total-1
curnode=${nodes[$idx]%,*}
echo "\
define lesseq$curnode
while \$arg0
" >>$output
let i=0
while ((i<$step))
do
let idx=$cnt+$i
[ $idx -ge $total ] && break
tnode=${nodes[$idx]%,*}
node=${tnode#*_}
if [ "x$tnode" = "xT_Integer" ]; then
echo "\
if ((const Node *)(\$arg0))->type == $tnode
print ((const Value *)(\$arg0))->val.ival
loop_break
end
" >> $output
elif [ "x$tnode" = "xT_Float" ] || [ "x$tnode" = "xT_String" ] || [ "x$tnode" = "xT_BitString" ]; then
echo "\
if ((const Node *)(\$arg0))->type == $tnode
print ((const Value *)(\$arg0))->val.str
loop_break
end
" >> $output
elif [ "x$tnode" = "xT_Null" ]; then
echo "\
if ((const Node *)(\$arg0))->type == $tnode
print *(const Value *)(\$arg0)
loop_break
end
" >> $output
else
echo "\
if ((const Node *)(\$arg0))->type == $tnode
print *(const $node *) (\$arg0)
loop_break
end
" >> $output
fi
let i++
done
echo "\
loop_break
end
end
" >> $output
done
}
function generate_print_list()
{
echo '
define plist
if $argc == 0
help plist
else
if $arg0 && ((const Node*)($arg0))->type == T_List
ppointerlist $arg0
else
if $arg0 && ((const Node*)($arg0))->type == T_IntList
pintlist $arg0
else
if $arg0 && ((const Node*)($arg0))->type == T_OidList
poidlist $arg0
else
printf "$arg0 is null pointer"
end
end
end
end
end
document plist
Usage:
plist list variable / list address
Print each element in the list
end
define ppointerlist
set $size = ((const List*)($arg0))->length
if $size == 0
printf "$arg0 is empty"
else
set $current = ((const List*)($arg0))->head
while $current != 0
pnode $current->data.ptr_value
set $current = $current->next
end
end
end
define pintlist
set $size = ((const List*)($arg0))->length
if $size == 0
printf "$arg0 is empty"
else
set $current = ((const List*)($arg0))->head
while $current != 0
print $current->data.int_value
set $current = $current->next
end
end
end
define poidlist
set $size = ((const List*)($arg0))->length
if $size == 0
printf "$arg0 is empty"
else
set $current = ((const List*)($arg0))->head
while $current != 0
print $current->data.oid_value
set $current = $current->next
end
end
end
' >> $output
}
function generate_copyright()
{
echo "\
# -------------------------------------------------------------------
# Program $(basename $0)
# Author Sunny
# Version $(date +%F_%T)
#
# Usage
#
# write \"source $output\" to ~/.gdbinit
# -------------------------------------------------------------------" >> $output
}
function generate_gdbinit()
{
echo "\
source $output" > $gdbinit
}
function main()
{
generate_copyright;
generate_print_list;
generate_print_node;
generate_gdbinit;
}
main
-
生成gdb文件
-
将 src/include/nodes/nodes.h 文件中定义的 enum NodeTag 拷贝到与当前脚本同级的目录下的 node.txt 文件。
typedef enum NodeTag { T_Invalid = 0, /* * TAGS FOR EXECUTOR NODES (execnodes.h) */ T_IndexInfo = 10, T_ExprContext, T_ProjectionInfo, T_JunkFilter, T_ResultRelInfo, T_EState, T_TupleTableSlot, /* * TAGS FOR PLAN NODES (plannodes.h) */ T_Plan = 100, T_Result, T_ModifyTable, T_Append, T_MergeAppend, T_RecursiveUnion, T_BitmapAnd, T_BitmapOr, T_Scan, T_SeqScan, T_SampleScan, T_IndexScan, T_IndexOnlyScan, T_BitmapIndexScan, T_BitmapHeapScan, T_TidScan, T_SubqueryScan, T_FunctionScan, T_ValuesScan, T_CteScan, T_WorkTableScan, T_ForeignScan, T_CustomScan, T_Join, T_NestLoop, T_MergeJoin, T_HashJoin, T_Material, T_Sort, T_Group, T_Agg, T_WindowAgg, T_Unique, T_Gather, T_GatherMerge, T_Hash, T_SetOp, T_LockRows, T_Limit, /* these aren't subclasses of Plan: */ T_NestLoopParam, T_PlanRowMark, T_PlanInvalItem, #ifdef ADB /* * TAGS FOR PGXC NODES * (planner.h, locator.h, nodemgr.h, groupmgr.h) */ T_ExecNodes, T_SimpleSort, T_RemoteQuery, T_AlterNodeStmt, T_CreateNodeStmt, T_DropNodeStmt, T_CreateGroupStmt, T_DropGroupStmt, T_ClusterGather, T_ClusterMergeGather, T_ClusterGetCopyData, T_ClusterReduce, T_ReduceScan, #endif /* * TAGS FOR PLAN STATE NODES (execnodes.h) * * These should correspond one-to-one with Plan node types. */ T_PlanState = 200, T_ResultState, T_ModifyTableState, T_AppendState, T_MergeAppendState, T_RecursiveUnionState, T_BitmapAndState, T_BitmapOrState, T_ScanState, T_SeqScanState, T_SampleScanState, T_IndexScanState, T_IndexOnlyScanState, T_BitmapIndexScanState, T_BitmapHeapScanState, T_TidScanState, T_SubqueryScanState, T_FunctionScanState, T_ValuesScanState, T_CteScanState, T_WorkTableScanState, T_ForeignScanState, T_CustomScanState, T_JoinState, T_NestLoopState, T_MergeJoinState, T_HashJoinState, T_MaterialState, T_SortState, T_GroupState, T_AggState, T_WindowAggState, T_UniqueState, T_GatherState, T_GatherMergeState, T_HashState, T_SetOpState, T_LockRowsState, T_LimitState, #ifdef ADB T_RemoteCopyState, T_RemoteQueryState, T_ClusterGatherState, T_ClusterMergeGatherState, T_ClusterGetCopyDataState, T_ClusterReduceState, T_ReduceScanState, #endif /* * TAGS FOR PRIMITIVE NODES (primnodes.h) */ T_Alias = 300, T_RangeVar, T_Expr, T_Var, T_Const, T_Param, T_Aggref, T_GroupingFunc, T_WindowFunc, T_ArrayRef, T_FuncExpr, T_NamedArgExpr, T_OpExpr, T_DistinctExpr, T_NullIfExpr, T_ScalarArrayOpExpr, T_BoolExpr, T_SubLink, T_SubPlan, T_AlternativeSubPlan, T_FieldSelect, T_FieldStore, T_RelabelType, T_CoerceViaIO, T_ArrayCoerceExpr, T_ConvertRowtypeExpr, T_CollateExpr, T_CaseExpr, T_CaseWhen, T_CaseTestExpr, T_ArrayExpr, T_RowExpr, T_RowCompareExpr, T_CoalesceExpr, T_MinMaxExpr, T_XmlExpr, T_NullTest, T_BooleanTest, T_CoerceToDomain, T_CoerceToDomainValue, T_SetToDefault, T_CurrentOfExpr, #ifdef ADB T_RownumExpr, T_LevelExpr, T_OidVectorLoopExpr, #endif T_InferenceElem, T_TargetEntry, T_RangeTblRef, T_JoinExpr, T_FromExpr, T_OnConflictExpr, T_IntoClause, #ifdef ADB T_DistributeBy, T_PGXCSubCluster, #endif /* * TAGS FOR EXPRESSION STATE NODES (execnodes.h) * * These correspond (not always one-for-one) to primitive nodes derived * from Expr. */ T_ExprState = 400, T_GenericExprState, T_WholeRowVarExprState, T_AggrefExprState, T_GroupingFuncExprState, T_WindowFuncExprState, T_ArrayRefExprState, T_FuncExprState, T_ScalarArrayOpExprState, T_BoolExprState, T_SubPlanState, T_AlternativeSubPlanState, T_FieldSelectState, T_FieldStoreState, T_CoerceViaIOState, T_ArrayCoerceExprState, T_ConvertRowtypeExprState, T_CaseExprState, T_CaseWhenState, T_ArrayExprState, T_RowExprState, T_RowCompareExprState, T_CoalesceExprState, T_MinMaxExprState, T_XmlExprState, T_NullTestState, T_CoerceToDomainState, T_DomainConstraintState, #ifdef ADB T_RownumExprState, T_OidVectorLoopExprState, #endif /* * TAGS FOR PLANNER NODES (relation.h) */ T_PlannerInfo = 500, T_PlannerGlobal, T_RelOptInfo, T_IndexOptInfo, T_ForeignKeyOptInfo, T_ParamPathInfo, T_Path, T_IndexPath, T_BitmapHeapPath, T_BitmapAndPath, T_BitmapOrPath, T_TidPath, T_SubqueryScanPath, T_ForeignPath, T_CustomPath, T_NestPath, T_MergePath, T_HashPath, T_AppendPath, T_MergeAppendPath, T_ResultPath, T_MaterialPath, T_UniquePath, T_GatherPath, T_GatherMergePath, T_ProjectionPath, T_SortPath, T_GroupPath, T_UpperUniquePath, T_AggPath, T_GroupingSetsPath, T_MinMaxAggPath, T_WindowAggPath, T_SetOpPath, T_RecursiveUnionPath, T_LockRowsPath, T_ModifyTablePath, T_LimitPath, #ifdef ADB T_RemoteQueryPath, T_ClusterGatherPath, T_ClusterMergeGatherPath, T_ClusterReducePath, T_ReduceScanPath, T_FilterPath, #endif /* these aren't subclasses of Path: */ T_EquivalenceClass, T_EquivalenceMember, T_PathKey, T_PathTarget, T_RestrictInfo, T_PlaceHolderVar, T_SpecialJoinInfo, T_AppendRelInfo, T_PlaceHolderInfo, T_MinMaxAggInfo, T_PlannerParamItem, /* * TAGS FOR MEMORY NODES (memnodes.h) */ T_MemoryContext = 600, T_AllocSetContext, /* * TAGS FOR VALUE NODES (value.h) */ T_Value = 650, T_Integer, T_Float, T_String, T_BitString, T_Null, /* * TAGS FOR LIST NODES (pg_list.h) */ T_List, T_IntList, T_OidList, /* * TAGS FOR EXTENSIBLE NODES (extensible.h) */ T_ExtensibleNode, /* * TAGS FOR STATEMENT NODES (mostly in parsenodes.h) */ T_Query = 700, T_PlannedStmt, T_InsertStmt, T_DeleteStmt, T_UpdateStmt, T_SelectStmt, T_AlterTableStmt, T_AlterTableCmd, T_AlterDomainStmt, T_SetOperationStmt, T_GrantStmt, T_GrantRoleStmt, T_AlterDefaultPrivilegesStmt, T_ClosePortalStmt, T_ClusterStmt, T_CopyStmt, T_CreateStmt, T_DefineStmt, T_DropStmt, T_TruncateStmt, T_CommentStmt, T_FetchStmt, T_IndexStmt, T_CreateFunctionStmt, T_AlterFunctionStmt, T_DoStmt, T_RenameStmt, T_RuleStmt, T_NotifyStmt, T_ListenStmt, T_UnlistenStmt, T_TransactionStmt, T_ViewStmt, T_LoadStmt, T_CreateDomainStmt, T_CreatedbStmt, T_DropdbStmt, T_VacuumStmt, T_ExplainStmt, T_CreateTableAsStmt, T_CreateSeqStmt, T_AlterSeqStmt, T_VariableSetStmt, T_VariableShowStmt, T_DiscardStmt, T_CreateTrigStmt, T_CreatePLangStmt, T_CreateRoleStmt, T_AlterRoleStmt, T_DropRoleStmt, T_LockStmt, T_ConstraintsSetStmt, T_ReindexStmt, T_CheckPointStmt, T_CreateSchemaStmt, T_AlterDatabaseStmt, T_AlterDatabaseSetStmt, T_AlterRoleSetStmt, T_CreateConversionStmt, T_CreateCastStmt, T_CreateOpClassStmt, T_CreateOpFamilyStmt, T_AlterOpFamilyStmt, T_PrepareStmt, T_ExecuteStmt, T_DeallocateStmt, T_DeclareCursorStmt, T_CreateTableSpaceStmt, T_DropTableSpaceStmt, T_AlterObjectDependsStmt, T_AlterObjectSchemaStmt, T_AlterOwnerStmt, T_AlterOperatorStmt, T_DropOwnedStmt, T_ReassignOwnedStmt, T_CompositeTypeStmt, T_CreateEnumStmt, T_CreateRangeStmt, T_AlterEnumStmt, T_AlterTSDictionaryStmt, T_AlterTSConfigurationStmt, T_CreateFdwStmt, T_AlterFdwStmt, T_CreateForeignServerStmt, T_AlterForeignServerStmt, T_CreateUserMappingStmt, T_AlterUserMappingStmt, T_DropUserMappingStmt, #ifdef ADB T_ExecDirectStmt, T_CleanConnStmt, #endif T_AlterTableSpaceOptionsStmt, T_AlterTableMoveAllStmt, T_SecLabelStmt, T_CreateForeignTableStmt, T_ImportForeignSchemaStmt, T_CreateExtensionStmt, T_AlterExtensionStmt, T_AlterExtensionContentsStmt, T_CreateEventTrigStmt, T_AlterEventTrigStmt, T_RefreshMatViewStmt, T_ReplicaIdentityStmt, T_AlterSystemStmt, T_CreatePolicyStmt, T_AlterPolicyStmt, T_CreateTransformStmt, T_CreateAmStmt, #ifdef ADB T_BarrierStmt, #endif /* * TAGS FOR PARSE TREE NODES (parsenodes.h) */ T_A_Expr = 900, T_ColumnRef, #ifdef ADB T_ColumnRefJoin, T_PriorExpr, #endif T_ParamRef, T_A_Const, T_FuncCall, T_A_Star, T_A_Indices, T_A_Indirection, T_A_ArrayExpr, T_ResTarget, T_MultiAssignRef, T_TypeCast, T_CollateClause, T_SortBy, T_WindowDef, T_RangeSubselect, T_RangeFunction, T_RangeTableSample, T_TypeName, T_ColumnDef, T_IndexElem, T_Constraint, T_DefElem, T_RangeTblEntry, T_RangeTblFunction, T_TableSampleClause, T_WithCheckOption, T_SortGroupClause, T_GroupingSet, T_WindowClause, T_FuncWithArgs, T_AccessPriv, T_CreateOpClassItem, T_TableLikeClause, T_FunctionParameter, T_LockingClause, T_RowMarkClause, T_XmlSerialize, T_WithClause, T_InferClause, T_OnConflictClause, T_CommonTableExpr, T_RoleSpec, /* * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h) */ T_IdentifySystemCmd, T_BaseBackupCmd, T_CreateReplicationSlotCmd, T_DropReplicationSlotCmd, T_StartReplicationCmd, T_TimeLineHistoryCmd, /* * TAGS FOR RANDOM OTHER STUFF * * These are objects that aren't part of parse/plan/execute node tree * structures, but we give them NodeTags anyway for identification * purposes (usually because they are involved in APIs where we want to * pass multiple object types through the same pointer). */ T_TriggerData = 951, /* in commands/trigger.h */ T_EventTriggerData, /* in commands/event_trigger.h */ T_ReturnSetInfo, /* in nodes/execnodes.h */ T_WindowObjectData, /* private in nodeWindowAgg.c */ T_TIDBitmap, /* in nodes/tidbitmap.h */ T_InlineCodeBlock, /* in nodes/parsenodes.h */ T_FdwRoutine, /* in foreign/fdwapi.h */ T_IndexAmRoutine, /* in access/amapi.h */ T_TsmRoutine, /* in access/tsmapi.h */ T_ForeignKeyCacheInfo /* in utils/rel.h */ }
-
执行gengdb.sh脚本,即在同级目录下生成 my.gdb。
[dev@CentOS-7 ~/workspace_adb31/gdb]$ ll 总用量 224 -rw-rw-r-- 1 dev dev 44 1月 18 15:24 gdbinit -rw-r--r--. 1 dev dev 5261 11月 30 10:49 gengdb.sh -rw-rw-r-- 1 dev dev 69707 1月 18 15:24 my.gdb -rw-rw-r-- 1 dev dev 6706 1月 18 15:24 node.out -rw-r--r--. 1 dev dev 9954 11月 30 10:49 node.txt
-
通过将 source /xx/xx/my.gdb 写入 ~/.gdbinit 或者 gdb -x my.gdb 等方式加载。
-
调试效果
有需要的同学可自主更改脚本,编出适合自己的gdb调试脚本