js get max value in (json) Array

// Max value in Array
var arr = [1,2,3,5,3,2];Math.max.apply(null, arr); // 5


// Max value in Jaon Array
var arr = [{"x":"8/11/2009","y":0.026572007},{"x":"8/12/2009","y":0.025057454},{"x":"8/13/2009","y":0.024530916},{"x":"8/14/2009","y":0.031004457}];
Math.max.apply(Math,arr.map(function(o){return o.y;}))
// 0.031004457

var arr = [{"a":1},{"a":2},{"a":3}];Math.max.apply(Math,arr.map(function(o){return o.a;}))
// 3
var arr = [{a:1},{a:2},{a:3}];Math.max.apply(Math,arr.map(function(o){return o.a;}))
// 3

 

这是其他一些get的代码,也许你能从中知道怎么从底层获取端口的isolationenable的值,使得我们可以在函数中不变更端口的原本的allowinternet状态并更改isolation状态 static int lanIPTVGetRspJsonObj(JSON_Object *rspObj) { int ret = ERR_NO_ERROR; IF_ID netIfId_down = {0}; IF_ID netIfId_up = {0}; IGMP_INTF_STATE_T igmpState = {0}; CFG_ZONE_INST **zoneCfg = NULL; CFG_ZONE_INST cfg = {0}; char version[16]; TPCONFIG_NETIF_ST netIfEntry = {0}; //初始化result对 JSON_Value *resultVal = json_value_init_object(); JSON_Object *result = json_value_get_object(resultVal); UINT32 ifIndex = 0; APPL_IF_ERR_DONE(ret, dmCfgZoneInstGet(defaultLAN, CFG_ZONE_INST_F_IFNAME, &cfg)); APPL_IF_ERR_DONE(ret, libGetIfindexByIfname(cfg.ifname, &ifIndex)); APPL_IF_ERR_DONE(ret, libNetIfIdGet(LIB_NETIF_GETMODE_SHM, ifIndex, &netIfId_down)); json_object_set_string(result, "igmp_enable", "off"); json_object_set_string(result, "igmp_interface", ""); json_object_set_string(result, "igmp_version", ""); json_object_set_string(result, "mld_enable", "off"); json_object_set_string(result, "mld_interface", ""); json_object_set_string(result, "mld_version", ""); //设置rsp基础字段 json_object_set_number(rspObj, "id", 1); json_object_set_string(rspObj, "error_code", "0"); //设置result对 json_object_set_value(rspObj, "result", resultVal); APPL_IF_ERR_DONE(ret, uiIgmpProxyUpStreamGetCpn(netIfId_down, &netIfId_up)); APPL_IF_ERR_DONE(ret, uiNetIfConfigEntryGet(netIfId_up, &netIfEntry)); APPL_IF_ERR_DONE(ret, uiIgmpParseIntfFromDB(netIfId_up, &igmpState)); APPL_IF_ERR_DONE(ret, dmCfgZoneInstGetLstByField(CFG_ZONE_INST_F_IFNAME, netIfEntry.kernelName, &zoneCfg)); sprintf(version, "%d", igmpState.version); json_object_set_string(result, "igmp_enable", igmpState.adminMode == ENABLE ? "on" : "off"); json_object_set_string(result, "igmp_interface", zoneCfg[0]->zoneName); json_object_set_string(result, "igmp_version", version); json_object_set_string(result, "mld_enable", igmpState.adminMode == ENABLE ? "on" : "off"); json_object_set_string(result, "mld_interface", zoneCfg[0]->zoneName); json_object_set_string(result, "mld_version", version); done: if (NULL != zoneCfg) { dmCfgZoneInstListFree(zoneCfg); } return ret; } int lanDHCPFillRspObjCb(TPCONFIG_NETIF_ST* netIfEntry, void* param) { IF_ADDR allIp[NETIF_MAX_IPV4_ADDR_NUM] = {}; int ret = ERR_NO_ERROR; int ipCount = 0; UINT32 numOfHelpAddr = 0; char maskStr[IP_ADDRESS_MAX_LENGTH] = {"unassigned"}; char ipStr[IP_ADDRESS_MAX_LENGTH] = {}; char vlanStr[VLAN_MAX_LENGTH] = {}; char modeStr[MODE_LENGTH] = {}; int subIfIndex = 0; GATEWAY_IF_TYPE subIfType; int ifIndex, dhcpServerEnable = 0, dhcpRelayEnable = 0; CFG_ZONE_INST **zoneCfg = NULL; DHCP_SERVER_POOL poolParam = {0}; unsigned int seqnum = 0; char seqnumStr[U32_LENGTH] = {0}; char leaseTime[U64_LENGTH] = {0}; char relayServerAddr[IP_ADDRESS_MAX_LENGTH] = {0}; DHCP_RELAY_ADDR netIfHelpAddGroup[DHCPRELAY_HELP_ADDR_MAX_NUM] = {0}; APPL_ENSURE_RET_VAL(netIfEntry, ERR_BAD_PARAM); APPL_ENSURE_RET_VAL(param, ERR_BAD_PARAM); APPL_ENSURE_RET_VAL((netIfEntry->netIfId.ifType == NETIF_TYPE_VLAN) || (netIfEntry->netIfId.ifType == NETIF_TYPE_GWVIRT), ERR_NO_ERROR); JSON_Object *rspObj = (JSON_Object *)param; JSON_Array *result = json_object_get_array(rspObj, "result"); JSON_Object *others = json_object_get_object(rspObj, "others"); JSON_Value *resultItemVal = json_value_init_object(); JSON_Object *resultItemObj = json_value_get_object(resultItemVal); if (netIfEntry->netIfId.ifType == NETIF_TYPE_GWVIRT) { netIfGwVirtDataParse(netIfEntry->netIfId.ifData.data, &subIfIndex, &subIfType); if (GATEWAY_TYPE_BRIDGE != subIfType) { return ERR_NO_ERROR; } uilibNetIfVlanBitmapToString(netIfEntry->vlanListBitMap, vlanStr, NULL); sprintf(modeStr, "%s", "bridge"); } else if (netIfEntry->netIfId.ifType == NETIF_TYPE_VLAN) { sprintf(vlanStr, "%d", netIfEntry->netIfId.ifData.vlanId); sprintf(modeStr, "%s", "normal"); } libNetIfIndexGet(netIfEntry->netIfId, &ifIndex); ret = libNetIfIpv4AllIpGet(LIB_NETIF_GETMODE_TPSTATE, ifIndex, allIp, &ipCount); if (ERR_NO_ERROR == ret) { inet_ntop(AF_INET, &(V4_ADDR(allIp[0])), ipStr, IP_ADDRESS_MAX_LENGTH); ret = libNetIfMaskLenToStr(V4_SUBNET(allIp[0]), IP_ADDRESS_MAX_LENGTH, maskStr); } APPL_IF_ERR_DONE(ret, dmCfgZoneInstGetLstByField(CFG_ZONE_INST_F_IFNAME, netIfEntry->kernelName, &zoneCfg)); if(!zoneCfg || !zoneCfg[0]){ return ERR_NO_ERROR; } ret = uiDhcpServerGetPool(zoneCfg[0]->zoneName, &poolParam); if (ERR_NO_ERROR != ret) { dhcpServerEnable = 0; } else { dhcpServerEnable = 1; sprintf(leaseTime, "%u", poolParam.lease); } ret = uilibDhcpRelayNetIfHelpAddressGet(netIfEntry->netIfId, netIfHelpAddGroup, &numOfHelpAddr); if (numOfHelpAddr == 0) { dhcpRelayEnable = 0; } else { dhcpRelayEnable = 1; netIfHelpAddGroup[0].ipAddr.ipv4.s_addr = htonl(netIfHelpAddGroup[0].ipAddr.ipv4.s_addr); inet_ntop(AF_INET, &netIfHelpAddGroup[0].ipAddr.ipv4.s_addr, relayServerAddr, IP_ADDRESS_MAX_LENGTH); if (dhcpServerEnable) { APPL_IF_ERR_DONE(ret, uiDhcpServerDelPool(zoneCfg[0]->zoneName)); dhcpServerEnable = 0; } } sscanf(zoneCfg[0]->zoneName, ZONE_LAN_PREFIX"%d", &seqnum); sprintf(seqnumStr, "%d", seqnum); //设置resultItem对中的字段 //LAN基础配置 json_object_set_string(resultItemObj, "ipaddr", ipStr); json_object_set_string(resultItemObj, "vlanid", vlanStr); json_object_set_string(resultItemObj, "netmask", maskStr); if (0 == strcmp(zoneCfg[0]->zoneName, defaultLAN)){ json_object_set_string(resultItemObj, "default", "1"); } else { json_object_set_string(resultItemObj, "default", "0"); } if (((netIfEntry->isolation >> 0) & 0x3) == 2) { json_object_set_string(resultItemObj, "isolation", "on"); } else { json_object_set_string(resultItemObj, "isolation", "off"); } if (((netIfEntry->isolation >> 2) & 0x3) == 1){ json_object_set_string(resultItemObj, "allowInternetAccess", "on"); } else { json_object_set_string(resultItemObj, "allowInternetAccess", "off"); } json_object_set_string(resultItemObj, "name", netIfEntry->description); json_object_set_string(resultItemObj, "mode", modeStr); json_object_set_string(resultItemObj, "cid", seqnumStr); //dhcp相关配置 if (dhcpServerEnable && !dhcpRelayEnable) { json_object_set_string(resultItemObj, "dhcp_mode", "dhcp_server"); json_object_set_string(resultItemObj, "enable", dhcpServerEnable?"on":"off"); UINT32 PoolRangeNum = 0; JSON_Value *pIPRangePoolVal = json_value_init_array(); JSON_Array *pIPRangePoolArray = json_value_get_array(pIPRangePoolVal); DHCP_SERVER_IP_RANGE rangeList[DHCP_SERVER_DEF_MAX_POOL_RANGE_NUM] = {0}; ret = uiDhcpServerPoolRangeListNumGet(zoneCfg[0]->zoneName, &PoolRangeNum); ret = uiDhcpServerPoolRangeListGet(zoneCfg[0]->zoneName, rangeList, PoolRangeNum); for (int i = 0; i < PoolRangeNum; i++) { JSON_Value *pIPRangePoolItemVal = json_value_init_object(); JSON_Object *pIPRangePoolItemObj = json_value_get_object(pIPRangePoolItemVal); char ipv4AddStartTmp[IP_ADDRESS_LENGTH] = {0}; char ipv4AddEndTmp[IP_ADDRESS_LENGTH] = {0}; struct in_addr startAddr, endAddr; memset(&(startAddr), 0, sizeof(struct in_addr)); memset(&(endAddr), 0, sizeof(struct in_addr)); startAddr.s_addr = htonl(rangeList[i].startIp); inet_ntop(AF_INET, &(startAddr), ipv4AddStartTmp, sizeof(char) * IP_ADDRESS_LENGTH); endAddr.s_addr = htonl(rangeList[i].endIp); inet_ntop(AF_INET, &(endAddr), ipv4AddEndTmp, sizeof(char) * IP_ADDRESS_LENGTH); json_object_set_string(pIPRangePoolItemObj, "start", ipv4AddStartTmp); json_object_set_string(pIPRangePoolItemObj, "end", ipv4AddEndTmp); json_array_append_value(pIPRangePoolArray, pIPRangePoolItemVal); } json_object_set_value(resultItemObj, "ipRangePool", pIPRangePoolVal); json_object_set_string(resultItemObj, "leasetime", leaseTime); json_object_set_string(resultItemObj, "domain", poolParam.domainName); if (poolParam.nextServer.s_addr != 0) { memset(ipStr, 0, sizeof(char) * IP_ADDRESS_MAX_LENGTH); poolParam.nextServer.s_addr = htonl(poolParam.nextServer.s_addr); inet_ntop(AF_INET, &(poolParam.nextServer), ipStr, IP_ADDRESS_MAX_LENGTH); json_object_set_string(resultItemObj, "next_server", ipStr); } APPL_IF_ERR_DONE(ret, uiDhcpServerGetOnePoolGatewayAll(zoneCfg[0]->zoneName, resultItemObj, dhcpServerPoolGateWayOutput)); APPL_IF_ERR_DONE(ret, uiDhcpServerGetOnePoolDnsAll(zoneCfg[0]->zoneName, resultItemObj, dhcpServerPoolDNSOutput)); JSON_Value *dhcpOptsOutVal = json_value_init_array(); json_object_set_value(resultItemObj, "dhcp_opts", dhcpOptsOutVal); APPL_IF_ERR_DONE(ret, uiDhcpServerGetOnePoolOptionAll(zoneCfg[0]->zoneName, resultItemObj, dhcpServerPoolOptionOutput)); } else if (!dhcpServerEnable && dhcpRelayEnable) { json_object_set_string(resultItemObj, "dhcp_mode", "dhcp_relay"); json_object_set_string(resultItemObj, "relay_enable", dhcpRelayEnable?"on":"off"); json_object_set_string(resultItemObj, "relay_server_ipaddr", relayServerAddr); } else { // 当dhcpServer和dhcpRelay都未启用时 返回DHCP Server模式以及禁用状态 json_object_set_string(resultItemObj, "dhcp_mode", "dhcp_server"); json_object_set_string(resultItemObj, "enable", "off"); } json_object_set_string(resultItemObj, "maxleases", "4096"); //填充result数组 json_array_append_value(result, resultItemVal); done: dmCfgZoneInstListFree(zoneCfg); return ERR_NO_ERROR; }
10-17
请你学习一下json_api.h的函数,再改一下我的代码,请不要到处乱创造函数。 extern JSON_OBJPTR jso_new_obj(); extern void jso_free_obj(JSON_OBJPTR obj); extern JSON_OBJPTR jso_new_string(char *str); extern JSON_OBJPTR jso_obj_get(JSON_OBJPTR obj, const char *key); extern void jso_obj_add(JSON_OBJPTR obj, const char *key, JSON_OBJPTR val); extern void jso_obj_del(JSON_OBJPTR obj, const char *key); extern JSON_OBJPTR jso_from_string(const char *json_string); extern int jso_to_string(JSON_OBJPTR obj, char *str_buf, int len); extern JSON_OBJPTR *jso_next_sub_obj(JSON_OBJPTR obj, JSON_OBJPTR *cur, char **key); extern int jso_add_string(JSON_OBJPTR obj, const char *key, const char *val); extern int jso_add_int(JSON_OBJPTR obj, const char *key, int val); extern int jso_add_bool(JSON_OBJPTR obj, const char *key, boolean val); extern int jso_add_string_from_int(JSON_OBJPTR obj, const char *key, int val); extern int jso_add_double(JSON_OBJPTR obj, const char *key, double val); extern int jso_add_string_from_double(JSON_OBJPTR obj, const char *key, double val); extern int jso_add_int64(JSON_OBJPTR obj, const char *key, long long val); extern const char *jso_get_string_origin(JSON_OBJPTR obj); extern const char *jso_obj_get_string_origin(JSON_OBJPTR obj, const char *key); extern int jso_obj_get_int(JSON_OBJPTR obj, const char *key, int *pValue); extern int jso_obj_get_double(JSON_OBJPTR obj, const char *key, double *val); extern int jso_obj_get_int64(JSON_OBJPTR obj, const char *key, long long *val); extern JSON_OBJPTR jso_new_array(); extern boolean jso_is_double(JSON_OBJPTR obj); extern boolean jso_is_string(JSON_OBJPTR obj); extern boolean jso_is_int(JSON_OBJPTR obj); extern boolean jso_is_bool(JSON_OBJPTR obj); extern boolean jso_is_int64(JSON_OBJPTR obj); extern int jso_get_int(JSON_OBJPTR obj, int *pVal); extern int jso_get_double(JSON_OBJPTR obj, double *pVal); extern boolean jso_is_obj(JSON_OBJPTR obj); extern boolean jso_obj_is_null(JSON_OBJPTR obj, const char *key); extern boolean jso_is_array(JSON_OBJPTR obj); extern int jso_array_length(JSON_OBJPTR obj); extern int jso_array_add(JSON_OBJPTR obj, JSON_OBJPTR val); extern JSON_OBJPTR jso_array_get_idx(JSON_OBJPTR obj, int idx); extern int jso_array_del_idx(JSON_OBJPTR obj, int idx, int count); extern JSON_OBJPTR jso_get(JSON_OBJPTR obj); extern JSON_OBJPTR jso_get_obj_from_obj(JSON_OBJPTR obj, const char *key); extern int jso_transfer_to_array(JSON_OBJPTR *json_table); extern int jso_sub_obj_cnt(JSON_OBJPTR obj); extern int jso_obj_url_coding(JSON_OBJ *obj, int coding_type); extern int jso_array_url_coding(JSON_OBJ *array, int coding_type);
08-28
添加和show都失败了 CN25G(config-dnsproxy-dot)#show %% Failed to get global DoT config CN25G(config-dnsproxy-dot)# add - Add a dot del - Delete a dot by id set - Set a dot show - Show all dot switch - Set dot global switch end - Return to Privileged EXEC Mode exit - Exit current mode history - Display command history no - Negate command show - Display system information CN25G(config-dnsproxy-dot)# CN25G(config-dnsproxy-dot)#add test 100.100.100.100 on CN25G(config-dnsproxy-dot)#show %% Failed to get global DoT config CN25G(config-dnsproxy-dot)#add test 100.100.100.100 200.100.100.100 on CN25G(config-dnsproxy-dot)#show %% Failed to get global DoT config 这是网页设置dot的程序 static int dnsSecurityDotGlobalGetHandle(UI_CTX *ctx) { JSON_Value *rspVal = json_value_init_object(); JSON_Object *rspObj = json_value_get_object(rspVal); JSON_Value *resVal = json_value_init_object(); JSON_Object *res = json_value_get_object(resVal); CFG_DOT_GBL_T g = {0}; if (ERR_NO_ERROR == dmDotCfgGlobalGet(&g)) { json_object_set_string(res, "switch", g.switch_s[0] ? g.switch_s : "off"); } json_object_set_number(rspObj, "id", 1); json_object_set_string(rspObj, "error_code", "0"); json_object_set_value (rspObj, "result", resVal); ctx->rsp = rspVal; return ERR_NO_ERROR; } static int dnsSecurityDotGlobalSetHandle(UI_CTX *ctx) { JSON_Object *params = json_object_get_object(ctx->param, "params"); CFG_DOT_GBL_T g = {0}; const char *sw = params ? json_object_get_string(params, "switch") : NULL; if (sw && *sw) { snprintf(g.switch_s, sizeof(g.switch_s), "%s", sw); g.mask |= 0x1; } APPL_IF_ERR_RET_VAL(dmDotCfgGlobalSet(&g), ERR_NO_ERROR); JSON_Value *rspVal = json_value_init_object(); JSON_Object *rspObj = json_value_get_object(rspVal); JSON_Value *resVal = json_value_init_object(); JSON_Object *res = json_value_get_object(resVal); json_object_set_string(res, "switch", sw && *sw ? sw : "off"); json_object_set_number(rspObj, "id", 1); json_object_set_value (rspObj, "result", resVal); json_object_set_string(rspObj, "error_code", "0"); ctx->rsp = rspVal; return ERR_NO_ERROR; } static int dnsSecurityDotServersGetHandle(UI_CTX *ctx) { JSON_Value *rspVal = json_value_init_object(); JSON_Object *rspObj = json_value_get_object(rspVal); JSON_Value *resVal = json_value_init_array(); JSON_Array *resArray = json_value_get_array(resVal); CFG_DOT_SERVER_T **lst = NULL; if (ERR_NO_ERROR == dmDotCfgServerGetAll(&lst)) { for (CFG_DOT_SERVER_T **pp = lst; pp && *pp; ++pp) { _dot_to_json_item(*pp, resArray); } dmDotCfgServerListFree(lst); } JSON_Value *othersVal = json_value_init_object(); JSON_Object *others = json_value_get_object(othersVal); json_object_set_number(others, "max_rules", 32); json_object_set_number(rspObj, "id", 1); json_object_set_string(rspObj, "error_code", "0"); json_object_set_value (rspObj, "others", othersVal); json_object_set_value (rspObj, "result", resVal); ctx->rsp = rspVal; return ERR_NO_ERROR; } static int dnsSecurityDotServersAddHandle(UI_CTX *ctx) { JSON_Object *params = json_object_get_object(ctx->param, "params"); JSON_Object *newObj = params ? json_object_get_object(params, "new") : NULL; const char *id_param = params ? json_object_get_string(params, "id") : NULL; APPL_ENSURE_RET_VAL(newObj, ERR_BAD_PARAM); CFG_DOT_SERVER_T ent; memset(&ent, 0, sizeof(ent)); if (newObj) { _parse_dot_new(newObj, &ent); } if (id_param && id_param[0] && strcmp(id_param, "add") != 0) { snprintf(ent.id, sizeof(ent.id), "%s", id_param); } APPL_IF_ERR_RET_VAL(dmDotCfgServerAdd(&ent), ERR_NO_ERROR); /* 回包:others.max_rules + result{name,status,id,custom} */ JSON_Value *rspVal = json_value_init_object(); JSON_Object *rspObj = json_value_get_object(rspVal); JSON_Value *othersVal= json_value_init_object(); JSON_Object *others = json_value_get_object(othersVal); JSON_Value *resVal = json_value_init_object(); JSON_Object *res = json_value_get_object(resVal); json_object_set_number(others, "max_rules", 32); json_object_set_string(res, "name", ent.name); json_object_set_string(res, "status", ent.status[0] ? ent.status : "off"); json_object_set_string(res, "id", ent.id[0] ? ent.id : ""); json_object_set_string(res, "custom", ent.custom ? "1" : "0"); json_object_set_number(rspObj, "id", 1); json_object_set_value (rspObj, "others", othersVal); json_object_set_value (rspObj, "result", resVal); json_object_set_string(rspObj, "error_code", "0"); ctx->rsp = rspVal; return ERR_NO_ERROR; } static int dnsSecurityDotServersSetHandle(UI_CTX *ctx) { JSON_Object *params = json_object_get_object(ctx->param, "params"); JSON_Object *newObj = params ? json_object_get_object(params, "new") : NULL; const char *id = params ? json_object_get_string(params, "id") : NULL; CFG_DOT_SERVER_T ent; memset(&ent, 0, sizeof(ent)); if (newObj) { _parse_dot_new(newObj, &ent); } else if (params) { _parse_dot_new(params, &ent); } if (id && id[0]) { snprintf(ent.id, sizeof(ent.id), "%s", id); } else if (params && json_object_has_value_of_type(params, "index", JSONNumber)) { ent.index = (int)json_object_get_number(params, "index"); } APPL_IF_ERR_RET_VAL(dmDotCfgServerSet(&ent), ERR_NO_ERROR); /* 回包:others.max_rules + result{name,status,custom,server2,server1} */ JSON_Value *rspVal = json_value_init_object(); JSON_Object *rspObj = json_value_get_object(rspVal); JSON_Value *othersVal= json_value_init_object(); JSON_Object *others = json_value_get_object(othersVal); JSON_Value *resVal = json_value_init_object(); JSON_Object *res = json_value_get_object(resVal); json_object_set_number(others, "max_rules", 32); json_object_set_string(res, "name", ent.name); json_object_set_string(res, "status", ent.status[0] ? ent.status : "off"); json_object_set_string(res, "custom", ent.custom ? "1" : "0"); json_object_set_string(res, "server2", ent.server2); json_object_set_string(res, "server1", ent.server1); json_object_set_number(rspObj, "id", 1); json_object_set_value (rspObj, "others", othersVal); json_object_set_value (rspObj, "result", resVal); json_object_set_string(rspObj, "error_code", "0"); ctx->rsp = rspVal; return ERR_NO_ERROR; } static int dnsSecurityDotServersDeleteHandle(UI_CTX *ctx) { int ret = ERR_NO_ERROR; JSON_Object *root = ctx ? ctx->param : NULL; JSON_Object *params = root ? json_object_get_object(root, "params") : NULL; const char *key = params ? json_object_get_string(params, "key") : NULL; const char *indexS = params ? json_object_get_string(params, "index") : NULL; if (!key || key[0] == '\0') { return write_bad_param_rsp(ctx); } unsigned id = (unsigned)atoi(key); if (id == 0) { return write_bad_param_rsp(ctx); } APPL_ERRCODE delResult = dmDotCfgServerDelById(id); JSON_Value *rspVal = json_value_init_object(); JSON_Object *rspObj = json_value_get_object(rspVal); JSON_Value *othersVal= json_value_init_object(); JSON_Object *others = json_value_get_object(othersVal); JSON_Value *resVal = json_value_init_object(); JSON_Object *res = json_value_get_object(resVal); json_object_set_number(others, "max_rules", 32); if (delResult == ERR_NO_ERROR) { json_object_set_boolean(res, "success", true); json_object_set_string(rspObj, "error_code", "0"); if (indexS) { json_object_set_string(res, "index", indexS); } if (key) { json_object_set_string(res, "key", key); } } else { json_object_set_boolean(res, "success", false); if (delResult == ERR_BAD_PARAM) { json_object_set_string(rspObj, "error_code", "87002"); /* 参数无效 */ } else { json_object_set_string(rspObj, "error_code", "87001"); /* 操作失败*/ } char error_msg[64]; snprintf(error_msg, sizeof(error_msg), "Delete failed, errcode=%d", delResult); json_object_set_string(rspObj, "error_message", error_msg); } json_object_set_number(rspObj, "id", 1); json_object_set_value (rspObj, "others", othersVal); json_object_set_value (rspObj, "result", resVal); ctx->rsp = rspVal; // return ERR_NO_ERROR; return ret; }
最新发布
10-25
<think>我们面对的问题是在代码中调用PM_CONFIG_ERROR("num:")这一行时出现了段错误(Segmentation Fault)。根据提供的信号信息: - `info.si_signo = 11`(SIGSEGV,表示段错误) - `info.si_code = 1`(SEGV_MAPERR),表示地址未映射到对,即访问了一个未映射的地址。 - `info.si_addr = 0x4`,这个地址非常低,通常是一个无效的指针(接近于NULL指针,但非零)。 从这些信息可以推断,程序在尝试访问内存地址0x4时发生了错误。由于0x4是一个无效地址(通常属于内核空间或未映射区域),因此触发了段错误。 现在,我们要分析为什么在调用`PM_CONFIG_ERROR("num:")`时会出现这样的错误。`PM_CONFIG_ERROR`可能是一个打印错误日志的宏或函数。通常,这种打印函数会接受一个字符串作为参数。 考虑以下可能性: 1. **字符串指针问题**:传递给`PM_CONFIG_ERROR`的字符串参数可能是一个无效的指针。但是,这里的字符串字面量`"num:"`在编译时会被分配在只读数据段,因此它的地址是有效的。所以直接传递字符串字面量不太可能导致段错误。 2. **格式化字符串问题**:如果`PM_CONFIG_ERROR`是一个类似`printf`的格式化输出函数,那么它可能会有多个参数。例如,`PM_CONFIG_ERROR("num: %d", num)`。在这种情况下,如果格式字符串与后面的参数不匹配,或者后面的参数有误,也可能导致段错误。但是,问题中只写了`"num:"`,没有看到其他参数,所以这里假设只有字符串参数。 3. **函数内部问题**:可能是`PM_CONFIG_ERROR`函数或宏内部实现有问题。例如,它可能试图访问一个无效的指针。但是,由于我们得到的错误地址是0x4,这个地址非常特殊,通常与访问结构体或类的成员有关。 4. **调用约定问题**:在调用函数时,如果栈被破坏,也可能导致函数调用时出现段错误。 5. **其他可能性**:比如,在调用`PM_CONFIG_ERROR`之前,栈溢出或者指针被破坏,导致函数调用时参数传递出错。 特别值得注意的是,`info.si_addr = 0x4`。这个地址0x4是一个接近NULL的地址。通常,当我们试图通过一个NULL指针访问成员时,比如: ```c struct some_struct *ptr = NULL; int value = ptr->member; // 如果ptr为NULL,则访问ptr->member会访问0x4(假设member在结构体中的偏移是4) ``` 那么,如果`ptr`是NULL,访问`ptr->member`实际上就是访问0+4=4,即0x4地址。 因此,我们怀疑在调用`PM_CONFIG_ERROR`的时候,实际上是在一个对的方法中,而这个对的指针(this指针)是NULL。例如: ```c class MyClass { public: void printError() { PM_CONFIG_ERROR("num:"); // 如果this为NULL,那么访问任何成员变量都可能导致段错误 } }; MyClass *obj = NULL; obj->printError(); // 这里会传递一个NULL作为this指针,如果printError中访问了成员变量,就会出错 ``` 或者,在C语言中,如果有一个结构体,函数需要结构体的指针,而传递了NULL: ```c struct MyStruct { // 一些成员 }; void my_function(struct MyStruct *s) { PM_CONFIG_ERROR("num:"); // 如果函数内部使用了s指向的成员,而s为NULL,则出错 } struct MyStruct *s = NULL; my_function(s); ``` 但是,注意在我们的调用中,`PM_CONFIG_ERROR`的参数是一个字符串字面量,没有直接看到对结构体成员的访问。所以,有可能是在`PM_CONFIG_ERROR`的调用之前,已经发生了栈破坏,或者在调用`PM_CONFIG_ERROR`的时候,它隐含地使用了某个对(如C++的成员函数)或者全局变量,而该对或全局变量被破坏。 根据引用[2]中提供的方法,我们可以通过捕获SIGSEGV信号并打印堆栈信息来定位问题。具体步骤如下: 1. **设置信号处理函数**:捕获SIGSEGV信号,并在处理函数中使用`backtrace`和`backtrace_symbols`获取堆栈信息。 2. **将堆栈地址转换为函数名和行号**:使用`addr2line`工具。 但是,问题中已经给出了错误发生的代码行:`PM_CONFIG_ERROR("num:")`。所以,我们需要检查这一行代码以及它所在的上下文。 可能的直接原因: - 该行代码在一个成员函数中,而调用该成员函数的对指针为NULL。 - 该行代码中使用了某个全局变量或成员变量,而该变量所在的指针为NULL(或者已经被释放)。 - 该行代码中调用了其他函数,而那个函数内部出现了问题。 由于错误地址0x4非常小,我们更倾向于认为是在访问一个结构体或类的成员,而基指针为NULL(因为NULL指针的地址为0,成员偏移为4)。 因此,检查代码中`PM_CONFIG_ERROR`所在的函数: - 如果是成员函数,检查调用该函数的对指针是否可能为NULL。 - 检查该函数中是否使用了成员变量(包括隐式的this指针)。 如果`PM_CONFIG_ERROR`是一个宏,我们需要展开宏,看看它内部是否访问了某个指针(可能是某个全局结构体指针或者对的成员)。 例如,假设`PM_CONFIG_ERROR`定义为: ```c #define PM_CONFIG_ERROR(fmt, ...) do { \ some_log_function(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \ } while (0) ``` 那么,它不会直接导致访问0x4。但是,如果`some_log_function`内部使用了某个全局变量,而该全局变量未初始化(为NULL),那么就可能出现访问0x4的情况。 或者,如果`PM_CONFIG_ERROR`定义中使用了某个结构体的成员,比如: ```c extern struct config_manager *g_cfg_mgr; #define PM_CONFIG_ERROR(fmt, ...) \ g_cfg_mgr->log_error(fmt, ##__VA_ARGS__) ``` 那么,如果`g_cfg_mgr`为NULL,那么`g_cfg_mgr->log_error`就会访问0x4(假设`log_error`在结构体中的偏移是4)。 因此,总结步骤: 1. 检查`PM_CONFIG_ERROR`宏或函数的定义,查看其内部实现,特别是是否有访问指针(尤其是全局指针或成员指针)的操作。 2. 检查在调用`PM_CONFIG_ERROR`之前,是否有可能导致指针失效的操作(如释放内存后未置NULL、未初始化指针等)。 3. 在调用`PM_CONFIG_ERROR`的前后添加日志,确认程序执行流以及相关指针的值(特别是如果该函数是成员函数,则检查this指针;如果是全局函数,检查其内部使用的全局指针)。 4. 使用引用[2]中的方法,捕获SIGSEGV信号,打印堆栈信息,并定位到具体的代码行。注意,堆栈信息可能能够指出是在`PM_CONFIG_ERROR`内部的哪一步出现了问题。 根据引用[3],我们还可以在内核日志中查看更详细的错误信息(如果该段错误发生在内核态)。但根据信号信息,这里发生在用户态(因为引用[1]中函数`force_sig_info_fault`是内核发送信号给用户进程的函数,而我们的错误发生在用户进程)。 因此,我们重点在用户态调试。 具体调试建议: 1. **定义信号处理函数**:在程序中安装一个SIGSEGV信号处理函数,并在其中使用`backtrace`和`backtrace_symbols`获取堆栈信息,然后打印出来。将堆栈地址保存起来,以便后续使用`addr2line`解析。 2. **检查指针**:在调用`PM_CONFIG_ERROR`的地方,检查所有涉及的指针(尤其是全局指针、对指针等)是否为NULL。 3. **检查内存越界**:如果程序中存在内存越界,可能会破坏堆结构,导致后续的指针错误。可以使用内存检测工具(如Valgrind)来检查。 4. **查看核心转储文件(core dump)**:如果系统配置了生成core文件,那么可以通过gdb加载core文件,然后使用`bt`命令查看堆栈,再使用`info registers`查看寄存器状态,特别是当错误发生在访问0x4地址时,查看是哪个寄存器指向0x4,然后回溯这个寄存器的值是从哪里来的。 由于问题中已经定位到是`PM_CONFIG_ERROR("num:")`这一行,因此重点检查这一行的上下文。 最后,给出一个可能的原因和解决方案: **可能原因**:在调用`PM_CONFIG_ERROR`之前,某个重要的全局指针(例如用于日志记录的结构体指针)未被正确初始化,或者被意外地置为NULL。或者在调用时,隐含的this指针为NULL。 **解决方案**: - 检查全局指针的初始化。 - 检查调用`PM_CONFIG_ERROR`的上下文,确保对指针(如果有)有效。 - 使用日志或调试器在调用前打印相关指针的值。 如果无法立即解决,建议使用信号处理函数捕获堆栈信息,以便准确定位问题发生的具体位置(因为`PM_CONFIG_ERROR`可能是一个宏,展开后有多条语句,我们需要知道具体是哪一条指令访问了0x4)。 相关问题: 1. 如何捕获SIGSEGV信号并打印堆栈信息? 2. 如何使用addr2line工具将地址转换为文件名和行号? 3. 在C++中,如何避免使用空指针调用成员函数? 4. 如何调试内存越界导致的内存破坏问题? </think>根据提供的信号信息和引用内容,代码中 `PM_CONFIG_ERROR("num:")` 行出现段错误(segmentation fault)的原因可能有以下方面: ### 直接原因分析 1. **无效指针解引用**(核心问题) - 信号信息 `info.si_addr = 0x4` 表明程序试图访问内存地址 `0x00000004` - `si_code=1 (SEGV_MAPERR)` 表示该地址未映射到任何有效内存对 - 这种低地址(接近 NULL)访问通常是由解引用空指针或未初始化指针引起的 - 典型场景:`some_struct *ptr = NULL; int value = ptr->field;`(`field` 偏移量正好为 4 字节)[^1][^3] 2. **具体触发位置** - 错误发生在 `PM_CONFIG_ERROR("num:")` 调用处,但实际崩溃点可能在: * 格式化字符串处理时(若该宏支持 `printf` 风格参数) * 日志系统内部访问全局数据结构(如日志句柄未初始化) * C++ 场景中隐式 `this` 指针为空时调用成员函数 ### 根本原因排查方向 1. **指针生命周期问题** - 检查 `PM_CONFIG_ERROR` 宏/函数内部是否依赖全局状态(如日志上下文) - 确认依赖的全局变量在调用前已完成初始化 - 验证多线程场景下是否存在竞态条件导致指针失效 2. **内存越界破坏** - 前序操作可能越界写入了关键指针区域 - 示例:数组越界或缓冲区溢出覆盖了日志模块的指针变量 3. **栈损坏** - 栈溢出或非法栈操作导致返回地址/指针被破坏 - 信号中 `address=0x4` 可能指向被破坏的栈帧位置 ### 调试建议(基于引用 [2] 方案) 1. **信号捕获与回溯** ```c #include <execinfo.h> #include <signal.h> void sig_handler(int sig) { void *array[32]; size_t size = backtrace(array, 32); // 获取堆栈 char **symbols = backtrace_symbols(array, size); // 符号解析 for (size_t i = 0; i < size; i++) { printf("%s\n", symbols[i]); // 输出堆栈 } free(symbols); exit(1); } int main() { signal(SIGSEGV, sig_handler); // 注册信号处理器 // ... 业务代码 ... } ``` 2. **地址解析流程** - 编译时添加 `-g -rdynamic` 保留调试信息 - 捕获堆栈后使用 `addr2line` 定位源码: ```bash addr2line -e your_executable -fCp <崩溃地址> ``` 3. **针对性检查** - 在 `PM_CONFIG_ERROR` 调用前添加指针有效性检查: ```c if (logger_global_ctx == NULL) { // 假设依赖全局上下文 emergency_log("Logger context null at %s:%d", __FILE__, __LINE__); } ``` ### 总结原因 最可能的情况是:**在 `PM_CONFIG_ERROR` 实现内部,存在对某个未初始化(或已被释放)的结构体指针的解引用操作,且该指针成员在结构体中的偏移量恰好为 4 字节**。需结合堆栈回溯确定具体访问点[^1][^2]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值